Commit 7b7cae3b authored by Caleb Michael Moore's avatar Caleb Michael Moore

late normalization of coordinates

parent 8d6b6819
......@@ -31,6 +31,18 @@
G_BEGIN_DECLS
struct _RsvgPSCtx {
double x0;
double y0;
double x1;
double y1;
guint32 color;
double affine[6];
RsvgDrawingCtx *ctx;
};
void
rsvg_art_render_paint_server (ArtRender *ar, RsvgPaintServer *ps,
const RsvgPSCtx *ctx);
......
......@@ -71,12 +71,13 @@ _pattern_add_rsvg_color_stops (cairo_pattern_t *pattern,
}
static void
_set_source_rsvg_linear_gradient (cairo_t *cr,
_set_source_rsvg_linear_gradient (RsvgDrawingCtx *ctx,
RsvgLinearGradient *linear,
guint32 current_color_rgb,
guint8 opacity,
RsvgBbox bbox)
{
cairo_t *cr = ((RsvgCairoRender *)ctx->render)->cr;
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
RsvgLinearGradient statlinear;
......@@ -87,8 +88,15 @@ _set_source_rsvg_linear_gradient (cairo_t *cr,
if (linear->has_current_color)
current_color_rgb = linear->current_color;
pattern = cairo_pattern_create_linear (linear->x1, linear->y1,
linear->x2, linear->y2);
if (linear->obj_bbox)
_rsvg_push_view_box(ctx, 1., 1.);
pattern = cairo_pattern_create_linear (_rsvg_css_normalize_length_struct(&linear->x1, ctx, 'h'),
_rsvg_css_normalize_length_struct(&linear->y1, ctx, 'v'),
_rsvg_css_normalize_length_struct(&linear->x2, ctx, 'h'),
_rsvg_css_normalize_length_struct(&linear->y2, ctx, 'v'));
if (linear->obj_bbox)
_rsvg_pop_view_box(ctx);
cairo_matrix_init (&matrix,
linear->affine[0], linear->affine[1],
......@@ -116,12 +124,13 @@ _set_source_rsvg_linear_gradient (cairo_t *cr,
}
static void
_set_source_rsvg_radial_gradient (cairo_t *cr,
_set_source_rsvg_radial_gradient (RsvgDrawingCtx *ctx,
RsvgRadialGradient *radial,
guint32 current_color_rgb,
guint8 opacity,
RsvgBbox bbox)
{
cairo_t *cr = ((RsvgCairoRender *)ctx->render)->cr;
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
RsvgRadialGradient statradial;
......@@ -132,8 +141,16 @@ _set_source_rsvg_radial_gradient (cairo_t *cr,
if (radial->has_current_color)
current_color_rgb = radial->current_color;
pattern = cairo_pattern_create_radial (radial->fx, radial->fy, 0.0,
radial->cx, radial->cy, radial->r);
if (radial->obj_bbox)
_rsvg_push_view_box(ctx, 1., 1.);
pattern = cairo_pattern_create_radial (_rsvg_css_normalize_length_struct(&radial->fx, ctx, 'h'),
_rsvg_css_normalize_length_struct(&radial->fy, ctx, 'v'), 0.0,
_rsvg_css_normalize_length_struct(&radial->cx, ctx, 'h'),
_rsvg_css_normalize_length_struct(&radial->cy, ctx, 'v'),
_rsvg_css_normalize_length_struct(&radial->r, ctx, 'o'));
if (radial->obj_bbox)
_rsvg_pop_view_box(ctx);
cairo_matrix_init (&matrix,
radial->affine[0], radial->affine[1],
......@@ -162,11 +179,12 @@ _set_source_rsvg_radial_gradient (cairo_t *cr,
}
static void
_set_source_rsvg_solid_colour (cairo_t *cr,
_set_source_rsvg_solid_colour (RsvgDrawingCtx *ctx,
RsvgSolidColour *colour,
guint8 opacity,
guint32 current_colour)
{
cairo_t *cr = ((RsvgCairoRender *)ctx->render)->cr;
guint32 rgb = colour->rgb;
if (colour->currentcolour)
rgb = current_colour;
......@@ -195,12 +213,25 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
cairo_matrix_t matrix;
int i;
double affine[6], caffine[6], bbwscale, bbhscale, scwscale, schscale;
double patternw, patternh, patternx, patterny;
int pw, ph;
rsvg_pattern = &local_pattern;
rsvg_pattern_fix_fallback(rsvg_pattern);
cr_render = render->cr;
if (rsvg_pattern->obj_bbox)
_rsvg_push_view_box(ctx, 1., 1.);
patternx = _rsvg_css_normalize_length_struct(&rsvg_pattern->x, ctx, 'h');
patterny = _rsvg_css_normalize_length_struct(&rsvg_pattern->y, ctx, 'v');
patternw = _rsvg_css_normalize_length_struct(&rsvg_pattern->width, ctx, 'h');
patternh = _rsvg_css_normalize_length_struct(&rsvg_pattern->height, ctx, 'v');
if (rsvg_pattern->obj_bbox)
_rsvg_pop_view_box(ctx);
/* Work out the size of the rectangle so it takes into account the object bounding box */
......@@ -218,11 +249,11 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
scwscale = sqrt(affine[0] * affine[0] + affine[2] * affine[2]);
schscale = sqrt(affine[1] * affine[1] + affine[3] * affine[3]);
pw = rsvg_pattern->width * bbwscale * scwscale;
ph = rsvg_pattern->height * bbhscale * schscale;
pw = patternw * bbwscale * scwscale;
ph = patternh * bbhscale * schscale;
scwscale = (double)pw / (double)(rsvg_pattern->width * bbwscale);
schscale = (double)ph / (double)(rsvg_pattern->height * bbhscale);
scwscale = (double)pw / (double)(patternw * bbwscale);
schscale = (double)ph / (double)(patternh * bbhscale);
surface = cairo_surface_create_similar(cairo_get_target (cr_render),
CAIRO_CONTENT_COLOR_ALPHA,
......@@ -237,12 +268,12 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
/* Create the pattern coordinate system */
if (rsvg_pattern->obj_bbox) {
/* subtract the pattern origin */
affine[4] = bbox.x + rsvg_pattern->x * bbox.w;
affine[5] = bbox.y + rsvg_pattern->y * bbox.h;
affine[4] = bbox.x + patternx * bbox.w;
affine[5] = bbox.y + patterny * bbox.h;
} else {
/* subtract the pattern origin */
affine[4] = rsvg_pattern->x;
affine[5] = rsvg_pattern->y;
affine[4] = patternx;
affine[5] = patterny;
}
/* Apply the pattern transform */
_rsvg_affine_multiply(affine, affine, rsvg_pattern->affine);
......@@ -251,8 +282,8 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
if (rsvg_pattern->vbox) {
/* If there is a vbox, use that */
double w, h, x, y;
w = rsvg_pattern->width * bbwscale;
h = rsvg_pattern->height * bbhscale;
w = patternw * bbwscale;
h = patternh * bbhscale;
x = 0;
y = 0;
rsvg_preserve_aspect_ratio(rsvg_pattern->preserve_aspect_ratio,
......@@ -268,6 +299,7 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
caffine[3] = h / rsvg_pattern->vbh;
caffine[4] = x;
caffine[5] = y;
_rsvg_push_view_box(ctx, rsvg_pattern->vbw, rsvg_pattern->vbh);
}
else if (rsvg_pattern->obj_cbbox) {
/* If coords are in terms of the bounding box, use them */
......@@ -277,6 +309,7 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
caffine[3] = bbox.h;
caffine[4] = 0;
caffine[5] = 0;
_rsvg_push_view_box(ctx, 1., 1.);
} else {
/* Otherwise default to an identity matrix */
caffine[0] = 1;
......@@ -332,6 +365,8 @@ _set_source_rsvg_pattern (RsvgDrawingCtx *ctx,
cairo_pattern_destroy (pattern);
cairo_destroy (cr_pattern);
cairo_surface_destroy (surface);
if (rsvg_pattern->obj_cbbox || rsvg_pattern->vbox)
_rsvg_pop_view_box(ctx);
}
static void
......@@ -339,25 +374,22 @@ _set_source_rsvg_paint_server (RsvgDrawingCtx *ctx,
guint32 current_color_rgb,
RsvgPaintServer *ps,
guint8 opacity,
RsvgBbox bbox,
RsvgBbox bbox,
guint32 current_colour)
{
RsvgCairoRender *render = (RsvgCairoRender *)ctx->render;
cairo_t *cr = render->cr;
switch (ps->type) {
case RSVG_PAINT_SERVER_LIN_GRAD:
_set_source_rsvg_linear_gradient (cr, ps->core.lingrad,
_set_source_rsvg_linear_gradient (ctx, ps->core.lingrad,
current_color_rgb, opacity,
bbox);
break;
case RSVG_PAINT_SERVER_RAD_GRAD:
_set_source_rsvg_radial_gradient (cr, ps->core.radgrad,
_set_source_rsvg_radial_gradient (ctx, ps->core.radgrad,
current_color_rgb, opacity,
bbox);
break;
case RSVG_PAINT_SERVER_SOLID:
_set_source_rsvg_solid_colour (cr, ps->core.colour, opacity,
_set_source_rsvg_solid_colour (ctx, ps->core.colour, opacity,
current_colour);
break;
case RSVG_PAINT_SERVER_PATTERN:
......@@ -406,11 +438,12 @@ rsvg_cairo_render_path (RsvgDrawingCtx *ctx, const RsvgBpathDef *bpath_def)
_set_rsvg_affine (cr, state->affine);
cairo_set_line_width (cr, state->stroke_width);
cairo_set_line_width (cr, _rsvg_css_normalize_length_struct(&state->stroke_width, ctx, 'h'));
cairo_set_miter_limit (cr, state->miter_limit);
cairo_set_line_cap (cr, (cairo_line_cap_t)state->cap);
cairo_set_line_join (cr, (cairo_line_join_t)state->join);
cairo_set_dash (cr, state->dash.dash, state->dash.n_dash, state->dash.offset);
cairo_set_dash (cr, state->dash.dash, state->dash.n_dash,
_rsvg_css_normalize_length_struct(&state->dash.offset, ctx, 'o'));
for (i=0; i < bpath_def->n_bpath; i++) {
bpath = &bpath_def->bpath[i];
......
......@@ -184,17 +184,26 @@ _rsvg_css_normalize_length_struct(const RsvgLength * in, RsvgDrawingCtx * ctx,
return in->length * ctx->vb.w;
if (dir == 'v')
return in->length * ctx->vb.h;
if (dir == 'o')
return in->length * rsvg_viewport_percentage(ctx->vb.w, ctx->vb.h);
}
else if (in->factor == 'm' || in->factor == 'x')
{
double font = _rsvg_css_hand_normalize_length_struct(&rsvg_state_current(ctx)->font_size,
ctx->dpi_y, ctx->vb.h, 1);
if (in->factor == 'm')
return in->length * font;
else
return in->length * font / 2.;
}
else if (in->factor == 'm')
return in->length * rsvg_state_current(ctx)->font_size;
else if (in->factor == 'x')
return in->length * rsvg_state_current(ctx)->font_size / 2.;
else if (in->factor == 'i')
{
if (dir == 'h')
return in->length * ctx->dpi_x;
if (dir == 'v')
return in->length * ctx->dpi_y;
if (dir == 'o')
return in->length * rsvg_viewport_percentage(ctx->dpi_x, ctx->dpi_y);
}
return 0;
}
......@@ -217,37 +226,6 @@ _rsvg_css_hand_normalize_length_struct(const RsvgLength * in, gdouble pixels_per
return 0;
}
/**
* rsvg_css_parse_normalized_length: Parse CSS2 length to a pixel value.
* @str: Original string.
* @pixels_per_inch: Pixels per inch
* @normalize_to: Bounding box's width or height, as appropriate, or 0
*
* Parses a CSS2 length into a pixel value.
*
* Returns: returns the length.
*/
double
rsvg_css_parse_normalized_length(const char *str, gdouble pixels_per_inch,
gdouble width_or_height, gdouble font_size)
{
double length;
gint percent, em, ex, in;
percent = em = ex = in = FALSE;
length = rsvg_css_parse_length (str, &in, &percent, &em, &ex);
if (percent)
return length * width_or_height;
else if (em)
return length * font_size;
else if (ex)
return (length * font_size) / 2.;
else if (in)
return length * pixels_per_inch;
else
return length;
}
gboolean
rsvg_css_param_match (const char *str, const char *param_name)
{
......
......@@ -48,10 +48,6 @@ double
rsvg_css_parse_length (const char *str, gint *in,
gint *percent, gint *em, gint *ex);
double
rsvg_css_parse_normalized_length(const char *str, gdouble pixels_per_inch,
gdouble width_or_height, gdouble font_size);
gboolean
rsvg_css_param_match (const char *str, const char *param_name);
......
This diff is collapsed.
......@@ -36,7 +36,7 @@ typedef RsvgCoordUnits RsvgFilterUnits;
struct _RsvgFilter {
RsvgNode super;
int refcnt;
double x, y, width, height;
RsvgLength x, y, width, height;
RsvgFilterUnits filterunits;
RsvgFilterUnits primitiveunits;
};
......
......@@ -500,9 +500,12 @@ rsvg_node_image_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
int dominate)
{
RsvgNodeImage *z = (RsvgNodeImage *)self;
double x = z->x, y = z->y, w = z->w, h = z->h;
unsigned int aspect_ratio = z->preserve_aspect_ratio;
GdkPixbuf *img = z->img;
gdouble x = _rsvg_css_normalize_length_struct(&z->x, ctx, 'h');
gdouble y = _rsvg_css_normalize_length_struct(&z->y, ctx, 'v');
gdouble w = _rsvg_css_normalize_length_struct(&z->w, ctx, 'h');
gdouble h = _rsvg_css_normalize_length_struct(&z->h, ctx, 'v');
rsvg_state_reinherit_top(ctx, z->super.state, dominate);
......@@ -535,13 +538,13 @@ rsvg_node_image_set_atts (RsvgNode *self, RsvgHandle *ctx, RsvgPropertyBag *atts
if (rsvg_property_bag_size (atts))
{
if ((value = rsvg_property_bag_lookup (atts, "x")))
image->x = rsvg_css_parse_normalized_length (value, ctx->dpi_x, (gdouble)ctx->width, font_size);
image->x = _rsvg_css_parse_length_struct(value);
if ((value = rsvg_property_bag_lookup (atts, "y")))
image->y = rsvg_css_parse_normalized_length (value, ctx->dpi_y, (gdouble)ctx->height, font_size);
image->y = _rsvg_css_parse_length_struct(value);
if ((value = rsvg_property_bag_lookup (atts, "width")))
image->w = rsvg_css_parse_normalized_length (value, ctx->dpi_x, (gdouble)ctx->width, font_size);
image->w = _rsvg_css_parse_length_struct(value);
if ((value = rsvg_property_bag_lookup (atts, "height")))
image->h = rsvg_css_parse_normalized_length (value, ctx->dpi_y, (gdouble)ctx->height, font_size);
image->h = _rsvg_css_parse_length_struct(value);
/* path is used by some older adobe illustrator versions */
if ((value = rsvg_property_bag_lookup (atts, "path")) || (value = rsvg_property_bag_lookup (atts, "xlink:href")))
{
......@@ -581,10 +584,7 @@ rsvg_new_image (void)
image = g_new (RsvgNodeImage, 1);
image->img = NULL;
image->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
image->x = 0;
image->y = 0;
image->w = -1;
image->h = -1;
image->x = image->y = image->w = image->h = _rsvg_css_parse_length_struct("0");
image->super.state = g_new(RsvgState, 1);
rsvg_state_init(image->super.state);
image->super.type = RSVG_NODE_PATH;
......
......@@ -40,7 +40,8 @@ typedef struct _RsvgNodeImage RsvgNodeImage;
struct _RsvgNodeImage {
RsvgNode super;
gint preserve_aspect_ratio, x, y, w, h;
gint preserve_aspect_ratio;
RsvgLength x, y, w, h;
GdkPixbuf *img;
};
......
......@@ -65,13 +65,13 @@ rsvg_node_marker_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *at
}
}
if ((value = rsvg_property_bag_lookup (atts, "refX")))
marker->refX = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
marker->refX = _rsvg_css_parse_length_struct (value);
if ((value = rsvg_property_bag_lookup (atts, "refY")))
marker->refY = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
marker->refY = _rsvg_css_parse_length_struct (value);
if ((value = rsvg_property_bag_lookup (atts, "markerWidth")))
marker->width = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
marker->width = _rsvg_css_parse_length_struct (value);
if ((value = rsvg_property_bag_lookup (atts, "markerHeight")))
marker->height = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
marker->height = _rsvg_css_parse_length_struct (value);
if ((value = rsvg_property_bag_lookup (atts, "orient"))) {
if (!strcmp (value, "auto"))
marker->orientAuto = TRUE;
......@@ -81,7 +81,7 @@ rsvg_node_marker_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *at
if ((value = rsvg_property_bag_lookup (atts, "markerUnits"))) {
if (!strcmp (value, "userSpaceOnUse"))
marker->bbox = FALSE;
if (!strcmp (value, "objectBoundingBox"))
if (!strcmp (value, "strokeWidth"))
marker->bbox = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
......@@ -99,10 +99,8 @@ rsvg_new_marker (void)
marker->orient = 0;
marker->orientAuto = FALSE;
marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
marker->refX = 0;
marker->refY = 0;
marker->width = 1;
marker->height = 1;
marker->refX = marker->refY = _rsvg_css_parse_length_struct ("0");
marker->width = marker->height = _rsvg_css_parse_length_struct ("1");
marker->bbox = TRUE;
marker->vbox = FALSE;
marker->super.type = RSVG_NODE_MARKER;
......@@ -119,19 +117,26 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
gdouble rotation;
RsvgState * state = rsvg_state_current(ctx);
_rsvg_affine_translate(taffine, x, y);
_rsvg_affine_multiply(affine, taffine, state->affine);
if (self->orientAuto)
rotation = orient * 180. / M_PI;
else
rotation = self->orient;
_rsvg_affine_rotate(taffine, rotation);
_rsvg_affine_multiply(affine, taffine, affine);
if (self->bbox) {
_rsvg_affine_scale(affine,linewidth * state->affine[0],
linewidth * state->affine[3]);
} else {
for (i = 0; i < 6; i++)
affine[i] = state->affine[i];
}
_rsvg_affine_scale(taffine,linewidth, linewidth);
_rsvg_affine_multiply(affine, taffine, affine);
}
if (self->vbox) {
double w, h, x, y;
w = self->width;
h = self->height;
w = _rsvg_css_normalize_length_struct(&self->width, ctx, 'h');
h = _rsvg_css_normalize_length_struct(&self->height, ctx, 'v');
x = 0;
y = 0;
......@@ -139,8 +144,8 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
self->vbw, self->vbh,
&w, &h, &x, &y);
x -= self->vbx / self->vbw;
y -= self->vby / self->vbh;
x = -self->vbx * w / self->vbw;
y = -self->vby * h / self->vbh;
taffine[0] = w / self->vbw;
taffine[1] = 0.;
......@@ -148,25 +153,14 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
taffine[3] = h / self->vbh;
taffine[4] = x;
taffine[5] = y;
_rsvg_affine_multiply(affine, taffine, affine);
_rsvg_affine_multiply(affine, taffine, affine);
_rsvg_push_view_box(ctx, self->vbw, self->vbh);
}
_rsvg_affine_translate(taffine, -self->refX, -self->refY);
_rsvg_affine_translate(taffine,
-_rsvg_css_normalize_length_struct(&self->refX, ctx, 'h'),
-_rsvg_css_normalize_length_struct(&self->refY, ctx, 'v'));
_rsvg_affine_multiply(affine, taffine, affine);
if (self->orientAuto)
rotation = orient * 180. / M_PI;
else
rotation = self->orient;
_rsvg_affine_rotate(taffine, rotation);
_rsvg_affine_multiply(affine, affine, taffine);
_rsvg_affine_translate(taffine, x, y);
_rsvg_affine_multiply(affine, affine, taffine);
rsvg_state_push(ctx);
state = rsvg_state_current(ctx);
......@@ -177,9 +171,18 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
rsvg_state_reconstruct(state, &self->super);
for (i = 0; i < 6; i++)
{
state->affine[i] = affine[i];
}
state->affine[i] = affine[i];
rsvg_push_discrete_layer(ctx);
state = rsvg_state_current(ctx);
if (self->vbox)
rsvg_add_clipping_rect(ctx, self->vbx, self->vby, self->vbw, self->vbh);
else
rsvg_add_clipping_rect(ctx, 0, 0,
_rsvg_css_normalize_length_struct(&self->width, ctx, 'h'),
_rsvg_css_normalize_length_struct(&self->height, ctx, 'v'));
for (i = 0; i < self->super.children->len; i++)
{
......@@ -190,8 +193,11 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
rsvg_state_pop(ctx);
}
rsvg_pop_discrete_layer(ctx);
rsvg_state_pop(ctx);
if (self->vbox)
_rsvg_pop_view_box(ctx);
}
RsvgNode *
......@@ -241,7 +247,7 @@ rsvg_render_markers(const RsvgBpathDef * bpath_def, RsvgDrawingCtx *ctx)
state = rsvg_state_current(ctx);
linewidth = state->stroke_width;
linewidth = _rsvg_css_normalize_length_struct(&state->stroke_width, ctx, 'o');
startmarker = (RsvgMarker *)state->startMarker;
middlemarker = (RsvgMarker *)state->middleMarker;
endmarker = (RsvgMarker *)state->endMarker;
......@@ -251,10 +257,8 @@ rsvg_render_markers(const RsvgBpathDef * bpath_def, RsvgDrawingCtx *ctx)
x = 0;
y = 0;
nextx = state->affine[0] * bpath_def->bpath[0].x3 +
state->affine[2] * bpath_def->bpath[0].y3 + state->affine[4];
nexty = state->affine[1] * bpath_def->bpath[0].x3 +
state->affine[3] * bpath_def->bpath[0].y3 + state->affine[5];
nextx = bpath_def->bpath[0].x3;
nexty = bpath_def->bpath[0].y3;
for (i = 0; i < bpath_def->n_bpath - 1; i++)
{
......@@ -262,10 +266,8 @@ rsvg_render_markers(const RsvgBpathDef * bpath_def, RsvgDrawingCtx *ctx)
lasty = y;
x = nextx;
y = nexty;
nextx = state->affine[0] * bpath_def->bpath[i + 1].x3 +
state->affine[2] * bpath_def->bpath[i + 1].y3 + state->affine[4];
nexty = state->affine[1] * bpath_def->bpath[i + 1].x3 +
state->affine[3] * bpath_def->bpath[i + 1].y3 + state->affine[5];
nextx = bpath_def->bpath[i + 1].x3;
nexty = bpath_def->bpath[i + 1].y3;
if(bpath_def->bpath[i + 1].code == RSVG_MOVETO ||
bpath_def->bpath[i + 1].code == RSVG_MOVETO_OPEN ||
......
......@@ -34,8 +34,8 @@ typedef struct _RsvgMarker RsvgMarker;
struct _RsvgMarker {
RsvgNode super;
gboolean bbox;
double refX, refY, orient;
double vbx, vby, vbw, vbh, width, height;
RsvgLength refX, refY, width, height;
double vbx, vby, vbw, vbh, orient;
gint preserve_aspect_ratio;
gboolean vbox, orientAuto;
};
......
......@@ -214,7 +214,8 @@ rsvg_stop_set_atts (RsvgNode *self, RsvgHandle *ctx,
if ((value = rsvg_property_bag_lookup (atts, "offset")))
{
/* either a number [0,1] or a percentage */
offset = rsvg_css_parse_normalized_length (value, rsvg_dpi_percentage (ctx), 1., 0.);
RsvgLength length = _rsvg_css_parse_length_struct (value);
offset = _rsvg_css_hand_normalize_length_struct(&length, rsvg_dpi_percentage (ctx), 1., 0.);
if (offset < 0.)
offset = 0.;
......@@ -258,26 +259,25 @@ rsvg_linear_gradient_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag
{
RsvgLinearGradient *grad = (RsvgLinearGradient *)self;
const char *value;
double font_size = rsvg_state_current_font_size(ctx);
if (rsvg_property_bag_size (atts))
{
if ((value = rsvg_property_bag_lookup (atts, "id")))
rsvg_defs_register_name (ctx->defs, value, self);
if ((value = rsvg_property_bag_lookup (atts, "x1"))){
grad->x1 = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
grad->x1 = _rsvg_css_parse_length_struct (value);
grad->hasx1 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y1"))){
grad->y1 = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
grad->y1 = _rsvg_css_parse_length_struct (value);
grad->hasy1 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "x2"))){
grad->x2 = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
grad->x2 = _rsvg_css_parse_length_struct (value);
grad->hasx2 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y2"))){
grad->y2 = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
grad->y2 = _rsvg_css_parse_length_struct (value);
grad->hasy2 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "spreadMethod")))
......@@ -323,10 +323,8 @@ rsvg_new_linear_gradient (void)
grad->super.type = RSVG_NODE_LINGRAD;
_rsvg_affine_identity(grad->affine);
grad->has_current_color = FALSE;
grad->x1 = 0;
grad->y1 = 0;
grad->x2 = 1.0;
grad->y2 = 0;
grad->x1 = grad->y1 = grad->y2 = _rsvg_css_parse_length_struct ("0");
grad->x2 = _rsvg_css_parse_length_struct ("1");
grad->fallback = NULL;
grad->obj_bbox = TRUE;
grad->spread = RSVG_GRADIENT_PAD;
......@@ -340,34 +338,33 @@ rsvg_radial_gradient_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag
{
RsvgRadialGradient *grad = (RsvgRadialGradient *) self;
const char *value;
double font_size = rsvg_state_current_font_size(ctx);
if (rsvg_property_bag_size (atts))
{
if ((value = rsvg_property_bag_lookup (atts, "id")))
rsvg_defs_register_name (ctx->defs, value, self);
if ((value = rsvg_property_bag_lookup (atts, "cx"))){
grad->cx = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
grad->cx = _rsvg_css_parse_length_struct (value);
grad->hascx = TRUE;
if (!grad->hasfx)
grad->fx = grad->cx;
}
if ((value = rsvg_property_bag_lookup (atts, "cy"))){
grad->cy = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
grad->cy = _rsvg_css_parse_length_struct (value);
grad->hascy = TRUE;
if (!grad->hasfy)
grad->fy = grad->cy;
}
if ((value = rsvg_property_bag_lookup (atts, "r"))){
grad->r = rsvg_css_parse_normalized_length (value, rsvg_dpi_percentage (ctx), 1, font_size);
grad->r = _rsvg_css_parse_length_struct (value);
grad->hasr = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "fx"))){
grad->fx = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
grad->fx = _rsvg_css_parse_length_struct (value);
grad->hasfx = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "fy"))){
grad->fy = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
grad->fy = _rsvg_css_parse_length_struct (value);
grad->hasfy = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "xlink:href")))
......@@ -412,11 +409,7 @@ rsvg_new_radial_gradient (void)
grad->obj_bbox = TRUE;
grad->spread = RSVG_GRADIENT_PAD;
grad->fallback = NULL;
grad->cx = 0.5;
grad->cy = 0.5;
grad->r = 0.5;
grad->fx = 0.5;
grad->fy = 0.5;
grad->cx = grad->cy = grad->r = grad->fx = grad->fy = _rsvg_css_parse_length_struct("0.5");
grad->super.set_atts = rsvg_radial_gradient_set_atts;
grad->hascx = grad->hascy = grad->hasfx = grad->hasfy = grad->hasr = grad->hasbbox = grad->hasspread = grad->hastransform = FALSE;
return &grad->super;
......@@ -427,7 +420,6 @@ rsvg_pattern_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
RsvgPattern *pattern = (RsvgPattern *)self;
const char *value;
double font_size = rsvg_state_current_font_size(ctx);
if (rsvg_property_bag_size (atts))
{
......@@ -442,19 +434,19 @@ rsvg_pattern_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
pattern->hasvbox = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "x"))){
pattern->x = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
pattern->x = _rsvg_css_parse_length_struct (value);
pattern->hasx = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y"))){
pattern->y = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
pattern->y = _rsvg_css_parse_length_struct (value);
pattern->hasy = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "width"))){
pattern->width = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
pattern->width = _rsvg_css_parse_length_struct (value);
pattern->haswidth = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "height"))){
pattern->height = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
pattern->height = _rsvg_css_parse_length_struct (value);
pattern->hasheight = TRUE;