diff options
author | Vitalii Vorobiov <vi.vorobiov@samsung.com> | 2017-03-16 14:53:49 +0200 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-11-07 11:54:09 +0900 |
commit | d98e2323ad93e66b13841d60cbfdd17cdf8fdff2 (patch) | |
tree | 14d5b3c30cf2c09a532b3968572ae87eb9d6631a | |
parent | 6bf5d9d96ef07dcd12f5c9e7ceaa1dbcca046206 (diff) |
vg_common: property apply "objectBoundingBox" morphings to radial gradient
When objectBoundingBox flag is set up, all gradients should morphed into
multiple gradients for every entity that has gradient to be applied on
-rw-r--r-- | src/lib/ector/cairo/ector_renderer_cairo_gradient_radial.c | 21 | ||||
-rw-r--r-- | src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c | 8 | ||||
-rw-r--r-- | src/static_libs/vg_common/vg_common.c | 63 |
3 files changed, 84 insertions, 8 deletions
diff --git a/src/lib/ector/cairo/ector_renderer_cairo_gradient_radial.c b/src/lib/ector/cairo/ector_renderer_cairo_gradient_radial.c index e970d23a15..30149e78a8 100644 --- a/src/lib/ector/cairo/ector_renderer_cairo_gradient_radial.c +++ b/src/lib/ector/cairo/ector_renderer_cairo_gradient_radial.c | |||
@@ -22,6 +22,11 @@ static void (*cairo_arc)(cairo_t *cr, | |||
22 | static void (*cairo_pattern_destroy)(cairo_pattern_t *pattern) = NULL; | 22 | static void (*cairo_pattern_destroy)(cairo_pattern_t *pattern) = NULL; |
23 | 23 | ||
24 | static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, cairo_extend_t extend) = NULL; | 24 | static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, cairo_extend_t extend) = NULL; |
25 | static void (*cairo_pattern_set_matrix)(cairo_t *cr, cairo_matrix_t *matrix) = NULL; | ||
26 | static void (*cairo_matrix_init)(cairo_matrix_t *matrix, | ||
27 | double xx, double yx, | ||
28 | double xy, double yy, | ||
29 | double x0, double y0) = NULL; | ||
25 | 30 | ||
26 | // FIXME: as long as it is not possible to directly access the parent structure | 31 | // FIXME: as long as it is not possible to directly access the parent structure |
27 | // this will be duplicated from the linear gradient renderer | 32 | // this will be duplicated from the linear gradient renderer |
@@ -48,12 +53,14 @@ _ector_renderer_cairo_gradient_radial_ector_renderer_prepare(Eo *obj, Ector_Rend | |||
48 | } | 53 | } |
49 | 54 | ||
50 | static cairo_pattern_t * | 55 | static cairo_pattern_t * |
51 | _ector_renderer_cairo_gradient_radial_prepare(Eo *obj EINA_UNUSED, | 56 | _ector_renderer_cairo_gradient_radial_prepare(Eo *obj, |
52 | Ector_Renderer_Gradient_Radial_Data *grd, | 57 | Ector_Renderer_Gradient_Radial_Data *grd, |
53 | Ector_Renderer_Gradient_Data *gd, | 58 | Ector_Renderer_Gradient_Data *gd, |
54 | unsigned int mul_col) | 59 | unsigned int mul_col) |
55 | { | 60 | { |
61 | Ector_Renderer_Data *pd = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS); | ||
56 | cairo_pattern_t *pat; | 62 | cairo_pattern_t *pat; |
63 | cairo_matrix_t *pd_m; | ||
57 | 64 | ||
58 | pat = cairo_pattern_create_radial(grd->focal.x, grd->focal.y, 0, | 65 | pat = cairo_pattern_create_radial(grd->focal.x, grd->focal.y, 0, |
59 | grd->radial.x, grd->radial.y, grd->radius); | 66 | grd->radial.x, grd->radial.y, grd->radius); |
@@ -63,6 +70,16 @@ _ector_renderer_cairo_gradient_radial_prepare(Eo *obj EINA_UNUSED, | |||
63 | 70 | ||
64 | cairo_pattern_set_extend(pat, _ector_cairo_extent_get(gd->s)); | 71 | cairo_pattern_set_extend(pat, _ector_cairo_extent_get(gd->s)); |
65 | 72 | ||
73 | pd_m = malloc(sizeof (cairo_matrix_t)); | ||
74 | if (pd->m) | ||
75 | { | ||
76 | cairo_matrix_init(pd_m, | ||
77 | pd->m->xx, pd->m->yx, | ||
78 | pd->m->xy, pd->m->yy, | ||
79 | pd->m->xz, pd->m->yz); | ||
80 | cairo_pattern_set_matrix(pat, pd_m); | ||
81 | } | ||
82 | |||
66 | return pat; | 83 | return pat; |
67 | } | 84 | } |
68 | 85 | ||
@@ -148,9 +165,11 @@ _ector_renderer_cairo_gradient_radial_efl_object_finalize(Eo *obj, Ector_Rendere | |||
148 | USE(base, cairo_pattern_destroy, NULL); | 165 | USE(base, cairo_pattern_destroy, NULL); |
149 | USE(base, cairo_arc, NULL); | 166 | USE(base, cairo_arc, NULL); |
150 | USE(base, cairo_fill, NULL); | 167 | USE(base, cairo_fill, NULL); |
168 | USE(base, cairo_matrix_init, NULL); | ||
151 | USE(base, cairo_set_source, NULL); | 169 | USE(base, cairo_set_source, NULL); |
152 | USE(base, cairo_pattern_destroy, NULL); | 170 | USE(base, cairo_pattern_destroy, NULL); |
153 | USE(base, cairo_pattern_set_extend, NULL); | 171 | USE(base, cairo_pattern_set_extend, NULL); |
172 | USE(base, cairo_pattern_set_matrix, NULL); | ||
154 | USE(base, cairo_pattern_create_radial, NULL); | 173 | USE(base, cairo_pattern_create_radial, NULL); |
155 | USE(base, cairo_pattern_add_color_stop_rgba, NULL); | 174 | USE(base, cairo_pattern_add_color_stop_rgba, NULL); |
156 | 175 | ||
diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c index 36e5d14409..1734472a3a 100644 --- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c +++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c | |||
@@ -1790,6 +1790,14 @@ _create_radialGradient(const char *buf, unsigned buflen) | |||
1790 | grad->type = SVG_RADIAL_GRADIENT; | 1790 | grad->type = SVG_RADIAL_GRADIENT; |
1791 | grad->user_space = EINA_TRUE; | 1791 | grad->user_space = EINA_TRUE; |
1792 | grad->radial = calloc(1, sizeof(Svg_Radial_Gradient)); | 1792 | grad->radial = calloc(1, sizeof(Svg_Radial_Gradient)); |
1793 | /** | ||
1794 | * Default values of gradient | ||
1795 | */ | ||
1796 | grad->radial->cx = 0.5; | ||
1797 | grad->radial->cy = 0.5; | ||
1798 | grad->radial->fx = 0.5; | ||
1799 | grad->radial->fy = 0.5; | ||
1800 | grad->radial->r = 0.5; | ||
1793 | 1801 | ||
1794 | svg_parse.gradient.fx_parsed = EINA_FALSE; | 1802 | svg_parse.gradient.fx_parsed = EINA_FALSE; |
1795 | svg_parse.gradient.fy_parsed = EINA_FALSE; | 1803 | svg_parse.gradient.fy_parsed = EINA_FALSE; |
diff --git a/src/static_libs/vg_common/vg_common.c b/src/static_libs/vg_common/vg_common.c index 7b33053ed0..21b9201b70 100644 --- a/src/static_libs/vg_common/vg_common.c +++ b/src/static_libs/vg_common/vg_common.c | |||
@@ -553,7 +553,10 @@ _apply_gradient_property(Svg_Style_Gradient *g, Efl_VG *vg, Vg_File_Data *vg_dat | |||
553 | Efl_Gfx_Gradient_Stop *stops, *stop; | 553 | Efl_Gfx_Gradient_Stop *stops, *stop; |
554 | int stop_count = 0, i = 0; | 554 | int stop_count = 0, i = 0; |
555 | Eina_List *l; | 555 | Eina_List *l; |
556 | Eina_Rect r = { 0, 0, 1, 1 }; | 556 | Eina_Matrix3 m; //for bbox translation |
557 | Eina_Rect r = EINA_RECT( 0, 0, 1, 1 ); | ||
558 | Eina_Rect grad_geom = EINA_RECT(0, 0, 0, 0); | ||
559 | int radius; | ||
557 | 560 | ||
558 | //TODO: apply actual sizes (imporve bounds_get function?)... | 561 | //TODO: apply actual sizes (imporve bounds_get function?)... |
559 | //for example with figures and paths | 562 | //for example with figures and paths |
@@ -573,16 +576,62 @@ _apply_gradient_property(Svg_Style_Gradient *g, Efl_VG *vg, Vg_File_Data *vg_dat | |||
573 | } | 576 | } |
574 | else if (g->type == SVG_RADIAL_GRADIENT) | 577 | else if (g->type == SVG_RADIAL_GRADIENT) |
575 | { | 578 | { |
576 | /** | 579 | radius = sqrt(pow(r.w, 2) + pow(r.h, 2)) / sqrt(2.0); |
577 | * That is according to Units in here | 580 | if (!g->user_space) |
578 | * | 581 | { |
579 | * https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html | 582 | /** |
580 | */ | 583 | * That is according to Units in here |
581 | int radius = sqrt(pow(r.h, 2) + pow(r.w, 2)) / sqrt(2.0); | 584 | * |
585 | * https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html | ||
586 | */ | ||
587 | int min = (r.h > r.w) ? r.w : r.h; | ||
588 | radius = sqrt(pow(min, 2) + pow(min, 2)) / sqrt(2.0); | ||
589 | } | ||
582 | grad_obj = evas_vg_gradient_radial_add(NULL); | 590 | grad_obj = evas_vg_gradient_radial_add(NULL); |
583 | evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx * r.w + r.x, g->radial->cy * r.h + r.y); | 591 | evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx * r.w + r.x, g->radial->cy * r.h + r.y); |
584 | evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r * radius); | 592 | evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r * radius); |
585 | evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx * r.w + r.x, g->radial->fy * r.h + r.y); | 593 | evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx * r.w + r.x, g->radial->fy * r.h + r.y); |
594 | |||
595 | /* in case of objectBoundingBox it need proper scaling */ | ||
596 | if (!g->user_space) | ||
597 | { | ||
598 | double scale_X = 1.0, scale_reversed_X = 1.0; | ||
599 | double scale_Y = 1.0, scale_reversed_Y = 1.0; | ||
600 | |||
601 | /* check the smallest size, find the scale value */ | ||
602 | if (r.h > r.w) | ||
603 | { | ||
604 | scale_Y = ((double) r.w) / r.h; | ||
605 | scale_reversed_Y = ((double) r.h) / r.w; | ||
606 | } | ||
607 | else | ||
608 | { | ||
609 | scale_X = ((double) r.h) / r.w; | ||
610 | scale_reversed_X = ((double) r.w) / r.h; | ||
611 | } | ||
612 | |||
613 | evas_vg_node_bounds_get(grad_obj, &grad_geom); | ||
614 | |||
615 | double cy = grad_geom.h / 2 + grad_geom.y; | ||
616 | double cy_scaled = (grad_geom.h / 2) * scale_reversed_Y; | ||
617 | double cx = grad_geom.w / 2 + grad_geom.x; | ||
618 | double cx_scaled = (grad_geom.w / 2) * scale_reversed_X; | ||
619 | |||
620 | /* matrix tranformation of gradient figure: | ||
621 | * 0. we remember size of gradient and it's center point | ||
622 | * 1. move all gradients to point {0;0} | ||
623 | * (so scale wont increase starting point) | ||
624 | * 2. scale properly only according to the bigger size of entity | ||
625 | * 3. move back so new center point would stay on position | ||
626 | * it had previously | ||
627 | */ | ||
628 | eina_matrix3_identity(&m); | ||
629 | eina_matrix3_translate(&m, grad_geom.x, grad_geom.y); | ||
630 | eina_matrix3_scale(&m, scale_X, scale_Y); | ||
631 | eina_matrix3_translate(&m, cx_scaled - cx, cy_scaled - cy); | ||
632 | |||
633 | efl_vg_transformation_set(grad_obj, &m); | ||
634 | } | ||
586 | } | 635 | } |
587 | else | 636 | else |
588 | { | 637 | { |