diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | rsvg-base.c | 165 | ||||
-rw-r--r-- | rsvg-cairo-draw.c | 32 | ||||
-rw-r--r-- | rsvg-cairo-render.c | 2 | ||||
-rw-r--r-- | rsvg-css.c | 100 | ||||
-rw-r--r-- | rsvg-css.h | 3 | ||||
-rw-r--r-- | rsvg-mask.c | 40 | ||||
-rw-r--r-- | rsvg-mask.h | 3 | ||||
-rw-r--r-- | rsvg-private.h | 29 | ||||
-rw-r--r-- | rsvg-structure.c | 47 | ||||
-rw-r--r-- | rsvg-structure.h | 2 | ||||
-rw-r--r-- | rsvg.c | 3 |
12 files changed, 356 insertions, 75 deletions
@@ -1,3 +1,8 @@ +2005-10-22 Caleb Moore <c.moore@student.unsw.edu.au> + + * a_lot_of_places: implemented a system of late normalizations of lengths. Now used in masks and svgs + * rsvg-base.c: find out the size of the contents of an SVG if there is nothing else to go on. + 2005-10-20 Dom Lachowicz <cinamod@hotmail.com> * configure.in: Prioritize the cairo backend over the libart one; disable the libart backend until it builds again diff --git a/rsvg-base.c b/rsvg-base.c index fddd0ee1..3fda9c18 100644 --- a/rsvg-base.c +++ b/rsvg-base.c @@ -1040,6 +1040,133 @@ rsvg_handle_new (void) return handle; } +typedef struct { + RsvgRender super; + RsvgBbox bbox; +} RsvgBboxRender; + +static void +rsvg_bbox_render_path (RsvgDrawingCtx *ctx, const RsvgBpathDef *bpath_def) +{ + RsvgState *state = rsvg_state_current (ctx); + RsvgBpath *bpath; + RsvgBboxRender *render = (RsvgBboxRender *)ctx->render; + RsvgBbox bbox; + int i; + + rsvg_bbox_init(&bbox, state->affine); + bbox.w = bbox.h = bbox.virgin = 0; + + for (i=0; i < bpath_def->n_bpath; i++) { + bpath = &bpath_def->bpath[i]; + + switch (bpath->code) { + case RSVG_MOVETO: + case RSVG_MOVETO_OPEN: + case RSVG_CURVETO: + case RSVG_LINETO: + bbox.x = bpath->x3; + bbox.y = bpath->y3; + rsvg_bbox_insert(&render->bbox, &bbox); + break; + default: + break; + } + } +} + +static void rsvg_bbox_render_image (RsvgDrawingCtx *ctx, + const GdkPixbuf * pixbuf, + double pixbuf_x, double pixbuf_y, + double w, double h) +{ + RsvgState *state = rsvg_state_current (ctx); + RsvgBboxRender *render = (RsvgBboxRender *)ctx->render; + RsvgBbox bbox; + + rsvg_bbox_init(&bbox, state->affine); + bbox.x = pixbuf_x; + bbox.y = pixbuf_y; + bbox.w = w; + bbox.h = h; + bbox.virgin = 0; + + rsvg_bbox_insert(&render->bbox, &bbox); +} + + +static void +rsvg_bbox_render_free (RsvgRender * self) +{ + g_free (self); +} + +static void +rsvg_bbox_push_discrete_layer (RsvgDrawingCtx *ctx) {} + +static void +rsvg_bbox_pop_discrete_layer (RsvgDrawingCtx *ctx) {} + +static void +rsvg_bbox_add_clipping_rect (RsvgDrawingCtx *ctx, + double x, double y, + double w, double h){} + +static RsvgBboxRender * +rsvg_bbox_render_new() +{ + RsvgBboxRender * render = g_new0(RsvgBboxRender, 1); + double affine[6]; + + render->super.free = rsvg_bbox_render_free; + render->super.render_image = rsvg_bbox_render_image; + render->super.render_path = rsvg_bbox_render_path; + render->super.pop_discrete_layer = + rsvg_bbox_pop_discrete_layer; + render->super.push_discrete_layer = + rsvg_bbox_push_discrete_layer; + render->super.add_clipping_rect = + rsvg_bbox_add_clipping_rect; + render->super.get_image_of_node = NULL; + _rsvg_affine_identity(affine); + rsvg_bbox_init(&render->bbox, affine); + + return render; +} + +static RsvgBbox +_rsvg_find_bbox (RsvgHandle *handle) +{ + RsvgDrawingCtx * ctx = g_new(RsvgDrawingCtx, 1); + RsvgBbox output; + RsvgBboxRender * render = rsvg_bbox_render_new(); + ctx->render = (RsvgRender *)render; + + ctx->state = NULL; + + ctx->state_allocator = g_mem_chunk_create (RsvgState, 256, G_ALLOC_AND_FREE); + + ctx->defs = handle->defs; + ctx->base_uri = g_strdup(handle->base_uri); + ctx->dpi_x = handle->dpi_x; + ctx->dpi_y = handle->dpi_y; + ctx->vb.w = 512; + ctx->vb.h = 512; + ctx->pango_context = NULL; + + rsvg_state_push(ctx); + _rsvg_affine_identity(rsvg_state_current(ctx)->affine); + + rsvg_state_push(ctx); + _rsvg_node_draw_children ((RsvgNode *)handle->treebase, ctx, 0); + rsvg_state_pop(ctx); + + output = render->bbox; + rsvg_render_free(ctx->render); + g_free(ctx); + return output; +} + void rsvg_handle_get_dimensions(RsvgHandle * handle, RsvgDimensionData * output) { @@ -1053,8 +1180,21 @@ rsvg_handle_get_dimensions(RsvgHandle * handle, RsvgDimensionData * output) if (sself->hasw && sself->hash) { - output->width = sself->w; - output->height = sself->h; + RsvgBbox bbox; + if (sself->w.factor == 'p' || sself->h.factor == 'p') + { + if (sself->has_vbox && sself->vbw > 0. && sself->vbh > 0.) + { + bbox.w = sself->vbw; + bbox.h = sself->vbh; + } + else + bbox = _rsvg_find_bbox(handle); + } + output->width = _rsvg_css_hand_normalize_length_struct(&sself->w, handle->dpi_x, + bbox.w, 12); + output->height = _rsvg_css_hand_normalize_length_struct(&sself->h, handle->dpi_y, + bbox.h, 12); } else if (sself->has_vbox && sself->vbw > 0. && sself->vbh > 0.) { @@ -1063,8 +1203,10 @@ rsvg_handle_get_dimensions(RsvgHandle * handle, RsvgDimensionData * output) } else { - output->width = 512; - output->height = 512; + RsvgBbox bbox; + bbox = _rsvg_find_bbox(handle); + output->width = bbox.w; + output->height = bbox.h; } output->em = output->width; @@ -1486,3 +1628,18 @@ void rsvg_bbox_clip(RsvgBbox * dst, RsvgBbox * src) dst->h = ymax - ymin; } +void _rsvg_push_view_box(RsvgDrawingCtx *ctx, double w, double h) +{ + RsvgViewBox * vb = g_new(RsvgViewBox, 1); + *vb = ctx->vb; + ctx->vb_stack = g_slist_prepend(ctx->vb_stack, vb); + ctx->vb.w = w; + ctx->vb.h = h; +} + +void _rsvg_pop_view_box(RsvgDrawingCtx *ctx) +{ + ctx->vb = *((RsvgViewBox *)ctx->vb_stack->data); + g_free(ctx->vb_stack->data); + ctx->vb_stack = g_slist_remove_link(ctx->vb_stack, ctx->vb_stack); +} diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c index 9ac9531d..24d6b757 100644 --- a/rsvg-cairo-draw.c +++ b/rsvg-cairo-draw.c @@ -633,7 +633,19 @@ rsvg_cairo_generate_mask(cairo_t *cr, guint32 width = render->width, height = render->height; guint32 rowstride = width * 4, row, i; double affinesave[6]; + double sx, sy, sw, sh; + if (self->maskunits == objectBoundingBox) + _rsvg_push_view_box(ctx, 1, 1); + + sx = _rsvg_css_normalize_length_struct(&self->x, ctx, 'h'); + sy = _rsvg_css_normalize_length_struct(&self->y, ctx, 'v'); + sw = _rsvg_css_normalize_length_struct(&self->width, ctx, 'h'); + sh = _rsvg_css_normalize_length_struct(&self->height, ctx, 'v'); + + if (self->maskunits == objectBoundingBox) + _rsvg_pop_view_box(ctx); + pixels = g_new0(guint8, height * rowstride); surface = cairo_image_surface_create_for_data (pixels, CAIRO_FORMAT_ARGB32, @@ -646,13 +658,12 @@ rsvg_cairo_generate_mask(cairo_t *cr, if (self->maskunits == objectBoundingBox) rsvg_cairo_add_clipping_rect (ctx, - self->x * bbox->w + bbox->x, - self->y * bbox->h + bbox->y, - self->width * bbox->w, - self->height * bbox->h); + sx * bbox->w + bbox->x, + sy * bbox->h + bbox->y, + sw * bbox->w, + sh * bbox->h); else - rsvg_cairo_add_clipping_rect (ctx, self->x, self->y, - self->width, self->height); + rsvg_cairo_add_clipping_rect (ctx, sx, sy, sw, sh); /* Horribly dirty hack to have the bbox premultiplied to everything */ if (self->contentunits == objectBoundingBox) @@ -669,6 +680,7 @@ rsvg_cairo_generate_mask(cairo_t *cr, _rsvg_affine_multiply(self->super.state->affine, bbtransform, self->super.state->affine); + _rsvg_push_view_box(ctx, 1, 1); } rsvg_state_push(ctx); @@ -676,9 +688,11 @@ rsvg_cairo_generate_mask(cairo_t *cr, rsvg_state_pop(ctx); if (self->contentunits == objectBoundingBox) - for (i = 0; i < 6; i++) - self->super.state->affine[i] = affinesave[i]; - + { + _rsvg_pop_view_box(ctx); + for (i = 0; i < 6; i++) + self->super.state->affine[i] = affinesave[i]; + } render->cr = save_cr; diff --git a/rsvg-cairo-render.c b/rsvg-cairo-render.c index f3f7549f..4414ff8d 100644 --- a/rsvg-cairo-render.c +++ b/rsvg-cairo-render.c @@ -94,6 +94,8 @@ rsvg_cairo_new_drawing_ctx (cairo_t *cr, RsvgHandle *handle) draw->base_uri = g_strdup(handle->base_uri); draw->dpi_x = handle->dpi_x; draw->dpi_y = handle->dpi_y; + draw->vb.w = data.em; + draw->vb.h = data.ex; draw->pango_context = NULL; rsvg_state_push(draw); @@ -25,6 +25,8 @@ #include "config.h" #include "rsvg-css.h" +#include "rsvg-private.h" +#include "rsvg-styles.h" #include <glib.h> #include <stdio.h> @@ -90,7 +92,7 @@ rsvg_css_parse_vbox (const char * vbox, double * x, double * y, * Returns: returns the length. **/ double -rsvg_css_parse_length (const char *str, gdouble pixels_per_inch, +rsvg_css_parse_length (const char *str, gint *in, gint *percent, gint *em, gint *ex) { double length = 0.0; @@ -114,15 +116,27 @@ rsvg_css_parse_length (const char *str, gdouble pixels_per_inch, if (p && (strcmp(p, "px") != 0)) { if (!strcmp(p, "pt")) - length *= (pixels_per_inch / POINTS_PER_INCH); + { + length /= POINTS_PER_INCH; + *in = TRUE; + } else if (!strcmp(p, "in")) - length *= pixels_per_inch; + *in = TRUE; else if (!strcmp(p, "cm")) - length *= (pixels_per_inch / CM_PER_INCH); + { + length /= CM_PER_INCH; + *in = TRUE; + } else if (!strcmp(p, "mm")) - length *= (pixels_per_inch / MM_PER_INCH); + { + length /= MM_PER_INCH; + *in = TRUE; + } else if (!strcmp(p, "pc")) - length *= (pixels_per_inch / PICA_PER_INCH); + { + length /= PICA_PER_INCH; + *in = TRUE; + } else if (!strcmp(p, "em")) *em = TRUE; else if (!strcmp(p, "ex")) @@ -137,6 +151,72 @@ rsvg_css_parse_length (const char *str, gdouble pixels_per_inch, return length; } +RsvgLength +_rsvg_css_parse_length_struct(const char *str) +{ + RsvgLength out; + gint percent, em, ex, in; + percent = em = ex = in = FALSE; + + out.length = rsvg_css_parse_length (str, &in, &percent, &em, &ex); + if (percent) + out.factor = 'p'; + else if (em) + out.factor = 'm'; + else if (ex) + out.factor = 'x'; + else if (in) + out.factor = 'i'; + else + out.factor = '\0'; + return out; +} + +double +_rsvg_css_normalize_length_struct(const RsvgLength * in, RsvgDrawingCtx * ctx, + char dir) +{ + if (in->factor == '\0') + return in->length; + else if (in->factor == 'p') + { + if (dir == 'h') + return in->length * ctx->vb.w; + if (dir == 'v') + return in->length * ctx->vb.h; + } + 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; + } + return 0; +} + +double +_rsvg_css_hand_normalize_length_struct(const RsvgLength * in, gdouble pixels_per_inch, + gdouble width_or_height, gdouble font_size) +{ + if (in->factor == '\0') + return in->length; + else if (in->factor == 'p') + return in->length * width_or_height; + else if (in->factor == 'm') + return in->length * font_size; + else if (in->factor == 'x') + return in->length * font_size / 2.; + else if (in->factor == 'i') + return in->length * pixels_per_inch; + + return 0; +} + /** * rsvg_css_parse_normalized_length: Parse CSS2 length to a pixel value. * @str: Original string. @@ -152,16 +232,18 @@ 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; - percent = em = ex = FALSE; + gint percent, em, ex, in; + percent = em = ex = in = FALSE; - length = rsvg_css_parse_length (str, pixels_per_inch, &percent, &em, &ex); + 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; } @@ -45,7 +45,7 @@ G_BEGIN_DECLS int rsvg_css_parse_aspect_ratio(const char * str); double -rsvg_css_parse_length (const char *str, gdouble pixels_per_inch, +rsvg_css_parse_length (const char *str, gint *in, gint *percent, gint *em, gint *ex); double @@ -105,6 +105,7 @@ rsvg_css_parse_number_list(const char * in_str, guint * out_list_len); gboolean rsvg_css_parse_overflow(const char * str, gboolean * inherit); + G_END_DECLS #endif /* RSVG_CSS_H */ diff --git a/rsvg-mask.c b/rsvg-mask.c index 82b56468..535886a1 100644 --- a/rsvg-mask.c +++ b/rsvg-mask.c @@ -33,20 +33,14 @@ rsvg_mask_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts) { const char *id = NULL, *klazz = NULL, *value; RsvgMask *mask; - double font_size, xscale = 1., yscale = 1.; - - font_size = rsvg_state_current_font_size (ctx); mask = (RsvgMask *)self; if (rsvg_property_bag_size (atts)) { if ((value = rsvg_property_bag_lookup (atts, "maskUnits"))) { - if (!strcmp (value, "userSpaceOnUse")){ + if (!strcmp (value, "userSpaceOnUse")) mask->maskunits = userSpaceOnUse; - xscale = (gdouble)ctx->width; - yscale = (gdouble)ctx->height; - } else mask->maskunits = objectBoundingBox; } @@ -58,29 +52,13 @@ rsvg_mask_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts) mask->contentunits = userSpaceOnUse; } if ((value = rsvg_property_bag_lookup (atts, "x"))) - mask->x = - rsvg_css_parse_normalized_length (value, - ctx->dpi_x, - xscale, - font_size); + mask->x = _rsvg_css_parse_length_struct (value); if ((value = rsvg_property_bag_lookup (atts, "y"))) - mask->y = - rsvg_css_parse_normalized_length (value, - ctx->dpi_y, - yscale, - font_size); + mask->y = _rsvg_css_parse_length_struct (value); if ((value = rsvg_property_bag_lookup (atts, "width"))) - mask->width = - rsvg_css_parse_normalized_length (value, - ctx->dpi_x, - xscale, - font_size); + mask->width = _rsvg_css_parse_length_struct (value); if ((value = rsvg_property_bag_lookup (atts, "height"))) - mask->height = - rsvg_css_parse_normalized_length (value, - ctx->dpi_y, - yscale, - font_size); + mask->height = _rsvg_css_parse_length_struct (value); if ((value = rsvg_property_bag_lookup (atts, "id"))) { id = value; @@ -102,10 +80,10 @@ rsvg_new_mask (void) _rsvg_node_init(&mask->super); mask->maskunits = objectBoundingBox; mask->contentunits = userSpaceOnUse; - mask->x = 0; - mask->y = 0; - mask->width = 1; - mask->height = 1; + mask->x = _rsvg_css_parse_length_struct ("0"); + mask->y = _rsvg_css_parse_length_struct ("0"); + mask->width = _rsvg_css_parse_length_struct ("1"); + mask->height = _rsvg_css_parse_length_struct ("1"); mask->super.type = RSVG_NODE_MASK; mask->super.set_atts = rsvg_mask_set_atts; return &mask->super; diff --git a/rsvg-mask.h b/rsvg-mask.h index 13ccba0b..46eacd5b 100644 --- a/rsvg-mask.h +++ b/rsvg-mask.h @@ -27,6 +27,7 @@ #include "rsvg.h" #include "rsvg-defs.h" +#include "rsvg-css.h" #include "rsvg-styles.h" #include "rsvg-shapes.h" #include <libxml/SAX.h> @@ -39,7 +40,7 @@ typedef struct _RsvgMask RsvgMask; struct _RsvgMask { RsvgNode super; - double x, y, width, height; + RsvgLength x, y, width, height; RsvgMaskUnits maskunits; RsvgMaskUnits contentunits; }; diff --git a/rsvg-private.h b/rsvg-private.h index f9aecc67..8bb6f136 100644 --- a/rsvg-private.h +++ b/rsvg-private.h @@ -65,7 +65,6 @@ typedef struct _RsvgIRect RsvgIRect; # endif /* G_PI */ #endif /* M_PI */ - struct RsvgSaxHandler { void (*free) (RsvgSaxHandler *self); void (*start_element) (RsvgSaxHandler *self, const xmlChar *name, RsvgPropertyBag *atts); @@ -122,6 +121,10 @@ struct RsvgHandle { void * gzipped_data; /* really a GsfOutput */ }; +typedef struct{ + double w, h; +} RsvgViewBox; + /*Contextual information for the drawing phase*/ struct RsvgDrawingCtx { @@ -132,8 +135,9 @@ struct RsvgDrawingCtx { gchar * base_uri; GMemChunk * state_allocator; PangoContext *pango_context; - double dpi_x; - double dpi_y; + double dpi_x, dpi_y; + RsvgViewBox vb; + GSList * vb_stack; }; /*Abstract base class for context for our backends (one as yet)*/ @@ -152,6 +156,12 @@ struct RsvgRender { double w, double h); }; + +typedef struct{ + double length; + char factor; +} RsvgLength; + struct _RsvgIRect { int x0, y0, x1, y1; }; @@ -331,6 +341,19 @@ void rsvg_bbox_init(RsvgBbox * self, double * affine); void rsvg_bbox_insert(RsvgBbox * dst, RsvgBbox * src); void rsvg_bbox_clip(RsvgBbox * dst, RsvgBbox * src); +double +_rsvg_css_normalize_length_struct(const RsvgLength * in, RsvgDrawingCtx * ctx, + char dir); +double +_rsvg_css_hand_normalize_length_struct(const RsvgLength * in, gdouble pixels_per_inch, + gdouble width_or_height, gdouble font_size); + +RsvgLength +_rsvg_css_parse_length_struct(const char *str); + +void _rsvg_push_view_box(RsvgDrawingCtx *ctx, double w, double h); +void _rsvg_pop_view_box(RsvgDrawingCtx *ctx); + G_END_DECLS #endif diff --git a/rsvg-structure.c b/rsvg-structure.c index e65779cb..ed2433e6 100644 --- a/rsvg-structure.c +++ b/rsvg-structure.c @@ -204,11 +204,12 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx *ctx, -symbol->y); _rsvg_affine_multiply(state->affine, affine, state->affine); + _rsvg_push_view_box(ctx, symbol->width, symbol->height); + rsvg_push_discrete_layer (ctx); if (!state->overflow || (!state->has_overflow && child->state->overflow)) - rsvg_push_discrete_layer (ctx); - rsvg_add_clipping_rect (ctx, symbol->x, symbol->y, - symbol->width, symbol->height); + rsvg_add_clipping_rect (ctx, symbol->x, symbol->y, + symbol->width, symbol->height); } else { _rsvg_affine_translate(affine, use->x, use->y); _rsvg_affine_multiply(state->affine, affine, state->affine); @@ -219,6 +220,8 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx *ctx, _rsvg_node_draw_children(child, ctx, 1); rsvg_state_pop(ctx); rsvg_pop_discrete_layer (ctx); + if (symbol->has_vbox) + _rsvg_pop_view_box(ctx); } } @@ -240,8 +243,14 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx, RsvgState *state; gdouble affine[6], affine_old[6], affine_new[6]; guint i; + double nx, ny, nw, nh; sself = (RsvgNodeSvg *)self; + nx = _rsvg_css_normalize_length_struct(&sself->x, ctx, 'h'); + ny = _rsvg_css_normalize_length_struct(&sself->y, ctx, 'v'); + nw = _rsvg_css_normalize_length_struct(&sself->w, ctx, 'h'); + nh = _rsvg_css_normalize_length_struct(&sself->h, ctx, 'v'); + rsvg_state_reinherit_top(ctx, self->state, dominate); state = rsvg_state_current (ctx); @@ -251,7 +260,7 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx, if (sself->has_vbox && sself->hasw && sself->hash) { - double x = sself->x, y = sself->y, w = sself->w, h = sself->h; + double x = nx, y = ny, w = nw, h = nh; rsvg_preserve_aspect_ratio(sself->preserve_aspect_ratio, sself->vbw, sself->vbh, &w, &h, &x, &y); @@ -263,6 +272,7 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx, affine[5] = y - sself->vby * h / sself->vbh; _rsvg_affine_multiply(state->affine, affine, state->affine); + _rsvg_push_view_box(ctx, sself->vbw, sself->vbh); } else { @@ -270,10 +280,11 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx, affine[1] = 0; affine[2] = 0; affine[3] = 1; - affine[4] = sself->x; - affine[5] = sself->y; + affine[4] = nx; + affine[5] = ny; _rsvg_affine_multiply(state->affine, affine, state->affine); + _rsvg_push_view_box(ctx, nw, nh); } for (i = 0; i < 6; i++) affine_new[i] = state->affine[i]; @@ -286,7 +297,7 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx, { for (i = 0; i < 6; i++) state->affine[i] = affine_old[i]; - rsvg_add_clipping_rect(ctx, sself->x, sself->y, sself->w, sself->h); + rsvg_add_clipping_rect(ctx, nx, ny, nw, nh); for (i = 0; i < 6; i++) state->affine[i] = affine_new[i]; } @@ -300,6 +311,7 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx, } rsvg_pop_discrete_layer (ctx); + _rsvg_pop_view_box(ctx); } static void @@ -329,22 +341,22 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts) svg->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value); if ((value = rsvg_property_bag_lookup (atts, "width"))) { - svg->w = rsvg_css_parse_normalized_length (value, ctx->dpi_x, ctx->width, 1); - svg->hasw = (svg->w > 0); + svg->w = _rsvg_css_parse_length_struct (value); + svg->hasw = svg->w.length > 0; if (!svg->has_vbox) - ctx->width = svg->w; + ctx->width = svg->w.length; } if ((value = rsvg_property_bag_lookup (atts, "height"))) { - svg->h = rsvg_css_parse_normalized_length (value, ctx->dpi_y, ctx->height, 1); - svg->hash = (svg->h > 0); + svg->h = _rsvg_css_parse_length_struct (value); + svg->hash = svg->h.length > 0; if (!svg->has_vbox) - ctx->height = svg->h; + ctx->height = svg->h.length; } if ((value = rsvg_property_bag_lookup (atts, "x"))) - svg->x = rsvg_css_parse_normalized_length (value, ctx->dpi_x, ctx->width, 1); + svg->x = _rsvg_css_parse_length_struct (value); if ((value = rsvg_property_bag_lookup (atts, "y"))) - svg->y = rsvg_css_parse_normalized_length (value, ctx->dpi_y, ctx->height, 1); + svg->y = _rsvg_css_parse_length_struct (value); if ((value = rsvg_property_bag_lookup (atts, "id"))) { id = value; @@ -361,7 +373,10 @@ rsvg_new_svg (void) _rsvg_node_init(&svg->super); svg->has_vbox = FALSE; svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID; - svg->x = 0; svg->y = 0; svg->w = -1; svg->h = -1; + svg->x = _rsvg_css_parse_length_struct ("0"); + svg->y = _rsvg_css_parse_length_struct ("0"); + svg->w = _rsvg_css_parse_length_struct ("0"); + svg->h = _rsvg_css_parse_length_struct ("0"); svg->hasw = svg->hash = FALSE; svg->vbx = 0; svg->vby = 0; svg->vbw = 0; svg->vbh = 0; svg->super.type = RSVG_NODE_PATH; diff --git a/rsvg-structure.h b/rsvg-structure.h index c6a72516..e92acb5c 100644 --- a/rsvg-structure.h +++ b/rsvg-structure.h @@ -67,7 +67,7 @@ struct _RsvgNodeUse { struct _RsvgNodeSvg { RsvgNode super; gint preserve_aspect_ratio; - gdouble x, y, w, h; + RsvgLength x, y, w, h; int hasw :1; int hash :1; gdouble vbx, vby, vbw, vbh; @@ -77,6 +77,9 @@ rsvg_new_drawing_ctx(RsvgHandle * handle) draw->base_uri = g_strdup(handle->base_uri); draw->dpi_x = handle->dpi_x; draw->dpi_y = handle->dpi_y; + draw->vb.w = data.w; + draw->vb.h = data.h; + draw->vb_stack = NULL; draw->pango_context = NULL; rsvg_state_push(draw); |