[lasem] <svg;marker> Start to render something.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [lasem] <svg;marker> Start to render something.
- Date: Wed, 12 Aug 2009 21:23:59 +0000 (UTC)
commit e1639c3462fc1b5463dd717463785d51a6c05c09
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Wed Aug 12 23:22:40 2009 +0200
<svg;marker> Start to render something.
src/lsmsvgdocument.c | 23 ++++
src/lsmsvgdocument.h | 1 +
src/lsmsvgelement.c | 4 +-
src/lsmsvgmarkerelement.c | 125 +++++++++++++++++++++-
src/lsmsvgmarkerelement.h | 12 ++
src/lsmsvgpatternelement.c | 1 -
src/lsmsvgstyle.c | 11 ++
src/lsmsvgstyle.h | 1 +
src/lsmsvgtraits.c | 22 ++--
src/lsmsvgtraits.h | 2 +-
src/lsmsvguseelement.c | 1 -
src/lsmsvgview.c | 253 ++++++++++++++++++++++++++-----------------
12 files changed, 337 insertions(+), 119 deletions(-)
---
diff --git a/src/lsmsvgdocument.c b/src/lsmsvgdocument.c
index 9adbf61..3354a68 100644
--- a/src/lsmsvgdocument.c
+++ b/src/lsmsvgdocument.c
@@ -55,6 +55,29 @@ lsm_svg_document_can_append_child (LsmDomNode *self, LsmDomNode *child)
/* LsmDomDocument implementation */
+LsmSvgElement *
+lsm_svg_document_get_element_by_url (LsmSvgDocument *document, const char *url)
+{
+ LsmDomElement *element;
+ char *end;
+ char *id;
+
+ g_return_val_if_fail (LSM_IS_SVG_DOCUMENT (document), NULL);
+
+ if (url == NULL || strncmp (url, "url(#", 5) != 0)
+ return NULL;
+
+ id = g_strdup (url + 5);
+ for (end = id; *end != '\0' && *end != ')'; end++);
+ *end = '\0';
+
+ element = lsm_dom_document_get_element_by_id (LSM_DOM_DOCUMENT (document), id);
+
+ g_free (id);
+
+ return LSM_SVG_ELEMENT (element);
+}
+
static LsmDomElement *
lsm_svg_document_create_element (LsmDomDocument *document, const char *tag_name)
{
diff --git a/src/lsmsvgdocument.h b/src/lsmsvgdocument.h
index ba173a9..3df022b 100644
--- a/src/lsmsvgdocument.h
+++ b/src/lsmsvgdocument.h
@@ -48,6 +48,7 @@ GType lsm_svg_document_get_type (void);
LsmSvgDocument * lsm_svg_document_new (void);
LsmSvgSvgElement * lsm_svg_document_get_root_element (const LsmSvgDocument *document);
+LsmSvgElement * lsm_svg_document_get_element_by_url (LsmSvgDocument *document, const char *url);
G_END_DECLS
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index 8c5ab53..331cd09 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -27,6 +27,7 @@
#include <lsmsvgpatternelement.h>
#include <lsmsvggradientelement.h>
#include <lsmsvgclippathelement.h>
+#include <lsmsvgmarkerelement.h>
#include <lsmsvgmaskelement.h>
#include <lsmsvgview.h>
#include <string.h>
@@ -161,7 +162,8 @@ lsm_svg_element_force_render (LsmSvgElement *element, LsmSvgView *view)
g_return_if_fail (LSM_IS_SVG_PATTERN_ELEMENT (element) ||
LSM_IS_SVG_GRADIENT_ELEMENT (element) ||
LSM_IS_SVG_MASK_ELEMENT (element) ||
- LSM_IS_SVG_CLIP_PATH_ELEMENT (element));
+ LSM_IS_SVG_CLIP_PATH_ELEMENT (element) ||
+ LSM_IS_SVG_MARKER_ELEMENT (element));
lsm_svg_element_enable_rendering (element);
lsm_svg_element_render (element, view);
diff --git a/src/lsmsvgmarkerelement.c b/src/lsmsvgmarkerelement.c
index f373d23..a918049 100644
--- a/src/lsmsvgmarkerelement.c
+++ b/src/lsmsvgmarkerelement.c
@@ -40,12 +40,94 @@ lsm_svg_marker_element_get_node_name (LsmDomNode *node)
/* LsmSvgGraphic implementation */
static void
-lsm_svg_marker_element_render (LsmSvgElement *self, LsmSvgView *view)
+_marker_element_render (LsmSvgElement *self, LsmSvgView *view)
{
+ LsmSvgMarkerElement *marker = LSM_SVG_MARKER_ELEMENT (self);
+ LsmSvgStyle *style;
+ LsmSvgMatrix matrix;
+ LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
+ LsmBox viewport;
+ double ref_x, ref_y;
+
+ if (!marker->enable_rendering) {
+ if (marker->style)
+ lsm_svg_style_free (marker->style);
+ /* FIXME Use reference counting for LsmSvgStyle */
+ marker->style = lsm_svg_style_duplicate (lsm_svg_view_get_current_style (view));
+
+ lsm_debug ("[LsmSvgMarkerElement::render] Direct rendering not allowed");
+ return;
+ } else {
+ marker->enable_rendering = FALSE;
+ }
+
+ style = lsm_svg_style_new_inherited (marker->style, &self->property_bag);
+ lsm_svg_view_push_style (view, style);
+
+ viewport.x = 0.0;
+ viewport.y = 0.0;
+
+ viewport.width = lsm_svg_view_normalize_length (view, &marker->width.length,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ viewport.height = lsm_svg_view_normalize_length (view, &marker->height.length,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+
+ ref_x = lsm_svg_view_normalize_length (view, &marker->ref_x.length,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ ref_y = lsm_svg_view_normalize_length (view, &marker->ref_y.length,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ lsm_svg_matrix_init_translate (&matrix, -ref_x, -ref_y);
+
+ if (marker->units.value == LSM_SVG_MARKER_UNITS_STROKE_WIDTH) {
+ lsm_svg_matrix_scale (&matrix, marker->stroke_width, marker->stroke_width);
+ }
+
+ lsm_svg_view_push_viewbox (view, &viewbox);
+ lsm_svg_view_push_matrix (view, &matrix);
+
+ lsm_debug ("[LsmSvgMarkerElement::render] stroke_width scale = %g",
+ marker->stroke_width);
+
+ lsm_svg_view_push_viewport (view, &viewport, &marker->viewbox.value,
+ &marker->preserve_aspect_ratio.value);
+
+ lsm_svg_matrix_init_rotate (&matrix, marker->vertex_angle);
+ lsm_svg_view_push_matrix (view, &matrix);
+
+ LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);
+
+ lsm_svg_view_pop_matrix (view);
+
+ lsm_svg_view_pop_viewport (view);
+
+ lsm_svg_view_pop_matrix (view);
+ lsm_svg_view_pop_viewbox (view);
+
+ lsm_svg_view_pop_style (view);
+ lsm_svg_style_free (style);
}
/* LsmSvgMarkerElement implementation */
+void
+lsm_svg_marker_element_render (LsmSvgMarkerElement *marker, LsmSvgView *view,
+ double stroke_width, double vertex_angle)
+{
+ g_return_if_fail (LSM_IS_SVG_MARKER_ELEMENT (marker));
+
+ marker->stroke_width = stroke_width;
+ marker->vertex_angle = vertex_angle;
+
+ lsm_svg_element_force_render (LSM_SVG_ELEMENT (marker), view);
+}
+
+static void
+lsm_svg_marker_element_enable_rendering (LsmSvgElement *element)
+{
+ LSM_SVG_MARKER_ELEMENT (element)->enable_rendering = TRUE;
+}
+
LsmDomNode *
lsm_svg_marker_element_new (void)
{
@@ -56,14 +138,33 @@ static const LsmSvgMarkerUnits units_default = LSM_SVG_MARKER_UNITS_STROKE_WID
static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_NUMBER};
static const LsmSvgLength width_default = { .value_unit = 3.0, .type = LSM_SVG_LENGTH_TYPE_NUMBER};
static const LsmSvgAngle orientation_default = { .angle = 0.0, .type = LSM_SVG_ANGLE_TYPE_FIXED};
+static const LsmBox viewbox_default = {0.0, 0.0, 0.0, 0.0};
+static const LsmSvgPreserveAspectRatio preserve_aspect_ratio_default = {
+ .defer = FALSE,
+ .align = LSM_SVG_ALIGN_X_MID_Y_MID,
+ .meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET
+};
static void
lsm_svg_marker_element_init (LsmSvgMarkerElement *self)
{
+ self->enable_rendering = FALSE;
self->ref_x.length = length_default;
self->ref_y.length = length_default;
self->width.length = width_default;
self->height.length = width_default;
+ self->preserve_aspect_ratio.value = preserve_aspect_ratio_default;
+}
+
+static void
+lsm_svg_marker_element_finalize (GObject *object)
+{
+ LsmSvgMarkerElement *marker = LSM_SVG_MARKER_ELEMENT (object);
+
+ if (marker->style)
+ lsm_svg_style_free (marker->style);
+
+ parent_class->finalize (object);
}
/* LsmSvgMarkerElement class */
@@ -88,13 +189,13 @@ static const LsmAttributeInfos lsm_svg_marker_element_attribute_infos[] = {
.trait_default = &length_default
},
{
- .name = "width",
+ .name = "markerWidth",
.attribute_offset = offsetof (LsmSvgMarkerElement, width),
.trait_class = &lsm_svg_length_trait_class,
.trait_default = &width_default
},
{
- .name = "height",
+ .name = "markerHeight",
.attribute_offset = offsetof (LsmSvgMarkerElement, height),
.trait_class = &lsm_svg_length_trait_class,
.trait_default = &width_default
@@ -104,20 +205,36 @@ static const LsmAttributeInfos lsm_svg_marker_element_attribute_infos[] = {
.attribute_offset = offsetof (LsmSvgMarkerElement, orientation),
.trait_class = &lsm_svg_angle_trait_class,
.trait_default = &orientation_default
+ },
+ {
+ .name = "viewBox",
+ .attribute_offset = offsetof (LsmSvgMarkerElement, viewbox),
+ .trait_class = &lsm_box_trait_class,
+ .trait_default = &viewbox_default
+ },
+ {
+ .name = "preserveAspectRatio",
+ .attribute_offset = offsetof (LsmSvgMarkerElement, preserve_aspect_ratio),
+ .trait_class = &lsm_svg_preserve_aspect_ratio_trait_class,
+ .trait_default = &preserve_aspect_ratio_default
}
};
static void
lsm_svg_marker_element_class_init (LsmSvgMarkerElementClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
+ object_class->finalize = lsm_svg_marker_element_finalize;
+
d_node_class->get_node_name = lsm_svg_marker_element_get_node_name;
- s_element_class->render = lsm_svg_marker_element_render;
+ s_element_class->render = _marker_element_render;
+ s_element_class->enable_rendering = lsm_svg_marker_element_enable_rendering;
s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
diff --git a/src/lsmsvgmarkerelement.h b/src/lsmsvgmarkerelement.h
index 7c444ee..3c911f1 100644
--- a/src/lsmsvgmarkerelement.h
+++ b/src/lsmsvgmarkerelement.h
@@ -45,6 +45,16 @@ struct _LsmSvgMarkerElement {
LsmSvgLengthAttribute width;
LsmSvgLengthAttribute height;
LsmSvgAngleAttribute orientation;
+
+ LsmSvgViewboxAttribute viewbox;
+ LsmSvgPreserveAspectRatioAttribute preserve_aspect_ratio;
+
+ gboolean enable_rendering;
+
+ double stroke_width;
+ double vertex_angle;
+
+ LsmSvgStyle *style;
};
struct _LsmSvgMarkerElementClass {
@@ -54,6 +64,8 @@ struct _LsmSvgMarkerElementClass {
GType lsm_svg_marker_element_get_type (void);
LsmDomNode * lsm_svg_marker_element_new (void);
+void lsm_svg_marker_element_render (LsmSvgMarkerElement *marker, LsmSvgView *view,
+ double stroke_width, double vertex_angle);
G_END_DECLS
diff --git a/src/lsmsvgpatternelement.c b/src/lsmsvgpatternelement.c
index 79dea55..471023b 100644
--- a/src/lsmsvgpatternelement.c
+++ b/src/lsmsvgpatternelement.c
@@ -54,7 +54,6 @@ lsm_svg_pattern_element_render (LsmSvgElement *self, LsmSvgView *view)
pattern->enable_rendering = FALSE;
}
-
style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
lsm_svg_view_push_style (view, style);
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index 438aa26..f28f45b 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -500,3 +500,14 @@ lsm_svg_style_new_inherited (const LsmSvgStyle *parent_style, LsmPropertyBag *pr
return style;
}
+LsmSvgStyle *
+lsm_svg_style_duplicate (const LsmSvgStyle *origin)
+{
+ LsmSvgStyle *style;
+
+ style = g_new (LsmSvgStyle, 1);
+
+ memcpy (style, origin, sizeof (LsmSvgStyle));
+
+ return style;
+}
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index cbb1cc7..a57ee60 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -152,6 +152,7 @@ LsmSvgStyle * lsm_svg_style_new (void);
void lsm_svg_style_free (LsmSvgStyle *style);
LsmSvgStyle * lsm_svg_style_new_inherited (const LsmSvgStyle *parent_style,
LsmPropertyBag *property_bag);
+LsmSvgStyle * lsm_svg_style_duplicate (const LsmSvgStyle *origin);
G_END_DECLS
diff --git a/src/lsmsvgtraits.c b/src/lsmsvgtraits.c
index db07b94..313f7d0 100644
--- a/src/lsmsvgtraits.c
+++ b/src/lsmsvgtraits.c
@@ -300,30 +300,29 @@ lsm_svg_paint_trait_from_string (LsmTrait *abstract_trait, char *string)
LsmSvgPaint *paint = (LsmSvgPaint *) abstract_trait;
LsmSvgPaintType paint_type;
- g_free (paint->uri);
+ g_free (paint->url);
if (strncmp (string, "url(#", 5) == 0) {
unsigned int length;
- string += 5;
- length = 0;
+ length = 5;
while (string[length] != ')')
length++;
length++;
- paint->uri = g_new (char, length);
- if (paint->uri != NULL) {
- memcpy (paint->uri, string, length - 1);
- paint->uri[length - 1] = '\0';
+ paint->url = g_new (char, length);
+ if (paint->url != NULL) {
+ memcpy (paint->url, string, length - 1);
+ paint->url[length - 1] = '\0';
}
string += length;
} else {
- paint->uri = NULL;
+ paint->url = NULL;
}
string = _parse_color (string, &paint->color, &paint_type);
- if (paint->uri != NULL)
+ if (paint->url != NULL)
switch (paint_type) {
case LSM_SVG_PAINT_TYPE_RGB_COLOR:
paint_type = LSM_SVG_PAINT_TYPE_URI_RGB_COLOR;
@@ -353,8 +352,9 @@ lsm_svg_paint_trait_to_string (LsmTrait *abstract_trait)
if (paint->color.red < 0.0 || paint->color.green < 0.0 || paint->color.blue < 0.0)
return g_strdup ("currentColor");
- if (paint->uri != NULL)
- g_strdup_printf ("url(#%s)", paint->uri);
+ /* FIXME */
+ if (paint->url != NULL)
+ return g_strdup (paint->url);
return g_strdup_printf ("rgb(%g%%,%g%%,%g%%)",
100.0 * paint->color.red,
diff --git a/src/lsmsvgtraits.h b/src/lsmsvgtraits.h
index 21ba491..e51d19a 100644
--- a/src/lsmsvgtraits.h
+++ b/src/lsmsvgtraits.h
@@ -50,7 +50,7 @@ void lsm_svg_dash_array_copy (LsmSvgDashArray *to, const LsmSvgDashArray *fro
typedef struct {
LsmSvgPaintType type;
- char *uri;
+ char *url;
LsmSvgColor color;
} LsmSvgPaint;
diff --git a/src/lsmsvguseelement.c b/src/lsmsvguseelement.c
index 5fcb2ee..d54bf33 100644
--- a/src/lsmsvguseelement.c
+++ b/src/lsmsvguseelement.c
@@ -67,7 +67,6 @@ lsm_svg_use_element_render (LsmSvgElement *self, LsmSvgView *view)
if (id == NULL)
return;
- /* TODO Ugly hack */
if (*id == '#')
id++;
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 58845fc..463c2bd 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -26,6 +26,7 @@
#include <lsmsvgsvgelement.h>
#include <lsmsvggradientelement.h>
#include <lsmsvgpatternelement.h>
+#include <lsmsvgmarkerelement.h>
#include <lsmsvgclippathelement.h>
#include <lsmsvgmaskelement.h>
#include <lsmstr.h>
@@ -686,14 +687,14 @@ typedef enum {
} LsmSvgViewPaintOperation;
static void
-_paint_uri (LsmSvgView *view, LsmSvgViewPaintOperation operation, const char *uri)
+_paint_url (LsmSvgView *view, LsmSvgViewPaintOperation operation, const char *url)
{
cairo_t *cairo;
- LsmDomElement *element;
+ LsmSvgElement *element;
LsmBox extents;
double x1, x2, y1, y2;
- element = lsm_dom_document_get_element_by_id (view->dom_view.document, uri);
+ element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document), url);
if (!LSM_IS_SVG_GRADIENT_ELEMENT (element) &&
!LSM_IS_SVG_PATTERN_ELEMENT (element))
return;
@@ -789,7 +790,7 @@ _set_color (LsmSvgView *view, LsmSvgViewPaintOperation operation,
case LSM_SVG_PAINT_TYPE_URI_RGB_COLOR:
case LSM_SVG_PAINT_TYPE_URI_CURRENT_COLOR:
case LSM_SVG_PAINT_TYPE_URI_NONE:
- _paint_uri (view, operation, paint->uri);
+ _paint_url (view, operation, paint->url);
break;
default:
return FALSE;
@@ -890,10 +891,80 @@ paint (LsmSvgView *view)
} else
cairo_set_dash (cairo, NULL, 0, 0.0);
- cairo_stroke (cairo);
+ cairo_stroke_preserve (cairo);
}
- cairo_new_path (cairo);
+ if ((style->marker->value != NULL && strcmp (style->marker->value, "none") != 0) ||
+ (style->marker_mid->value != NULL && strcmp (style->marker_mid->value, "none") != 0) ||
+ (style->marker_end->value != NULL && strcmp (style->marker_end->value, "none") != 0) ||
+ (style->marker_start->value != NULL && strcmp (style->marker_start->value, "none") != 0)) {
+ LsmSvgElement *marker;
+ LsmSvgElement *marker_start;
+ LsmSvgElement *marker_mid;
+ LsmSvgElement *marker_end;
+ cairo_path_t *path;
+ cairo_path_data_t *data;
+ double stroke_width;
+ int i;
+
+ marker = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
+ style->marker->value);
+ marker_start = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
+ style->marker_start->value);
+ marker_mid = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
+ style->marker_mid->value);
+ marker_end = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
+ style->marker_end->value);
+ stroke_width = lsm_svg_view_normalize_length (view, &view->style->stroke_width->length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+
+ if (marker_start == NULL)
+ marker_start = marker;
+ if (marker_mid == NULL)
+ marker_mid = marker;
+ if (marker_end == NULL)
+ marker_end = marker;
+
+ path = cairo_copy_path (cairo);
+ cairo_new_path (cairo);
+
+ for (i = 0; i < path->num_data; i += path->data[i].header.length) {
+ data = &path->data[i];
+#if 0
+ switch (data->header.type) {
+ case CAIRO_PATH_MOVE_TO:
+ break;
+ case CAIRO_PATH_LINE_TO:
+ break;
+ case CAIRO_PATH_CURVE_TO:
+ break;
+ case CAIRO_PATH_CLOSE_PATH:
+ break;
+ }
+#endif
+ if (i == 0)
+ marker = marker_start;
+ else if (i + path->data[i].header.length >= path->num_data)
+ marker = marker_end;
+ else
+ marker = marker_mid;
+
+ if (marker != NULL) {
+ double x, y;
+ cairo_save (cairo);
+
+ x = data[1].point.x;
+ y = data[1].point.y;
+ cairo_translate (cairo, x, y);
+ lsm_svg_marker_element_render (LSM_SVG_MARKER_ELEMENT (marker), view,
+ stroke_width, 0.0);
+ cairo_restore (cairo);
+ }
+ }
+
+ cairo_path_destroy (path);
+ } else
+ cairo_new_path (cairo);
if (use_group) {
cairo_pop_group_to_source (cairo);
@@ -1004,6 +1075,7 @@ lsm_svg_view_show_path (LsmSvgView *view,
_emit_svg_path (view->dom_view.cairo, d);
process_path (view);
+
}
void
@@ -1017,8 +1089,8 @@ lsm_svg_view_show_line (LsmSvgView *view, double x1, double y1, double x2, doubl
process_path (view);
}
-void
-lsm_svg_view_show_polyline (LsmSvgView *view, const char *points)
+static void
+_show_points (LsmSvgView *view, const char *points, gboolean close_path)
{
char *str;
double values[2];
@@ -1033,28 +1105,22 @@ lsm_svg_view_show_polyline (LsmSvgView *view, const char *points)
cairo_line_to (view->dom_view.cairo, values[0], values[1]);
}
+ if (close_path)
+ cairo_close_path (view->dom_view.cairo);
+
process_path (view);
}
void
-lsm_svg_view_show_polygon (LsmSvgView *view, const char *points)
+lsm_svg_view_show_polyline (LsmSvgView *view, const char *points)
{
- char *str;
- double values[2];
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
- str = (char *) points;
-
- if (lsm_str_parse_double_list (&str, 2, values)) {
- cairo_move_to (view->dom_view.cairo, values[0], values[1]);
- while (lsm_str_parse_double_list (&str, 2, values))
- cairo_line_to (view->dom_view.cairo, values[0], values[1]);
- }
-
- cairo_close_path (view->dom_view.cairo);
+ _show_points (view, points, FALSE);
+}
- process_path (view);
+void
+lsm_svg_view_show_polygon (LsmSvgView *view, const char *points)
+{
+ _show_points (view, points, TRUE);
}
void
@@ -1221,6 +1287,14 @@ lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport, const LsmB
cairo = view->dom_view.cairo;
cairo_save (cairo);
+ if (view->dom_view.debug) {
+ cairo_save (cairo);
+ cairo_set_line_width (cairo, 1.0);
+ cairo_set_source_rgb (cairo, 0.0, 0.0, 0.0);
+ cairo_rectangle (cairo, viewport->x, viewport->y, viewport->width, viewport->height);
+ cairo_stroke (cairo);
+ cairo_restore (cairo);
+ }
cairo_rectangle (cairo, viewport->x, viewport->y, viewport->width, viewport->height);
cairo_clip (cairo);
cairo_translate (cairo, x, y);
@@ -1306,18 +1380,18 @@ lsm_svg_view_pop_group_opacity (LsmSvgView *view)
static void
lsm_svg_view_push_clip (LsmSvgView *view)
{
- LsmDomElement *element;
+ LsmSvgElement *element;
LsmExtents extents;
- char *uri;
+ char *url;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
g_return_if_fail (!view->is_clipping);
lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
- uri = view->style->clip_path->value;
+ url = view->style->clip_path->value;
- lsm_debug ("[LsmSvgView::push_clip] Using '%s'", uri);
+ lsm_debug ("[LsmSvgView::push_clip] Using '%s'", url);
cairo_save (view->dom_view.cairo);
@@ -1326,23 +1400,12 @@ lsm_svg_view_push_clip (LsmSvgView *view)
view->clip_extents.width = extents.x2 - extents.x1;
view->clip_extents.height = extents.y2 - extents.y1;
- if (strncmp (uri, "url(#", 5) ==0) {
- char *end;
-
- uri = g_strdup (uri + 5);
- for (end = uri; *end != '\0' && *end != ')'; end++);
- *end = '\0';
-
- element = lsm_dom_document_get_element_by_id (view->dom_view.document, uri);
-
- g_free (uri);
-
- if (element != NULL && LSM_IS_SVG_CLIP_PATH_ELEMENT (element)) {
- view->is_clipping = TRUE;
- lsm_svg_element_force_render (LSM_SVG_ELEMENT (element), view);
- cairo_clip (view->dom_view.cairo);
- view->is_clipping = FALSE;
- }
+ element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document), url);
+ if (element != NULL && LSM_IS_SVG_CLIP_PATH_ELEMENT (element)) {
+ view->is_clipping = TRUE;
+ lsm_svg_element_force_render (LSM_SVG_ELEMENT (element), view);
+ cairo_clip (view->dom_view.cairo);
+ view->is_clipping = FALSE;
}
}
@@ -1365,76 +1428,66 @@ lsm_svg_view_push_mask (LsmSvgView *view)
static void
lsm_svg_view_pop_mask (LsmSvgView *view)
{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
- if (strncmp (view->style->mask->value, "url(#", 5) == 0) {
- LsmDomElement *mask_element;
- char *end;
- char *uri;
-
- uri = g_strdup (view->style->mask->value + 5);
- for (end = uri; *end != '\0' && *end != ')'; end++);
- *end = '\0';
-
- mask_element = lsm_dom_document_get_element_by_id (view->dom_view.document, uri);
+ LsmSvgElement *mask_element;
- if (LSM_IS_SVG_MASK_ELEMENT (mask_element)) {
- LsmExtents extents;
- LsmBox mask_extents;
- cairo_t *cairo;
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
- lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
+ mask_element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
+ view->style->mask->value);
- mask_extents.x = extents.x1;
- mask_extents.y = extents.y1;
- mask_extents.width = extents.x2 - extents.x1;
- mask_extents.height = extents.y2 - extents.y1;
+ if (LSM_IS_SVG_MASK_ELEMENT (mask_element)) {
+ LsmExtents extents;
+ LsmBox mask_extents;
+ cairo_t *cairo;
- cairo = view->dom_view.cairo;
+ lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
- _start_pattern (view, &mask_extents);
+ mask_extents.x = extents.x1;
+ mask_extents.y = extents.y1;
+ mask_extents.width = extents.x2 - extents.x1;
+ mask_extents.height = extents.y2 - extents.y1;
- lsm_svg_element_force_render (LSM_SVG_ELEMENT (mask_element), view);
+ cairo = view->dom_view.cairo;
- cairo_pop_group_to_source (cairo);
- if (view->pattern_data->pattern != NULL) {
- cairo_surface_t *surface;
- int width, height, row, i, stride;
- unsigned char *pixels;
+ _start_pattern (view, &mask_extents);
- cairo_pattern_get_surface (view->pattern_data->pattern, &surface);
- pixels = cairo_image_surface_get_data (surface);
- height = cairo_image_surface_get_height (surface);
- width = cairo_image_surface_get_width (surface);
- stride = cairo_image_surface_get_stride (surface);
+ lsm_svg_element_force_render (LSM_SVG_ELEMENT (mask_element), view);
- for (row = 0; row < height; row++) {
- guint8 *row_data = (pixels + (row * stride));
- for (i = 0; i < width; i++) {
- guint32 *pixel = (guint32 *) row_data + i;
- *pixel = ((((*pixel & 0x00ff0000) >> 16) * 13817 +
- ((*pixel & 0x0000ff00) >> 8) * 46518 +
- ((*pixel & 0x000000ff)) * 4688) * 0xff
- /* * opacity */);
- }
+ cairo_pop_group_to_source (cairo);
+ if (view->pattern_data->pattern != NULL) {
+ cairo_surface_t *surface;
+ int width, height, row, i, stride;
+ unsigned char *pixels;
+
+ cairo_pattern_get_surface (view->pattern_data->pattern, &surface);
+ pixels = cairo_image_surface_get_data (surface);
+ height = cairo_image_surface_get_height (surface);
+ width = cairo_image_surface_get_width (surface);
+ stride = cairo_image_surface_get_stride (surface);
+
+ for (row = 0; row < height; row++) {
+ guint8 *row_data = (pixels + (row * stride));
+ for (i = 0; i < width; i++) {
+ guint32 *pixel = (guint32 *) row_data + i;
+ *pixel = ((((*pixel & 0x00ff0000) >> 16) * 13817 +
+ ((*pixel & 0x0000ff00) >> 8) * 46518 +
+ ((*pixel & 0x000000ff)) * 4688) * 0xff
+ /* * opacity */);
}
+ }
- cairo_pattern_set_matrix (view->pattern_data->pattern,
- &view->pattern_data->matrix);
- cairo_pattern_set_extend (view->pattern_data->pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_matrix (view->pattern_data->pattern,
+ &view->pattern_data->matrix);
+ cairo_pattern_set_extend (view->pattern_data->pattern, CAIRO_EXTEND_NONE);
#if 0
- cairo_surface_write_to_png (surface, "mask.png");
+ cairo_surface_write_to_png (surface, "mask.png");
#endif
- cairo_mask (cairo, view->pattern_data->pattern);
- } else {
- cairo_paint (cairo);
- }
-
- _end_pattern (view);
+ cairo_mask (cairo, view->pattern_data->pattern);
} else {
- cairo_pop_group_to_source (view->dom_view.cairo);
- cairo_paint (view->dom_view.cairo);
+ cairo_paint (cairo);
}
+
+ _end_pattern (view);
} else {
cairo_pop_group_to_source (view->dom_view.cairo);
cairo_paint (view->dom_view.cairo);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]