summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitalii Vorobiov <vi.vorobiov@samsung.com>2017-03-16 14:53:49 +0200
committerJean-Philippe Andre <jp.andre@samsung.com>2017-11-07 11:54:09 +0900
commitd98e2323ad93e66b13841d60cbfdd17cdf8fdff2 (patch)
tree14d5b3c30cf2c09a532b3968572ae87eb9d6631a
parent6bf5d9d96ef07dcd12f5c9e7ceaa1dbcca046206 (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.c21
-rw-r--r--src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c8
-rw-r--r--src/static_libs/vg_common/vg_common.c63
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,
22static void (*cairo_pattern_destroy)(cairo_pattern_t *pattern) = NULL; 22static void (*cairo_pattern_destroy)(cairo_pattern_t *pattern) = NULL;
23 23
24static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, cairo_extend_t extend) = NULL; 24static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, cairo_extend_t extend) = NULL;
25static void (*cairo_pattern_set_matrix)(cairo_t *cr, cairo_matrix_t *matrix) = NULL;
26static 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
50static cairo_pattern_t * 55static 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 {