[lasem] <svg:mask> Pass the two testsuite mask example.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [lasem] <svg:mask> Pass the two testsuite mask example.
- Date: Thu, 2 Jul 2009 15:45:05 +0000 (UTC)
commit f4b610548d5d7106443ac1d46ae2c41d2293fca1
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Thu Jul 2 17:44:18 2009 +0200
<svg:mask> Pass the two testsuite mask example.
src/lsmsvgattributebags.c | 4 +
src/lsmsvgattributebags.h | 3 +-
src/lsmsvgmaskelement.c | 83 ++++-
src/lsmsvgpatternelement.c | 15 +-
src/lsmsvgview.c | 883 ++++++++++++++++++++++++--------------------
src/lsmsvgview.h | 55 ++--
6 files changed, 611 insertions(+), 432 deletions(-)
---
diff --git a/src/lsmsvgattributebags.c b/src/lsmsvgattributebags.c
index dfadb82..923498f 100644
--- a/src/lsmsvgattributebags.c
+++ b/src/lsmsvgattributebags.c
@@ -57,6 +57,10 @@ lsm_dom_attribute_map_add_mask_attribute_bag (LsmDomAttributeMap *map, ptrdiff_t
offsetof (LsmSvgMaskAttributeBag, clip_rule),
NULL,
bag_offset, &lsm_svg_mask_attribute_bag_class);
+ lsm_dom_attribute_map_add_bag_attribute (map, "mask",
+ offsetof (LsmSvgMaskAttributeBag, mask),
+ NULL,
+ bag_offset, &lsm_svg_mask_attribute_bag_class);
}
static void *
diff --git a/src/lsmsvgattributebags.h b/src/lsmsvgattributebags.h
index e84f07b..73b7311 100644
--- a/src/lsmsvgattributebags.h
+++ b/src/lsmsvgattributebags.h
@@ -28,9 +28,10 @@
G_BEGIN_DECLS
typedef struct {
+ LsmSvgDoubleAttribute opacity;
LsmDomAttribute clip_path;
LsmDomEnumAttribute clip_rule;
- LsmSvgDoubleAttribute opacity;
+ LsmDomAttribute mask;
} LsmSvgMaskAttributeBag;
typedef struct {
diff --git a/src/lsmsvgmaskelement.c b/src/lsmsvgmaskelement.c
index d8a2a7a..c65541d 100644
--- a/src/lsmsvgmaskelement.c
+++ b/src/lsmsvgmaskelement.c
@@ -49,20 +49,20 @@ _mask_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
lsm_svg_pattern_units_attribute_parse (&mask->content_units, &units);
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
+ length.value_unit = -10.0;
+ length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
lsm_svg_animated_length_attribute_parse (&mask->x, &length);
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
+ length.value_unit = -10.0;
+ length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
lsm_svg_animated_length_attribute_parse (&mask->y, &length);
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
+ length.value_unit = 120.0;
+ length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
lsm_svg_animated_length_attribute_parse (&mask->width, &length);
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
+ length.value_unit = 120.0;
+ length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
lsm_svg_animated_length_attribute_parse (&mask->height, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
@@ -71,6 +71,73 @@ _mask_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
static void
_mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
{
+ LsmSvgMaskElement *mask = LSM_SVG_MASK_ELEMENT (self);
+ gboolean is_object_bounding_box;
+ LsmBox viewport;
+ const LsmBox *mask_extents;
+
+ mask_extents = lsm_svg_view_get_pattern_extents (view);
+
+ is_object_bounding_box = (mask->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+
+ if (is_object_bounding_box) {
+ LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
+
+ lsm_svg_view_push_viewbox (view, &viewbox);
+ }
+
+ viewport.x = lsm_svg_view_normalize_length (view, &mask->x.length.base,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ viewport.y = lsm_svg_view_normalize_length (view, &mask->y.length.base,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ viewport.width = lsm_svg_view_normalize_length (view, &mask->width.length.base,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ viewport.height = lsm_svg_view_normalize_length (view, &mask->height.length.base,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ if (is_object_bounding_box) {
+ lsm_svg_view_pop_viewbox (view);
+
+ viewport.x = viewport.x * mask_extents->width + mask_extents->x;
+ viewport.y = viewport.y * mask_extents->height + mask_extents->y;
+ viewport.width *= mask_extents->width;
+ viewport.height *= mask_extents->height;
+ }
+
+ if (viewport.width <= 0.0 || viewport.height <= 0.0)
+ return;
+
+ lsm_debug ("[LsmSvgMaskElement::render_paint] Create mask x = %g, y = %g, w = %g, h = %g",
+ viewport.x, viewport.y, viewport.width, viewport.height);
+
+ lsm_svg_view_create_surface_pattern (view, &viewport,
+ mask->units.value,
+ mask->content_units.value, NULL,
+ LSM_SVG_VIEW_SURFACE_TYPE_IMAGE);
+
+ is_object_bounding_box = (mask->content_units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+
+ if (is_object_bounding_box) {
+ LsmSvgMatrix matrix;
+ LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
+
+ lsm_svg_matrix_init_translate (&matrix, +mask_extents->x, +mask_extents->y);
+ lsm_svg_matrix_scale (&matrix, mask_extents->width, mask_extents->height);
+ lsm_svg_view_push_viewbox (view, &viewbox);
+ lsm_svg_view_push_matrix (view, &matrix);
+
+ lsm_debug ("[LsmSvgMaskElement::render_paint] object_bounding_box"
+ " x_scale = %g, y_scale = %g, x_offset = %g, y_offset = %g",
+ mask_extents->width, mask_extents->height,
+ mask_extents->x, mask_extents->y);
+ }
+
+ LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);
+
+ if (is_object_bounding_box) {
+ lsm_svg_view_pop_matrix (view);
+ lsm_svg_view_pop_viewbox (view);
+ }
}
/* LsmSvgMaskElement implementation */
diff --git a/src/lsmsvgpatternelement.c b/src/lsmsvgpatternelement.c
index f88d104..551da38 100644
--- a/src/lsmsvgpatternelement.c
+++ b/src/lsmsvgpatternelement.c
@@ -101,9 +101,15 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
viewport.height = lsm_svg_view_normalize_length (view, &pattern->height.length.base,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- if (is_object_bounding_box)
+ if (is_object_bounding_box) {
lsm_svg_view_pop_viewbox (view);
+ viewport.x *= pattern_extents->width;
+ viewport.y *= pattern_extents->height;
+ viewport.width *= pattern_extents->width;
+ viewport.height *= pattern_extents->height;
+ }
+
if (viewport.width <= 0.0 || viewport.height <= 0.0)
return;
@@ -113,7 +119,8 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_create_surface_pattern (view, &viewport,
pattern->units.value,
pattern->content_units.value,
- &pattern->transform.matrix);
+ &pattern->transform.matrix,
+ LSM_SVG_VIEW_SURFACE_TYPE_AUTO);
is_object_bounding_box = (pattern->content_units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
@@ -127,7 +134,9 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_push_matrix (view, &matrix);
lsm_debug ("[LsmSvgPatternElement::render_paint] object_bounding_box"
- " x_scale = %g, y_scale = %g",pattern_extents->width, pattern_extents->height);
+ " x_scale = %g, y_scale = %g, x_offset = %g, y_offset = %g",
+ pattern_extents->width, pattern_extents->height,
+ pattern_extents->x, pattern_extents->y);
}
is_viewbox_defined = lsm_dom_attribute_is_defined ((LsmDomAttribute *) &pattern->viewbox);
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 52bd449..648d1ff 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -27,6 +27,7 @@
#include <lsmsvggradientelement.h>
#include <lsmsvgpatternelement.h>
#include <lsmsvgclippathelement.h>
+#include <lsmsvgmaskelement.h>
#include <lsmsvgutils.h>
#include <gdk/gdk.h>
#include <glib/gprintf.h>
@@ -69,383 +70,9 @@ lsm_svg_view_normalize_length (LsmSvgView *view, const LsmSvgLength *length, Lsm
return lsm_svg_length_normalize (length, view->viewbox_stack->data, font_size, direction);
}
-void
-lsm_svg_view_push_viewbox (LsmSvgView *view, const LsmBox *viewbox)
-{
- LsmSvgViewbox *svg_viewbox;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
- lsm_debug ("[LsmSvgView::push_viewbox] viewbox = %g, %g, %g, %g",
- viewbox->x, viewbox->y, viewbox->width, viewbox->height);
-
- svg_viewbox = lsm_svg_viewbox_new (view->resolution_ppi, viewbox);
-
- view->viewbox_stack = g_slist_prepend (view->viewbox_stack, svg_viewbox);
-}
-
-void
-lsm_svg_view_pop_viewbox (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->viewbox_stack != NULL);
-
- lsm_debug ("[LsmSvgView::pop_viewbox]");
-
- lsm_svg_viewbox_free (view->viewbox_stack->data);
- view->viewbox_stack = g_slist_delete_link (view->viewbox_stack, view->viewbox_stack);
-}
-
-void
-lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport, const LsmBox *viewbox,
- const LsmSvgPreserveAspectRatio *aspect_ratio)
-{
- cairo_t *cairo;
- double x_ratio, x_scale;
- double y_ratio, y_scale;
- double x, y;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (viewport != NULL);
- g_return_if_fail (aspect_ratio != NULL);
-
- x = viewport->x;
- y = viewport->y;
-
- if (viewbox != NULL) {
- x_ratio = viewbox->width > 0.0 ? viewport->width / viewbox->width : 0.0;
- y_ratio = viewbox->height > 0.0 ? viewport->height / viewbox->height : 0.0;
-
- if (aspect_ratio->align > LSM_SVG_ALIGN_NONE) {
- if (aspect_ratio->meet_or_slice == LSM_SVG_MEET_OR_SLICE_MEET) {
- x_scale = MIN (x_ratio, y_ratio);
- y_scale = x_scale;
- } else {
- x_scale = MAX (x_ratio, y_ratio);
- y_scale = x_scale;
- }
-
- x -= viewbox->x;
- y -= viewbox->y;
-
- switch (aspect_ratio->align) {
- case LSM_SVG_ALIGN_X_MIN_Y_MIN:
- break;
- case LSM_SVG_ALIGN_X_MIN_Y_MID:
- y += (viewport->height- viewbox->height * y_scale) * 0.5;
- break;
- case LSM_SVG_ALIGN_X_MIN_Y_MAX:
- y += (viewport->height - viewbox->height * y_scale);
- break;
- case LSM_SVG_ALIGN_X_MID_Y_MIN:
- x += (viewport->width - viewbox->width * x_scale) * 0.5;
- break;
- case LSM_SVG_ALIGN_X_MID_Y_MID:
- x += (viewport->width - viewbox->width * x_scale) * 0.5;
- y += (viewport->height- viewbox->height * y_scale) * 0.5;
- break;
- case LSM_SVG_ALIGN_X_MID_Y_MAX:
- x += (viewport->width - viewbox->width * x_scale) * 0.5;
- y += (viewport->height - viewbox->height * y_scale);
- break;
- case LSM_SVG_ALIGN_X_MAX_Y_MIN:
- x += (viewport->width - viewbox->width * x_scale);
- break;
- case LSM_SVG_ALIGN_X_MAX_Y_MID:
- x += (viewport->width - viewbox->width * x_scale);
- y += (viewport->height- viewbox->height * y_scale) * 0.5;
- break;
- case LSM_SVG_ALIGN_X_MAX_Y_MAX:
- x += (viewport->width - viewbox->width * x_scale);
- y += (viewport->height - viewbox->height * y_scale);
- break;
- default:
- break;
- }
- } else {
- x_scale = x_ratio;
- y_scale = y_ratio;
- }
-
- lsm_debug ("[LsmSvgView::push_viewport] scale = %g, %g", x_scale, y_scale);
-
- lsm_svg_view_push_viewbox (view, viewbox);
-
- } else {
- x_scale = y_scale = 1.0;
- lsm_svg_view_push_viewbox (view, viewport);
- }
-
- cairo = view->dom_view.cairo;
-
- cairo_save (cairo);
- cairo_rectangle (cairo, viewport->x, viewport->y, viewport->width, viewport->height);
- cairo_clip (cairo);
- cairo_translate (cairo, x, y);
- cairo_scale (cairo, x_scale, y_scale);
-}
-
-void
-lsm_svg_view_pop_viewport (LsmSvgView *view)
-{
- cairo_restore (view->dom_view.cairo);
-
- lsm_svg_view_pop_viewbox (view);
-}
-
-void
-lsm_svg_view_push_matrix (LsmSvgView *view, LsmSvgMatrix *matrix)
-{
- cairo_matrix_t cr_matrix;
- cairo_matrix_t *ctm;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
- ctm = g_new (cairo_matrix_t, 1);
- cairo_get_matrix (view->dom_view.cairo, ctm);
-
- view->matrix_stack = g_slist_prepend (view->matrix_stack, ctm);
-
- lsm_debug ("[LsmSvgView::push_matrix] New transform %g, %g, %g, %g, %g, %g",
- matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
-
- cairo_matrix_init (&cr_matrix, matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
- cairo_transform (view->dom_view.cairo, &cr_matrix);
-
- {
- cairo_matrix_t current_ctm;
- cairo_get_matrix (view->dom_view.cairo, ¤t_ctm);
-
- lsm_debug ("[LsmSvgView::push_matrix] Current ctm %g, %g, %g, %g, %g, %g",
- current_ctm.xx, current_ctm.xy, current_ctm.yx, current_ctm.yy,
- current_ctm.x0, current_ctm.y0);
- }
-}
-
-void
-lsm_svg_view_pop_matrix (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
- if (view->matrix_stack != NULL) {
- cairo_matrix_t *ctm;
-
- ctm = view->matrix_stack->data;
-
- cairo_set_matrix (view->dom_view.cairo, ctm);
-
- g_free (ctm);
- view->matrix_stack = g_slist_delete_link (view->matrix_stack, view->matrix_stack);
- }
-}
-
-void
-lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
-
- view->element_stack = g_slist_prepend (view->element_stack, (void *) element);
-}
-
-void
-lsm_svg_view_pop_element (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->element_stack != NULL);
-
- view->element_stack = g_slist_delete_link (view->element_stack, view->element_stack);
-}
-
static void
-lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_rule)
+_start_pattern (LsmSvgView *view, const LsmBox *extents)
{
- LsmDomElement *element;
- LsmExtents extents;
- char *uri;
-
- 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 = clip_path;
-
- lsm_debug ("[LsmSvgView::push_clip] Using '%s'", clip_path);
-
- cairo_save (view->dom_view.cairo);
-
- view->clip_extents.x = extents.x1;
- view->clip_extents.y = extents.y1;
- 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_render_clip (LSM_SVG_ELEMENT (element), view);
- cairo_clip (view->dom_view.cairo);
- view->is_clipping = FALSE;
- }
- }
-}
-
-static void
-lsm_svg_view_pop_clip (LsmSvgView *view)
-{
- lsm_debug ("[LsmSvgView::pop_clip");
-
- cairo_restore (view->dom_view.cairo);
-}
-
-void
-lsm_svg_view_push_group_opacity (LsmSvgView *view)
-{
- LsmSvgMaskAttributeBag *mask;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->mask_stack != NULL);
-
- mask = view->mask_stack->data;
-
- if (mask->opacity.value < 1.0)
- cairo_push_group (view->dom_view.cairo);
-}
-
-void
-lsm_svg_view_pop_group_opacity (LsmSvgView *view)
-{
- LsmSvgMaskAttributeBag *mask;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->mask_stack != NULL);
-
- mask = view->mask_stack->data;
-
- if (mask->opacity.value < 1.0) {
- cairo_pop_group_to_source (view->dom_view.cairo);
- cairo_paint_with_alpha (view->dom_view.cairo, mask->opacity.value);
- }
-}
-
-void
-lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (mask != NULL);
-
- view->mask_stack = g_slist_prepend (view->mask_stack, (void *) mask);
-
- if (mask->clip_path.value != NULL)
- lsm_svg_view_push_clip (view, mask->clip_path.value, mask->clip_rule.value);
-}
-
-void
-lsm_svg_view_pop_mask_attributes (LsmSvgView *view)
-{
- LsmSvgMaskAttributeBag *mask;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->mask_stack != NULL);
-
- mask = view->mask_stack->data;
-
- if (mask->clip_path.value != NULL)
- lsm_svg_view_pop_clip (view);
-
- view->mask_stack = g_slist_delete_link (view->mask_stack, view->mask_stack);
-}
-
-void
-lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (fill != NULL);
-
- view->fill_stack = g_slist_prepend (view->fill_stack, (void *) fill);
-}
-
-void
-lsm_svg_view_pop_fill_attributes (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->fill_stack != NULL);
-
- view->fill_stack = g_slist_delete_link (view->fill_stack, view->fill_stack);
-}
-
-void
-lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (stroke != NULL);
-
- view->stroke_stack = g_slist_prepend (view->stroke_stack, (void *) stroke);
-}
-
-void
-lsm_svg_view_pop_stroke_attributes (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->stroke_stack != NULL);
-
- view->stroke_stack = g_slist_delete_link (view->stroke_stack, view->stroke_stack);
-}
-
-void
-lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (text != NULL);
-
- view->text_stack = g_slist_prepend (view->text_stack, (void *) text);
-}
-
-void
-lsm_svg_view_pop_text_attributes (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->text_stack != NULL);
-
- view->text_stack = g_slist_delete_link (view->text_stack, view->text_stack);
-}
-
-const LsmBox *
-lsm_svg_view_get_pattern_extents (LsmSvgView *view)
-{
- static LsmBox null_extents = {.x = 0.0, .y = 0.0, .width = 0.0, .height = 0.0};
-
- g_return_val_if_fail (LSM_IS_SVG_VIEW (view), &null_extents);
- g_return_val_if_fail (view->pattern_data != NULL, &null_extents);
-
- return &view->pattern_data->extents;
-}
-
-const LsmBox *
-lsm_svg_view_get_clip_extents (LsmSvgView *view)
-{
- static LsmBox null_extents = {.x = 0.0, .y = 0.0, .width = 0.0, .height = 0.0};
-
- g_return_val_if_fail (LSM_IS_SVG_VIEW (view), &null_extents);
- g_return_val_if_fail (view->is_clipping, &null_extents);
-
- return &view->clip_extents;
-}
-
-static void
-_start_pattern (LsmSvgView *view)
-{
- double x1, x2, y1, y2;
lsm_debug ("[LsmSvgView::start_pattern]");
view->pattern_stack = g_slist_prepend (view->pattern_stack, view->pattern_data);
@@ -456,16 +83,10 @@ _start_pattern (LsmSvgView *view)
view->pattern_data->content_units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
view->pattern_data->units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
view->pattern_data->spread_method = LSM_SVG_SPREAD_METHOD_REPEAT;
-
- cairo_path_extents (view->dom_view.cairo, &x1, &y1, &x2, &y2);
+ view->pattern_data->extents = *extents;
view->dom_view.cairo = NULL;
- view->pattern_data->extents.x = x1;
- view->pattern_data->extents.y = y1;
- view->pattern_data->extents.width = x2 - x1;
- view->pattern_data->extents.height = y2 - y1;
-
cairo_matrix_init_identity (&view->pattern_data->matrix);
}
@@ -561,7 +182,8 @@ lsm_svg_view_create_surface_pattern (LsmSvgView *view,
const LsmBox *viewport,
LsmSvgPatternUnits units,
LsmSvgPatternUnits content_units,
- const LsmSvgMatrix *matrix)
+ const LsmSvgMatrix *matrix,
+ LsmSvgViewSurfaceType surface_type)
{
cairo_surface_t *surface;
cairo_pattern_t *pattern;
@@ -577,22 +199,31 @@ lsm_svg_view_create_surface_pattern (LsmSvgView *view,
width = viewport->width;
height = viewport->height;
- if (units == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX) {
- x *= view->pattern_data->extents.width;
- y *= view->pattern_data->extents.height;
- width *= view->pattern_data->extents.width;
- height *= view->pattern_data->extents.height;
- }
+/* if (units == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX) {*/
+/* x *= view->pattern_data->extents.width;*/
+/* y *= view->pattern_data->extents.height;*/
+/* width *= view->pattern_data->extents.width;*/
+/* height *= view->pattern_data->extents.height;*/
+/* }*/
- lsm_debug ("[LsmSvgView::create_pattern] pattern size = %g ,%g",
- width, height);
+ lsm_debug ("[LsmSvgView::create_pattern] pattern size = %g ,%g at %g, %g",
+ width, height, x, y);
if (height < 1 || width < 1)
return;
- surface = cairo_surface_create_similar (cairo_get_target (view->pattern_data->old_cairo),
- CAIRO_CONTENT_COLOR_ALPHA,
- width, height);
+ switch (surface_type) {
+ case LSM_SVG_VIEW_SURFACE_TYPE_AUTO:
+ surface = cairo_surface_create_similar (cairo_get_target (view->pattern_data->old_cairo),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+ break;
+ default:
+ case LSM_SVG_VIEW_SURFACE_TYPE_IMAGE:
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ break;
+ }
+
pattern = cairo_pattern_create_for_surface (surface);
view->dom_view.cairo = cairo_create (surface);
cairo_surface_destroy (surface);
@@ -633,7 +264,7 @@ typedef struct {
* _emit_smooth_curve
* _emit_smooth_quadratic_curve
*
- * is adpated from the goocanvas library (goocanvasutils.c)
+ * is adapted from the goocanvas library (goocanvasutils.c)
*
* GooCanvas. Copyright (C) 2005 Damon Chaplin.
*/
@@ -1046,13 +677,22 @@ _paint_uri (LsmSvgView *view, LsmSvgViewPaintOperation operation, const char *ur
{
cairo_t *cairo;
LsmDomElement *element;
+ LsmBox extents;
+ double x1, x2, y1, y2;
element = lsm_dom_document_get_element_by_id (view->dom_view.document, uri);
if (!LSM_IS_SVG_GRADIENT_ELEMENT (element) &&
!LSM_IS_SVG_PATTERN_ELEMENT (element))
return;
- _start_pattern (view);
+ cairo_path_extents (view->dom_view.cairo, &x1, &y1, &x2, &y2);
+
+ extents.x = x1;
+ extents.y = y1;
+ extents.width = x2 - x1;
+ extents.height = y2 - y1;
+
+ _start_pattern (view, &extents);
lsm_svg_element_render_paint (LSM_SVG_ELEMENT (element), view);
@@ -1462,6 +1102,457 @@ lsm_svg_view_show_pixbuf (LsmSvgView *view, GdkPixbuf *pixbuf)
cairo_paint (view->dom_view.cairo);
}
+void
+lsm_svg_view_push_viewbox (LsmSvgView *view, const LsmBox *viewbox)
+{
+ LsmSvgViewbox *svg_viewbox;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+ lsm_debug ("[LsmSvgView::push_viewbox] viewbox = %g, %g, %g, %g",
+ viewbox->x, viewbox->y, viewbox->width, viewbox->height);
+
+ svg_viewbox = lsm_svg_viewbox_new (view->resolution_ppi, viewbox);
+
+ view->viewbox_stack = g_slist_prepend (view->viewbox_stack, svg_viewbox);
+}
+
+void
+lsm_svg_view_pop_viewbox (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->viewbox_stack != NULL);
+
+ lsm_debug ("[LsmSvgView::pop_viewbox]");
+
+ lsm_svg_viewbox_free (view->viewbox_stack->data);
+ view->viewbox_stack = g_slist_delete_link (view->viewbox_stack, view->viewbox_stack);
+}
+
+void
+lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport, const LsmBox *viewbox,
+ const LsmSvgPreserveAspectRatio *aspect_ratio)
+{
+ cairo_t *cairo;
+ double x_ratio, x_scale;
+ double y_ratio, y_scale;
+ double x, y;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (viewport != NULL);
+ g_return_if_fail (aspect_ratio != NULL);
+
+ x = viewport->x;
+ y = viewport->y;
+
+ if (viewbox != NULL) {
+ x_ratio = viewbox->width > 0.0 ? viewport->width / viewbox->width : 0.0;
+ y_ratio = viewbox->height > 0.0 ? viewport->height / viewbox->height : 0.0;
+
+ if (aspect_ratio->align > LSM_SVG_ALIGN_NONE) {
+ if (aspect_ratio->meet_or_slice == LSM_SVG_MEET_OR_SLICE_MEET) {
+ x_scale = MIN (x_ratio, y_ratio);
+ y_scale = x_scale;
+ } else {
+ x_scale = MAX (x_ratio, y_ratio);
+ y_scale = x_scale;
+ }
+
+ x -= viewbox->x;
+ y -= viewbox->y;
+
+ switch (aspect_ratio->align) {
+ case LSM_SVG_ALIGN_X_MIN_Y_MIN:
+ break;
+ case LSM_SVG_ALIGN_X_MIN_Y_MID:
+ y += (viewport->height- viewbox->height * y_scale) * 0.5;
+ break;
+ case LSM_SVG_ALIGN_X_MIN_Y_MAX:
+ y += (viewport->height - viewbox->height * y_scale);
+ break;
+ case LSM_SVG_ALIGN_X_MID_Y_MIN:
+ x += (viewport->width - viewbox->width * x_scale) * 0.5;
+ break;
+ case LSM_SVG_ALIGN_X_MID_Y_MID:
+ x += (viewport->width - viewbox->width * x_scale) * 0.5;
+ y += (viewport->height- viewbox->height * y_scale) * 0.5;
+ break;
+ case LSM_SVG_ALIGN_X_MID_Y_MAX:
+ x += (viewport->width - viewbox->width * x_scale) * 0.5;
+ y += (viewport->height - viewbox->height * y_scale);
+ break;
+ case LSM_SVG_ALIGN_X_MAX_Y_MIN:
+ x += (viewport->width - viewbox->width * x_scale);
+ break;
+ case LSM_SVG_ALIGN_X_MAX_Y_MID:
+ x += (viewport->width - viewbox->width * x_scale);
+ y += (viewport->height- viewbox->height * y_scale) * 0.5;
+ break;
+ case LSM_SVG_ALIGN_X_MAX_Y_MAX:
+ x += (viewport->width - viewbox->width * x_scale);
+ y += (viewport->height - viewbox->height * y_scale);
+ break;
+ default:
+ break;
+ }
+ } else {
+ x_scale = x_ratio;
+ y_scale = y_ratio;
+ }
+
+ lsm_debug ("[LsmSvgView::push_viewport] scale = %g, %g", x_scale, y_scale);
+
+ lsm_svg_view_push_viewbox (view, viewbox);
+
+ } else {
+ x_scale = y_scale = 1.0;
+ lsm_svg_view_push_viewbox (view, viewport);
+ }
+
+ cairo = view->dom_view.cairo;
+
+ cairo_save (cairo);
+ cairo_rectangle (cairo, viewport->x, viewport->y, viewport->width, viewport->height);
+ cairo_clip (cairo);
+ cairo_translate (cairo, x, y);
+ cairo_scale (cairo, x_scale, y_scale);
+}
+
+void
+lsm_svg_view_pop_viewport (LsmSvgView *view)
+{
+ cairo_restore (view->dom_view.cairo);
+
+ lsm_svg_view_pop_viewbox (view);
+}
+
+void
+lsm_svg_view_push_matrix (LsmSvgView *view, LsmSvgMatrix *matrix)
+{
+ cairo_matrix_t cr_matrix;
+ cairo_matrix_t *ctm;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+ ctm = g_new (cairo_matrix_t, 1);
+ cairo_get_matrix (view->dom_view.cairo, ctm);
+
+ view->matrix_stack = g_slist_prepend (view->matrix_stack, ctm);
+
+ lsm_debug ("[LsmSvgView::push_matrix] New transform %g, %g, %g, %g, %g, %g",
+ matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
+
+ cairo_matrix_init (&cr_matrix, matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
+ cairo_transform (view->dom_view.cairo, &cr_matrix);
+
+ {
+ cairo_matrix_t current_ctm;
+ cairo_get_matrix (view->dom_view.cairo, ¤t_ctm);
+
+ lsm_debug ("[LsmSvgView::push_matrix] Current ctm %g, %g, %g, %g, %g, %g",
+ current_ctm.xx, current_ctm.xy, current_ctm.yx, current_ctm.yy,
+ current_ctm.x0, current_ctm.y0);
+ }
+}
+
+void
+lsm_svg_view_pop_matrix (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+ if (view->matrix_stack != NULL) {
+ cairo_matrix_t *ctm;
+
+ ctm = view->matrix_stack->data;
+
+ cairo_set_matrix (view->dom_view.cairo, ctm);
+
+ g_free (ctm);
+ view->matrix_stack = g_slist_delete_link (view->matrix_stack, view->matrix_stack);
+ }
+}
+
+void
+lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
+
+ view->element_stack = g_slist_prepend (view->element_stack, (void *) element);
+}
+
+void
+lsm_svg_view_pop_element (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->element_stack != NULL);
+
+ view->element_stack = g_slist_delete_link (view->element_stack, view->element_stack);
+}
+
+static void
+lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_rule)
+{
+ LsmDomElement *element;
+ LsmExtents extents;
+ char *uri;
+
+ 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 = clip_path;
+
+ lsm_debug ("[LsmSvgView::push_clip] Using '%s'", clip_path);
+
+ cairo_save (view->dom_view.cairo);
+
+ view->clip_extents.x = extents.x1;
+ view->clip_extents.y = extents.y1;
+ 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_render_clip (LSM_SVG_ELEMENT (element), view);
+ cairo_clip (view->dom_view.cairo);
+ view->is_clipping = FALSE;
+ }
+ }
+}
+
+static void
+lsm_svg_view_pop_clip (LsmSvgView *view)
+{
+ lsm_debug ("[LsmSvgView::pop_clip");
+
+ cairo_restore (view->dom_view.cairo);
+}
+
+void
+lsm_svg_view_push_group_opacity (LsmSvgView *view)
+{
+ LsmSvgMaskAttributeBag *mask;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->mask_stack != NULL);
+
+ mask = view->mask_stack->data;
+
+ if (mask->opacity.value < 1.0)
+ cairo_push_group (view->dom_view.cairo);
+}
+
+void
+lsm_svg_view_pop_group_opacity (LsmSvgView *view)
+{
+ LsmSvgMaskAttributeBag *mask;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->mask_stack != NULL);
+
+ mask = view->mask_stack->data;
+
+ if (mask->opacity.value < 1.0) {
+ cairo_pop_group_to_source (view->dom_view.cairo);
+ cairo_paint_with_alpha (view->dom_view.cairo, mask->opacity.value);
+ }
+}
+
+void
+lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (mask != NULL);
+
+ view->mask_stack = g_slist_prepend (view->mask_stack, (void *) mask);
+
+ if (mask->clip_path.value != NULL)
+ lsm_svg_view_push_clip (view, mask->clip_path.value, mask->clip_rule.value);
+
+ if (mask->mask.value != NULL)
+ cairo_push_group (view->dom_view.cairo);
+}
+
+void
+lsm_svg_view_pop_mask_attributes (LsmSvgView *view)
+{
+ LsmSvgMaskAttributeBag *mask;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->mask_stack != NULL);
+
+ mask = view->mask_stack->data;
+
+ if (mask->clip_path.value != NULL)
+ lsm_svg_view_pop_clip (view);
+
+ if (mask->mask.value != NULL) {
+ if (strncmp (mask->mask.value, "url(#", 5) == 0) {
+ LsmDomElement *mask_element;
+ char *end;
+ char *uri;
+
+ uri = g_strdup (mask->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);
+
+ if (LSM_IS_SVG_MASK_ELEMENT (mask_element)) {
+ LsmExtents extents;
+ LsmBox mask_extents;
+ cairo_t *cairo;
+
+ lsm_svg_element_get_extents (view->element_stack->data, view, &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;
+
+ cairo = view->dom_view.cairo;
+
+ _start_pattern (view, &mask_extents);
+
+ lsm_svg_element_render_paint (LSM_SVG_ELEMENT (mask_element), view);
+
+ 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);
+#if 0
+ cairo_surface_write_to_png (surface, "mask.png");
+#endif
+ cairo_mask (cairo, view->pattern_data->pattern);
+ } else {
+ cairo_paint (cairo);
+ }
+
+ _end_pattern (view);
+ } else {
+ cairo_pop_group_to_source (view->dom_view.cairo);
+ cairo_paint (view->dom_view.cairo);
+ }
+ } else {
+ cairo_pop_group_to_source (view->dom_view.cairo);
+ cairo_paint (view->dom_view.cairo);
+ }
+ }
+
+ view->mask_stack = g_slist_delete_link (view->mask_stack, view->mask_stack);
+}
+
+void
+lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (fill != NULL);
+
+ view->fill_stack = g_slist_prepend (view->fill_stack, (void *) fill);
+}
+
+void
+lsm_svg_view_pop_fill_attributes (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->fill_stack != NULL);
+
+ view->fill_stack = g_slist_delete_link (view->fill_stack, view->fill_stack);
+}
+
+void
+lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (stroke != NULL);
+
+ view->stroke_stack = g_slist_prepend (view->stroke_stack, (void *) stroke);
+}
+
+void
+lsm_svg_view_pop_stroke_attributes (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->stroke_stack != NULL);
+
+ view->stroke_stack = g_slist_delete_link (view->stroke_stack, view->stroke_stack);
+}
+
+void
+lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (text != NULL);
+
+ view->text_stack = g_slist_prepend (view->text_stack, (void *) text);
+}
+
+void
+lsm_svg_view_pop_text_attributes (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (view->text_stack != NULL);
+
+ view->text_stack = g_slist_delete_link (view->text_stack, view->text_stack);
+}
+
+const LsmBox *
+lsm_svg_view_get_pattern_extents (LsmSvgView *view)
+{
+ static LsmBox null_extents = {.x = 0.0, .y = 0.0, .width = 0.0, .height = 0.0};
+
+ g_return_val_if_fail (LSM_IS_SVG_VIEW (view), &null_extents);
+ g_return_val_if_fail (view->pattern_data != NULL, &null_extents);
+
+ return &view->pattern_data->extents;
+}
+
+const LsmBox *
+lsm_svg_view_get_clip_extents (LsmSvgView *view)
+{
+ static LsmBox null_extents = {.x = 0.0, .y = 0.0, .width = 0.0, .height = 0.0};
+
+ g_return_val_if_fail (LSM_IS_SVG_VIEW (view), &null_extents);
+ g_return_val_if_fail (view->is_clipping, &null_extents);
+
+ return &view->clip_extents;
+}
+
static void
lsm_svg_view_measure (LsmDomView *view, double *width, double *height)
{
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index 54fbb90..d295ffe 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -29,6 +29,11 @@
G_BEGIN_DECLS
+typedef enum {
+ LSM_SVG_VIEW_SURFACE_TYPE_AUTO,
+ LSM_SVG_VIEW_SURFACE_TYPE_IMAGE
+} LsmSvgViewSurfaceType;
+
#define LSM_TYPE_SVG_VIEW (lsm_svg_view_get_type ())
#define LSM_SVG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_VIEW, LsmSvgView))
#define LSM_SVG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_VIEW, LsmSvgViewClass))
@@ -72,29 +77,6 @@ LsmSvgView * lsm_svg_view_new (LsmSvgDocument *document);
double lsm_svg_view_normalize_length (LsmSvgView *view, const LsmSvgLength *length,
LsmSvgLengthDirection direction);
-void lsm_svg_view_push_viewbox (LsmSvgView *view, const LsmBox *viewbox);
-void lsm_svg_view_pop_viewbox (LsmSvgView *view);
-void lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport,
- const LsmBox *viewbox,
- const LsmSvgPreserveAspectRatio *aspect_ratio);
-void lsm_svg_view_pop_viewport (LsmSvgView *view);
-void lsm_svg_view_push_matrix (LsmSvgView *view, LsmSvgMatrix *matrix);
-void lsm_svg_view_pop_matrix (LsmSvgView *view);
-
-void lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element);
-void lsm_svg_view_pop_element (LsmSvgView *view);
-
-void lsm_svg_view_push_group_opacity (LsmSvgView *view);
-void lsm_svg_view_pop_group_opacity (LsmSvgView *view);
-
-void lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask);
-void lsm_svg_view_pop_mask_attributes (LsmSvgView *view);
-void lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill);
-void lsm_svg_view_pop_fill_attributes (LsmSvgView *view);
-void lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke);
-void lsm_svg_view_pop_stroke_attributes (LsmSvgView *view);
-void lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text);
-void lsm_svg_view_pop_text_attributes (LsmSvgView *view);
const LsmBox * lsm_svg_view_get_pattern_extents (LsmSvgView *view);
const LsmBox * lsm_svg_view_get_clip_extents (LsmSvgView *view);
@@ -113,7 +95,8 @@ void lsm_svg_view_set_gradient_properties (LsmSvgView *view,
void lsm_svg_view_create_surface_pattern (LsmSvgView *view, const LsmBox *viewport,
LsmSvgPatternUnits units,
LsmSvgPatternUnits content_units,
- const LsmSvgMatrix *matrix);
+ const LsmSvgMatrix *matrix,
+ LsmSvgViewSurfaceType surface_type);
void lsm_svg_view_show_rectangle (LsmSvgView *view, double x, double y,
double width, double height,
@@ -127,6 +110,30 @@ void lsm_svg_view_show_polygon (LsmSvgView *view, const char *points);
void lsm_svg_view_show_text (LsmSvgView *view, char const *text, double x, double y);
void lsm_svg_view_show_pixbuf (LsmSvgView *view, GdkPixbuf *pixbuf);
+void lsm_svg_view_push_viewbox (LsmSvgView *view, const LsmBox *viewbox);
+void lsm_svg_view_pop_viewbox (LsmSvgView *view);
+void lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport,
+ const LsmBox *viewbox,
+ const LsmSvgPreserveAspectRatio *aspect_ratio);
+void lsm_svg_view_pop_viewport (LsmSvgView *view);
+void lsm_svg_view_push_matrix (LsmSvgView *view, LsmSvgMatrix *matrix);
+void lsm_svg_view_pop_matrix (LsmSvgView *view);
+
+void lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element);
+void lsm_svg_view_pop_element (LsmSvgView *view);
+
+void lsm_svg_view_push_group_opacity (LsmSvgView *view);
+void lsm_svg_view_pop_group_opacity (LsmSvgView *view);
+
+void lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask);
+void lsm_svg_view_pop_mask_attributes (LsmSvgView *view);
+void lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill);
+void lsm_svg_view_pop_fill_attributes (LsmSvgView *view);
+void lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke);
+void lsm_svg_view_pop_stroke_attributes (LsmSvgView *view);
+void lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text);
+void lsm_svg_view_pop_text_attributes (LsmSvgView *view);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]