forked from enlightenment/efl
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
This commit is contained in:
parent
6bf5d9d96e
commit
d98e2323ad
|
@ -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_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_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
|
// FIXME: as long as it is not possible to directly access the parent structure
|
||||||
// this will be duplicated from the linear gradient renderer
|
// 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 *
|
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_Radial_Data *grd,
|
||||||
Ector_Renderer_Gradient_Data *gd,
|
Ector_Renderer_Gradient_Data *gd,
|
||||||
unsigned int mul_col)
|
unsigned int mul_col)
|
||||||
{
|
{
|
||||||
|
Ector_Renderer_Data *pd = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS);
|
||||||
cairo_pattern_t *pat;
|
cairo_pattern_t *pat;
|
||||||
|
cairo_matrix_t *pd_m;
|
||||||
|
|
||||||
pat = cairo_pattern_create_radial(grd->focal.x, grd->focal.y, 0,
|
pat = cairo_pattern_create_radial(grd->focal.x, grd->focal.y, 0,
|
||||||
grd->radial.x, grd->radial.y, grd->radius);
|
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));
|
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;
|
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_pattern_destroy, NULL);
|
||||||
USE(base, cairo_arc, NULL);
|
USE(base, cairo_arc, NULL);
|
||||||
USE(base, cairo_fill, NULL);
|
USE(base, cairo_fill, NULL);
|
||||||
|
USE(base, cairo_matrix_init, NULL);
|
||||||
USE(base, cairo_set_source, NULL);
|
USE(base, cairo_set_source, NULL);
|
||||||
USE(base, cairo_pattern_destroy, NULL);
|
USE(base, cairo_pattern_destroy, NULL);
|
||||||
USE(base, cairo_pattern_set_extend, 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_create_radial, NULL);
|
||||||
USE(base, cairo_pattern_add_color_stop_rgba, NULL);
|
USE(base, cairo_pattern_add_color_stop_rgba, NULL);
|
||||||
|
|
||||||
|
|
|
@ -1790,6 +1790,14 @@ _create_radialGradient(const char *buf, unsigned buflen)
|
||||||
grad->type = SVG_RADIAL_GRADIENT;
|
grad->type = SVG_RADIAL_GRADIENT;
|
||||||
grad->user_space = EINA_TRUE;
|
grad->user_space = EINA_TRUE;
|
||||||
grad->radial = calloc(1, sizeof(Svg_Radial_Gradient));
|
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.fx_parsed = EINA_FALSE;
|
||||||
svg_parse.gradient.fy_parsed = EINA_FALSE;
|
svg_parse.gradient.fy_parsed = EINA_FALSE;
|
||||||
|
|
|
@ -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;
|
Efl_Gfx_Gradient_Stop *stops, *stop;
|
||||||
int stop_count = 0, i = 0;
|
int stop_count = 0, i = 0;
|
||||||
Eina_List *l;
|
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?)...
|
//TODO: apply actual sizes (imporve bounds_get function?)...
|
||||||
//for example with figures and paths
|
//for example with figures and paths
|
||||||
|
@ -572,17 +575,63 @@ _apply_gradient_property(Svg_Style_Gradient *g, Efl_VG *vg, Vg_File_Data *vg_dat
|
||||||
evas_vg_gradient_linear_end_set(grad_obj, g->linear->x2 * r.w + r.x, g->linear->y2 * r.h + r.y);
|
evas_vg_gradient_linear_end_set(grad_obj, g->linear->x2 * r.w + r.x, g->linear->y2 * r.h + r.y);
|
||||||
}
|
}
|
||||||
else if (g->type == SVG_RADIAL_GRADIENT)
|
else if (g->type == SVG_RADIAL_GRADIENT)
|
||||||
|
{
|
||||||
|
radius = sqrt(pow(r.w, 2) + pow(r.h, 2)) / sqrt(2.0);
|
||||||
|
if (!g->user_space)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* That is according to Units in here
|
* That is according to Units in here
|
||||||
*
|
*
|
||||||
* https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
|
* 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);
|
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);
|
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_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_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);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue