jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=d98e2323ad93e66b13841d60cbfdd17cdf8fdff2

commit d98e2323ad93e66b13841d60cbfdd17cdf8fdff2
Author: Vitalii Vorobiov <vi.vorob...@samsung.com>
Date:   Thu Mar 16 14:53:49 2017 +0200

    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
---
 .../cairo/ector_renderer_cairo_gradient_radial.c   | 21 +++++++-
 src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c |  8 +++
 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,
 static void (*cairo_pattern_destroy)(cairo_pattern_t *pattern) = NULL;
 
 static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, 
cairo_extend_t extend) = NULL;
+static void (*cairo_pattern_set_matrix)(cairo_t *cr, cairo_matrix_t *matrix) = 
NULL;
+static void (*cairo_matrix_init)(cairo_matrix_t *matrix,
+                                 double xx, double yx,
+                                 double xy, double yy,
+                                 double x0, double y0) = NULL;
 
 // FIXME: as long as it is not possible to directly access the parent structure
 //  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
 }
 
 static cairo_pattern_t *
-_ector_renderer_cairo_gradient_radial_prepare(Eo *obj EINA_UNUSED,
+_ector_renderer_cairo_gradient_radial_prepare(Eo *obj,
                                               
Ector_Renderer_Gradient_Radial_Data *grd,
                                               Ector_Renderer_Gradient_Data *gd,
                                               unsigned int mul_col)
 {
+   Ector_Renderer_Data *pd = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS);
    cairo_pattern_t *pat;
+   cairo_matrix_t *pd_m;
 
    pat = cairo_pattern_create_radial(grd->focal.x, grd->focal.y, 0,
                                      grd->radial.x, grd->radial.y, 
grd->radius);
@@ -63,6 +70,16 @@ _ector_renderer_cairo_gradient_radial_prepare(Eo *obj 
EINA_UNUSED,
 
    cairo_pattern_set_extend(pat, _ector_cairo_extent_get(gd->s));
 
+   pd_m = malloc(sizeof (cairo_matrix_t));
+   if (pd->m)
+     {
+        cairo_matrix_init(pd_m,
+                          pd->m->xx, pd->m->yx,
+                          pd->m->xy, pd->m->yy,
+                          pd->m->xz, pd->m->yz);
+        cairo_pattern_set_matrix(pat, pd_m);
+     }
+
    return pat;
 }
 
@@ -148,9 +165,11 @@ 
_ector_renderer_cairo_gradient_radial_efl_object_finalize(Eo *obj, Ector_Rendere
    USE(base, cairo_pattern_destroy, NULL);
    USE(base, cairo_arc, NULL);
    USE(base, cairo_fill, NULL);
+   USE(base, cairo_matrix_init, NULL);
    USE(base, cairo_set_source, NULL);
    USE(base, cairo_pattern_destroy, NULL);
    USE(base, cairo_pattern_set_extend, NULL);
+   USE(base, cairo_pattern_set_matrix, NULL);
    USE(base, cairo_pattern_create_radial, NULL);
    USE(base, cairo_pattern_add_color_stop_rgba, NULL);
 
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)
    grad->type = SVG_RADIAL_GRADIENT;
    grad->user_space = EINA_TRUE;
    grad->radial = calloc(1, sizeof(Svg_Radial_Gradient));
+   /**
+    * Default values of gradient
+    */
+   grad->radial->cx = 0.5;
+   grad->radial->cy = 0.5;
+   grad->radial->fx = 0.5;
+   grad->radial->fy = 0.5;
+   grad->radial->r = 0.5;
 
    svg_parse.gradient.fx_parsed = EINA_FALSE;
    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
    Efl_Gfx_Gradient_Stop *stops, *stop;
    int stop_count = 0, i = 0;
    Eina_List *l;
-   Eina_Rect r = { 0, 0, 1, 1 };
+   Eina_Matrix3 m; //for bbox translation
+   Eina_Rect r = EINA_RECT( 0, 0, 1, 1 );
+   Eina_Rect grad_geom = EINA_RECT(0, 0, 0, 0);
+   int radius;
 
    //TODO: apply actual sizes (imporve bounds_get function?)...
    //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
      }
    else if (g->type == SVG_RADIAL_GRADIENT)
      {
-        /**
-         * That is according to Units in here
-         *
-         * https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
-         */
-        int radius = sqrt(pow(r.h, 2) + pow(r.w, 2)) / sqrt(2.0);
+        radius = sqrt(pow(r.w, 2) + pow(r.h, 2)) / sqrt(2.0);
+        if (!g->user_space)
+          {
+             /**
+              * That is according to Units in here
+              *
+              * https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
+              */
+             int min = (r.h > r.w) ? r.w : r.h;
+             radius = sqrt(pow(min, 2) + pow(min, 2)) / sqrt(2.0);
+          }
         grad_obj = evas_vg_gradient_radial_add(NULL);
         evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx * r.w + 
r.x, g->radial->cy * r.h + r.y);
         evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r * radius);
         evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx * r.w + r.x, 
g->radial->fy * r.h + r.y);
+
+        /* in case of objectBoundingBox it need proper scaling */
+        if (!g->user_space)
+          {
+             double scale_X = 1.0, scale_reversed_X = 1.0;
+             double scale_Y = 1.0, scale_reversed_Y = 1.0;
+
+             /* check the smallest size, find the scale value */
+             if (r.h > r.w)
+               {
+                  scale_Y = ((double) r.w) / r.h;
+                  scale_reversed_Y = ((double) r.h) / r.w;
+               }
+             else
+               {
+                  scale_X = ((double) r.h) / r.w;
+                  scale_reversed_X = ((double) r.w) / r.h;
+               }
+
+             evas_vg_node_bounds_get(grad_obj, &grad_geom);
+
+             double cy = grad_geom.h / 2 + grad_geom.y;
+             double cy_scaled = (grad_geom.h / 2) * scale_reversed_Y;
+             double cx = grad_geom.w / 2 + grad_geom.x;
+             double cx_scaled = (grad_geom.w / 2) * scale_reversed_X;
+
+             /* matrix tranformation of gradient figure:
+              * 0. we remember size of gradient and it's center point
+              * 1. move all gradients to point {0;0}
+              *    (so scale wont increase starting point)
+              * 2. scale properly only according to the bigger size of entity
+              * 3. move back so new center point would stay on position
+              *    it had previously
+              */
+             eina_matrix3_identity(&m);
+             eina_matrix3_translate(&m, grad_geom.x, grad_geom.y);
+             eina_matrix3_scale(&m, scale_X, scale_Y);
+             eina_matrix3_translate(&m, cx_scaled - cx, cy_scaled - cy);
+
+             efl_vg_transformation_set(grad_obj, &m);
+          }
      }
    else
      {

-- 


Reply via email to