Commit 1872ec5b authored by Dom Lachowicz's avatar Dom Lachowicz

preliminary support for style definitions within defs-paths

parent 9f78465d
2003-03-25 Dom Lachowicz <cinamod@hotmail.com>
* rsvg-shapes.c: Support style information inside of defs paths
2003-03-25 Dom Lachowicz <cinamod@hotmail.com>
* rsvg.c: Support for <style> outside of a <defs> block
......
......@@ -46,7 +46,8 @@
struct _RsvgDefsPath {
RsvgDefVal super;
char *d;
RsvgState state;
char *d;
};
typedef struct _RsvgDefsPath RsvgDefsPath;
......@@ -175,7 +176,7 @@ rsvg_render_bpath (RsvgHandle *ctx, const ArtBpath *bpath)
return;
}
state = &ctx->state[ctx->n_state - 1];
state = rsvg_state_current (ctx);
/* todo: handle visibility stuff earlier for performance benefits
* handles all path based shapes. will handle text and images separately
......@@ -273,6 +274,7 @@ static void
rsvg_defs_path_free (RsvgDefVal *self)
{
RsvgDefsPath *z = (RsvgDefsPath *)self;
rsvg_state_finalize (&z->state);
g_free (z);
}
......@@ -292,6 +294,7 @@ rsvg_handle_path (RsvgHandle *ctx, const char * d, const char * id)
path = g_new (RsvgDefsPath, 1);
path->d = g_strdup(d);
rsvg_state_clone (&path->state, rsvg_state_current (ctx));
path->super.type = RSVG_DEF_PATH;
path->super.free = rsvg_defs_path_free;
......@@ -322,7 +325,7 @@ rsvg_start_path (RsvgHandle *ctx, const xmlChar **atts)
if (d == NULL)
return;
rsvg_parse_style_attrs (ctx, "path", klazz, id, atts);
rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "path", klazz, id, atts);
rsvg_handle_path (ctx, d, id);
}
......@@ -380,7 +383,7 @@ rsvg_start_any_poly(RsvgHandle *ctx, const xmlChar **atts, gboolean is_polyline)
if (!verts)
return;
rsvg_parse_style_attrs (ctx, (is_polyline ? "polyline" : "polygon"), klazz, id, atts);
rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), (is_polyline ? "polyline" : "polygon"), klazz, id, atts);
/* todo: make the following more memory and CPU friendly */
g = rsvg_make_poly_point_list (verts);
......@@ -428,7 +431,7 @@ rsvg_start_line (RsvgHandle *ctx, const xmlChar **atts)
double font_size;
if (ctx->n_state > 0)
font_size = ctx->state[ctx->n_state - 1].font_size;
font_size = rsvg_state_current (ctx)->font_size;
else
font_size = 12.0;
......@@ -450,7 +453,7 @@ rsvg_start_line (RsvgHandle *ctx, const xmlChar **atts)
id = (const char *)atts[i + 1];
}
}
rsvg_parse_style_attrs (ctx, "line", klazz, id, atts);
rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "line", klazz, id, atts);
/* emulate a line using a path */
/* ("M %f %f L %f %f", x1, y1, x2, y2) */
......@@ -480,7 +483,7 @@ rsvg_start_rect (RsvgHandle *ctx, const xmlChar **atts)
double font_size;
if (ctx->n_state > 0)
font_size = ctx->state[ctx->n_state - 1].font_size;
font_size = rsvg_state_current (ctx)->font_size;
else
font_size = 12.0;
......@@ -524,7 +527,7 @@ rsvg_start_rect (RsvgHandle *ctx, const xmlChar **atts)
if (ry > (h / 2.))
ry = h / 2.;
rsvg_parse_style_attrs (ctx, "rect", klazz, id, atts);
rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "rect", klazz, id, atts);
/* incrementing y by 1 properly draws borders. this is a HACK */
y += 1.;
......@@ -623,7 +626,7 @@ rsvg_start_circle (RsvgHandle *ctx, const xmlChar **atts)
double font_size;
if (ctx->n_state > 0)
font_size = ctx->state[ctx->n_state - 1].font_size;
font_size = rsvg_state_current (ctx)->font_size;
else
font_size = 12.0;
......@@ -649,7 +652,7 @@ rsvg_start_circle (RsvgHandle *ctx, const xmlChar **atts)
if (cx < 0. || cy < 0. || r <= 0.)
return;
rsvg_parse_style_attrs (ctx, "circle", klazz, id, atts);
rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "circle", klazz, id, atts);
/* approximate a circle using 4 bezier curves */
......@@ -727,7 +730,7 @@ rsvg_start_ellipse (RsvgHandle *ctx, const xmlChar **atts)
double font_size;
if (ctx->n_state > 0)
font_size = ctx->state[ctx->n_state - 1].font_size;
font_size = rsvg_state_current (ctx)->font_size;
else
font_size = 12.0;
......@@ -753,7 +756,7 @@ rsvg_start_ellipse (RsvgHandle *ctx, const xmlChar **atts)
if (cx < 0. || cy < 0. || rx <= 0. || ry <= 0.)
return;
rsvg_parse_style_attrs (ctx, "ellipse", klazz, id, atts);
rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "ellipse", klazz, id, atts);
/* approximate an ellipse using 4 bezier curves */
......@@ -844,7 +847,7 @@ rsvg_start_image (RsvgHandle *ctx, const xmlChar **atts)
/* skip over defs entries for now */
if (ctx->in_defs) return;
state = &ctx->state[ctx->n_state - 1];
state = rsvg_state_current (ctx);
if (atts != NULL)
{
......@@ -871,7 +874,7 @@ rsvg_start_image (RsvgHandle *ctx, const xmlChar **atts)
if (!href || x < 0. || y < 0. || w <= 0. || h <= 0.)
return;
rsvg_parse_style_attrs (ctx, "image", klazz, id, atts);
rsvg_parse_style_attrs (ctx, state, "image", klazz, id, atts);
/* figure out if image is visible or not */
if (!state->visible)
......@@ -940,12 +943,13 @@ rsvg_start_image (RsvgHandle *ctx, const xmlChar **atts)
void
rsvg_start_use (RsvgHandle *ctx, const xmlChar **atts)
{
RsvgState *state = &ctx->state[ctx->n_state - 1];
RsvgState *state = rsvg_state_current (ctx);
const char * klazz = NULL, *id = NULL, *xlink_href = NULL;
double x = 0, y = 0;
double x = 0, y = 0, width = 0, height = 0;
int i;
double affine[6];
gboolean got_width = FALSE, got_height = FALSE;
if (atts != NULL)
{
for (i = 0; atts[i] != NULL; i += 2)
......@@ -954,7 +958,14 @@ rsvg_start_use (RsvgHandle *ctx, const xmlChar **atts)
x = rsvg_css_parse_normalized_length ((char *)atts[i + 1], ctx->dpi, (gdouble)ctx->width, state->font_size);
else if (!strcmp ((char *)atts[i], "y"))
y = rsvg_css_parse_normalized_length ((char *)atts[i + 1], ctx->dpi, (gdouble)ctx->height, state->font_size);
else if (!strcmp ((char *)atts[i], "width")) {
width = rsvg_css_parse_normalized_length ((char *)atts[i + 1], ctx->dpi, (gdouble)ctx->height, state->font_size);
got_width = TRUE;
}
else if (!strcmp ((char *)atts[i], "height")) {
height = rsvg_css_parse_normalized_length ((char *)atts[i + 1], ctx->dpi, (gdouble)ctx->height, state->font_size);
got_height = TRUE;
}
else if (!strcmp ((char *)atts[i], "class"))
klazz = (const char *)atts[i + 1];
else if (!strcmp ((char *)atts[i], "id"))
......@@ -964,12 +975,10 @@ rsvg_start_use (RsvgHandle *ctx, const xmlChar **atts)
}
}
art_affine_translate (affine, x, y);
art_affine_multiply (state->affine, affine, state->affine);
rsvg_parse_style_attrs (ctx, "use", klazz, id, atts);
if (state->opacity != 0xff)
rsvg_push_opacity_group (ctx);
/* < 0 is an error, 0 disables rendering. TODO: handle positive values correctly */
if (got_width || got_height)
if (width <= 0. || height <= 0.)
return;
if (xlink_href != NULL)
{
......@@ -980,7 +989,17 @@ rsvg_start_use (RsvgHandle *ctx, const xmlChar **atts)
case RSVG_DEF_PATH:
{
RsvgDefsPath *path = (RsvgDefsPath*)parent;
/* always want to render inside of a USE */
/* combine state definitions */
rsvg_state_clone (state, &path->state);
art_affine_translate (affine, x, y);
art_affine_multiply (state->affine, affine, state->affine);
rsvg_parse_style_attrs (ctx, state, "use", klazz, id, atts);
if (state->opacity != 0xff)
rsvg_push_opacity_group (ctx);
/* always want to render inside of a <use/> */
rsvg_render_path (ctx, path->d);
break;
}
......
......@@ -750,6 +750,7 @@ rsvg_lookup_apply_css_style (RsvgHandle *ctx, const char * target)
/**
* rsvg_parse_style_attrs: Parse style attribute.
* @ctx: Rsvg context.
* @state: Rsvg state
* @tag: The SVG tag we're processing (eg: circle, ellipse), optionally %NULL
* @klazz: The space delimited class list, optionally %NULL
* @atts: Attributes in SAX style.
......@@ -758,7 +759,8 @@ rsvg_lookup_apply_css_style (RsvgHandle *ctx, const char * target)
* stack.
**/
void
rsvg_parse_style_attrs (RsvgHandle *ctx,
rsvg_parse_style_attrs (RsvgHandle * ctx,
RsvgState * state,
const char * tag,
const char * klazz,
const char * id,
......@@ -777,7 +779,7 @@ rsvg_parse_style_attrs (RsvgHandle *ctx,
* tag.class
* tag.class#id
*
* TODO: test that this reasonably works and conforms to the SVG/CSS spec
* This is basically a semi-compliant CSS2 selection engine
*/
/* * */
......@@ -846,14 +848,11 @@ rsvg_parse_style_attrs (RsvgHandle *ctx,
for (i = 0; atts[i] != NULL; i += 2)
{
if (!strcmp ((char *)atts[i], "style"))
rsvg_parse_style (ctx, &ctx->state[ctx->n_state - 1],
(char *)atts[i + 1]);
rsvg_parse_style (ctx, state, (char *)atts[i + 1]);
else if (!strcmp ((char *)atts[i], "transform"))
rsvg_parse_transform_attr (ctx, &ctx->state[ctx->n_state - 1],
(char *)atts[i + 1]);
rsvg_parse_transform_attr (ctx, state, (char *)atts[i + 1]);
else if (rsvg_is_style_arg ((char *)atts[i]))
rsvg_parse_style_pair (ctx, &ctx->state[ctx->n_state - 1],
(char *)atts[i], (char *)atts[i + 1]);
rsvg_parse_style_pair (ctx, state, (char *)atts[i], (char *)atts[i + 1]);
}
}
}
......@@ -980,3 +979,11 @@ rsvg_pop_opacity_group (RsvgHandle *ctx, int opacity)
g_object_unref (tos);
ctx->pixbuf = nos;
}
RsvgState *
rsvg_state_current (RsvgHandle *ctx)
{
if (ctx->n_state > 0)
return &ctx->state[ctx->n_state - 1];
return NULL;
}
......@@ -90,16 +90,18 @@ void rsvg_parse_style_pair (RsvgHandle *ctx, RsvgState *state,
const char *key, const char *val);
void rsvg_parse_style (RsvgHandle *ctx, RsvgState *state, const char *str);
void rsvg_parse_cssbuffer (RsvgHandle *ctx, const char * buff, size_t buflen);
void rsvg_parse_style_attrs (RsvgHandle *ctx, const char * tag,
void rsvg_parse_style_attrs (RsvgHandle *ctx, RsvgState *state, const char * tag,
const char * klazz, const char * id,
const xmlChar **atts);
gdouble rsvg_viewport_percentage (gdouble width, gdouble height);
void rsvg_pop_opacity_group (RsvgHandle *ctx, int opacity);
void rsvg_push_opacity_group (RsvgHandle *ctx);
gboolean rsvg_parse_transform (double dst[6], const char *src);
RsvgState * rsvg_state_current (RsvgHandle *ctx);
G_END_DECLS
#endif /* RSVG_STYLES_H */
......@@ -124,7 +124,7 @@ rsvg_text_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
PangoRectangle ink_rect, line_ink_rect;
FT_Bitmap bitmap;
state = &ctx->state[ctx->n_state - 1];
state = rsvg_state_current (ctx);
if (state->fill == NULL && state->font_size <= 0)
return;
......@@ -258,7 +258,7 @@ rsvg_start_tspan (RsvgHandle *ctx, const xmlChar **atts)
const char * klazz = NULL, * id = NULL;
x = y = dx = dy = 0.;
state = &ctx->state[ctx->n_state - 1];
state = rsvg_state_current (ctx);
if (atts != NULL)
{
......@@ -288,7 +288,7 @@ rsvg_start_tspan (RsvgHandle *ctx, const xmlChar **atts)
art_affine_translate (affine, x, y);
art_affine_multiply (state->affine, affine, state->affine);
}
rsvg_parse_style_attrs (ctx, "tspan", klazz, id, atts);
rsvg_parse_style_attrs (ctx, state, "tspan", klazz, id, atts);
}
static void
......@@ -358,7 +358,7 @@ rsvg_start_text (RsvgHandle *ctx, const xmlChar **atts)
x = y = dx = dy = 0.;
state = &ctx->state[ctx->n_state - 1];
state = rsvg_state_current (ctx);
if (atts != NULL)
{
......@@ -385,7 +385,7 @@ rsvg_start_text (RsvgHandle *ctx, const xmlChar **atts)
art_affine_translate (affine, x, y);
art_affine_multiply (state->affine, affine, state->affine);
rsvg_parse_style_attrs (ctx, "text", klazz, id, atts);
rsvg_parse_style_attrs (ctx, state, "text", klazz, id, atts);
handler->parent = ctx->handler;
ctx->handler = &handler->super;
......
......@@ -154,7 +154,7 @@ rsvg_start_svg (RsvgHandle *ctx, const xmlChar **atts)
}
/* Scale size of target pixbuf */
state = &ctx->state[ctx->n_state - 1];
state = rsvg_state_current (ctx);
art_affine_scale (state->affine, x_zoom, y_zoom);
#if 0
......@@ -210,7 +210,7 @@ rsvg_start_svg (RsvgHandle *ctx, const xmlChar **atts)
static void
rsvg_start_g (RsvgHandle *ctx, const xmlChar **atts)
{
RsvgState *state = &ctx->state[ctx->n_state - 1];
RsvgState *state = rsvg_state_current (ctx);
const char * klazz = NULL, * id = NULL;
int i;
......@@ -225,7 +225,7 @@ rsvg_start_g (RsvgHandle *ctx, const xmlChar **atts)
}
}
rsvg_parse_style_attrs (ctx, "g", klazz, id, atts);
rsvg_parse_style_attrs (ctx, state, "g", klazz, id, atts);
if (state->opacity != 0xff)
rsvg_push_opacity_group (ctx);
}
......@@ -233,7 +233,7 @@ rsvg_start_g (RsvgHandle *ctx, const xmlChar **atts)
static void
rsvg_end_g (RsvgHandle *ctx)
{
RsvgState *state = &ctx->state[ctx->n_state - 1];
RsvgState *state = rsvg_state_current (ctx);
if (state->opacity != 0xff)
rsvg_pop_opacity_group (ctx, state->opacity);
......@@ -396,7 +396,7 @@ rsvg_linear_gradient_free (RsvgDefVal *self)
static void
rsvg_start_linear_gradient (RsvgHandle *ctx, const xmlChar **atts)
{
RsvgState *state = &ctx->state[ctx->n_state - 1];
RsvgState *state = rsvg_state_current (ctx);
RsvgLinearGradient *grad = NULL;
int i;
const char *id = NULL;
......@@ -516,7 +516,7 @@ rsvg_radial_gradient_free (RsvgDefVal *self)
static void
rsvg_start_radial_gradient (RsvgHandle *ctx, const xmlChar **atts, const char * tag) /* tag for conicalGradient */
{
RsvgState *state = &ctx->state[ctx->n_state - 1];
RsvgState *state = rsvg_state_current (ctx);
RsvgRadialGradient *grad = NULL;
int i;
const char *id = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment