[lasem] [SVG] Don't compute the actual length value during update.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [lasem] [SVG] Don't compute the actual length value during update.
- Date: Fri, 15 May 2009 14:15:45 -0400 (EDT)
commit 9f37ee94b5d89f465762028ad39835349c508b16
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Fri May 15 20:14:22 2009 +0200
[SVG] Don't compute the actual length value during update.
We don't have all the necessary informations at that time.
---
src/Makefile.am | 1 +
src/lasemtest.c | 8 ++-
src/lsmdom.h | 7 ++
src/lsmdomdocument.c | 50 ++++++++----
src/lsmdomdocument.h | 16 ++--
src/lsmsvgattributes.c | 102 ++++------------------
src/lsmsvgattributes.h | 40 ++-------
src/lsmsvgcircleelement.c | 22 ++---
src/lsmsvgellipseelement.c | 28 +++----
src/lsmsvgenums.c | 14 ++--
src/lsmsvgenums.h | 10 +-
src/lsmsvggradientelement.c | 15 +--
src/lsmsvggraphic.c | 12 +--
src/lsmsvglength.c | 90 ++++++++++++++++++++
src/lsmsvglength.h | 57 +++++++++++++
src/lsmsvglineargradientelement.c | 37 +++++----
src/lsmsvglineelement.c | 30 +++----
src/lsmsvgpatternelement.c | 73 +++++++++++-----
src/lsmsvgradialgradientelement.c | 58 ++++++++-----
src/lsmsvgrectelement.c | 40 +++------
src/lsmsvgstopelement.c | 10 +--
src/lsmsvgstopelement.h | 2 +-
src/lsmsvgstyle.h | 12 +---
src/lsmsvgsvgelement.c | 161 +++++++++++++++++++-----------------
src/lsmsvgsvgelement.h | 5 +-
src/lsmsvgtextelement.c | 15 ++--
src/lsmsvguseelement.c | 34 ++++----
src/lsmsvgview.c | 168 ++++++++++++++++++++++++++++++-------
src/lsmsvgview.h | 15 +++-
29 files changed, 681 insertions(+), 451 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 3819a41..83ff7af 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,6 +86,7 @@ liblasem_la_SOURCES = \
lsmsvgattributebags.c \
lsmsvgstyle.c \
lsmsvgcolors.c \
+ lsmsvglength.c \
lsmsvgutils.c \
lsmsvgview.c \
lsmsvgmatrix.c
diff --git a/src/lasemtest.c b/src/lasemtest.c
index b7760e4..b33b2d4 100644
--- a/src/lasemtest.c
+++ b/src/lasemtest.c
@@ -110,6 +110,7 @@ lasem_test_render (char const *filename)
success = g_file_get_contents (filename, &buffer, &size, NULL);
if (success) {
+ LsmBox viewport;
char *xml = NULL;
if (is_xml)
@@ -121,8 +122,13 @@ lasem_test_render (char const *filename)
view = lsm_dom_document_create_view (document);
- lsm_dom_document_set_viewport_px (document, 480.0, 360.0);
+ viewport.x = 0.0;
+ viewport.y = 0.0;
+ viewport.width = 480.0;
+ viewport.height = 360.0;
+
lsm_dom_document_set_resolution (document, option_ppi);
+ lsm_dom_document_set_viewport_px (document, &viewport);
lsm_dom_view_get_size_pixels (LSM_DOM_VIEW (view), &width, &height);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width + 2, height + 2);
diff --git a/src/lsmdom.h b/src/lsmdom.h
index b1afee1..5c37273 100644
--- a/src/lsmdom.h
+++ b/src/lsmdom.h
@@ -28,6 +28,13 @@
G_BEGIN_DECLS
+typedef struct {
+ double x;
+ double y;
+ double width;
+ double height;
+} LsmBox;
+
typedef struct _GDomNode LsmDomNode;
typedef struct _GDomElement LsmDomElement;
typedef struct _GDomDocument LsmDomDocument;
diff --git a/src/lsmdomdocument.c b/src/lsmdomdocument.c
index d96a6ba..8dd9879 100644
--- a/src/lsmdomdocument.c
+++ b/src/lsmdomdocument.c
@@ -104,32 +104,49 @@ lsm_dom_document_set_resolution (LsmDomDocument *self, double ppi)
}
void
-lsm_dom_document_set_viewport (LsmDomDocument *self, double width, double height)
+lsm_dom_document_set_viewport (LsmDomDocument *self, const LsmBox *viewport_pt)
{
g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+ g_return_if_fail (viewport_pt != NULL);
- self->viewport_width = width;
- self->viewport_height = height;
+ self->viewport_pt = *viewport_pt;
}
void
-lsm_dom_document_set_viewport_px (LsmDomDocument *self, double width, double height)
+lsm_dom_document_set_viewport_px (LsmDomDocument *self, const LsmBox *viewport)
{
g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+ g_return_if_fail (viewport != NULL);
- self->viewport_width = width * 72.0 / self->resolution_ppi;
- self->viewport_height = height * 72.0 / self->resolution_ppi;
+ self->viewport_pt.x = viewport->x * 72.0 / self->resolution_ppi;
+ self->viewport_pt.y = viewport->y * 72.0 / self->resolution_ppi;
+ self->viewport_pt.width = viewport->width * 72.0 / self->resolution_ppi;
+ self->viewport_pt.height = viewport->height * 72.0 / self->resolution_ppi;
}
-void
-lsm_dom_document_get_viewport (LsmDomDocument *self, double *width, double *height)
+LsmBox
+lsm_dom_document_get_viewport (LsmDomDocument *self)
{
- g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+ static const LsmBox null_viewport = {0, 0, 0, 0};
+
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), null_viewport);
+
+ return self->viewport_pt;
+}
- if (width != NULL)
- *width = self->viewport_width;
- if (height != NULL)
- *height = self->viewport_height;
+LsmBox
+lsm_dom_document_get_viewport_px (LsmDomDocument *self)
+{
+ LsmBox viewport = {0, 0, 0, 0};
+
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), viewport);
+
+ viewport.x = self->viewport_pt.x * self->resolution_ppi / 72.0;
+ viewport.y = self->viewport_pt.y * self->resolution_ppi / 72.0;
+ viewport.width = self->viewport_pt.width * self->resolution_ppi / 72.0;
+ viewport.height = self->viewport_pt.height * self->resolution_ppi / 72.0;
+
+ return viewport;
}
LsmDomElement *
@@ -173,9 +190,12 @@ lsm_dom_document_init (LsmDomDocument *document)
{
document->ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
document->elements = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+
document->resolution_ppi = LSM_DOM_DOCUMENT_DEFAULT_RESOLUTION;
- document->viewport_width = LSM_DOM_DOCUMENT_DEFAULT_VIEWPORT_WIDTH;
- document->viewport_height = LSM_DOM_DOCUMENT_DEFAULT_VIEWPORT_HEIGHT;
+ document->viewport_pt.x = 0;
+ document->viewport_pt.y = 0;
+ document->viewport_pt.width = LSM_DOM_DOCUMENT_DEFAULT_VIEWBOX_WIDTH;
+ document->viewport_pt.height = LSM_DOM_DOCUMENT_DEFAULT_VIEWBOX_HEIGHT;
}
static void
diff --git a/src/lsmdomdocument.h b/src/lsmdomdocument.h
index 1ef081b..0fed990 100644
--- a/src/lsmdomdocument.h
+++ b/src/lsmdomdocument.h
@@ -30,8 +30,8 @@
G_BEGIN_DECLS
#define LSM_DOM_DOCUMENT_DEFAULT_RESOLUTION 72.0
-#define LSM_DOM_DOCUMENT_DEFAULT_VIEWPORT_WIDTH 320.0
-#define LSM_DOM_DOCUMENT_DEFAULT_VIEWPORT_HEIGHT 200.0
+#define LSM_DOM_DOCUMENT_DEFAULT_VIEWBOX_WIDTH 320.0
+#define LSM_DOM_DOCUMENT_DEFAULT_VIEWBOX_HEIGHT 200.0
#define LSM_TYPE_DOM_DOCUMENT (lsm_dom_document_get_type ())
#define LSM_DOM_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_DOCUMENT, LsmDomDocument))
@@ -50,8 +50,7 @@ struct _GDomDocument {
/* Not really a document property, but that simplifies things greatly */
double resolution_ppi;
- double viewport_width;
- double viewport_height;
+ LsmBox viewport_pt;
};
struct _GDomDocumentClass {
@@ -74,11 +73,14 @@ LsmDomElement * lsm_dom_document_get_element_by_id (LsmDomDocument *self, const
void lsm_dom_document_register_element (LsmDomDocument *self, LsmDomElement *element, const char *id);
LsmDomView* lsm_dom_document_create_view (LsmDomDocument *self);
+
double lsm_dom_document_get_resolution (LsmDomDocument *self);
void lsm_dom_document_set_resolution (LsmDomDocument *self, double ppi);
-void lsm_dom_document_set_viewport (LsmDomDocument *self, double width, double height);
-void lsm_dom_document_get_viewport (LsmDomDocument *self, double *width, double *height);
-void lsm_dom_document_set_viewport_px (LsmDomDocument *self, double width, double height);
+
+void lsm_dom_document_set_viewport (LsmDomDocument *self, const LsmBox *viewport);
+void lsm_dom_document_set_viewport_px (LsmDomDocument *self, const LsmBox *viewport);
+LsmBox lsm_dom_document_get_viewport (LsmDomDocument *self);
+LsmBox lsm_dom_document_get_viewport_px (LsmDomDocument *self);
G_END_DECLS
diff --git a/src/lsmsvgattributes.c b/src/lsmsvgattributes.c
index ba5e4a5..0333247 100644
--- a/src/lsmsvgattributes.c
+++ b/src/lsmsvgattributes.c
@@ -111,68 +111,9 @@ lsm_svg_double_attribute_parse (LsmSvgDoubleAttribute *attribute,
*double_value = attribute->value;
}
-static double
-lsm_svg_length_compute (const LsmSvgLength *length,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction)
-{
- double viewport;
- double viewport_scale;
-
- g_return_val_if_fail (length != NULL, 0.0);
-
- switch (direction) {
- case LSM_SVG_LENGTH_DIRECTION_HORIZONTAL:
- viewport = style->viewport.width;
- viewport_scale = style->viewport.horizontal_scale;
- break;
- case LSM_SVG_LENGTH_DIRECTION_VERTICAL:
- viewport = style->viewport.height;
- viewport_scale = style->viewport.vertical_scale;
- break;
- case LSM_SVG_LENGTH_DIRECTION_DIAGONAL:
- viewport = style->viewport.diagonal;
- viewport_scale = style->viewport.diagonal_scale;
- break;
- default:
- viewport = 0.0;
- viewport_scale = 0.0;
- }
-
- switch (length->type) {
- case LSM_SVG_LENGTH_TYPE_NUMBER:
- case LSM_SVG_LENGTH_TYPE_UNKNOWN:
- return length->value_unit;
- case LSM_SVG_LENGTH_TYPE_PERCENTAGE:
- return length->value_unit * viewport / 100.0;
- case LSM_SVG_LENGTH_TYPE_PX:
- return length->value_unit * 72.0 * viewport_scale / style->resolution_ppi;
- case LSM_SVG_LENGTH_TYPE_PT:
- return length->value_unit * viewport_scale;
- case LSM_SVG_LENGTH_TYPE_PC:
- return length->value_unit * 72.0 * viewport_scale / 6.0;
- case LSM_SVG_LENGTH_TYPE_CM:
- return length->value_unit * 72.0 * viewport_scale / 2.54;
- case LSM_SVG_LENGTH_TYPE_MM:
- return length->value_unit * 72.0 * viewport_scale / 25.4;
- case LSM_SVG_LENGTH_TYPE_IN:
- return length->value_unit * 72.0 * viewport_scale;
- case LSM_SVG_LENGTH_TYPE_EMS:
- return length->value_unit * style->text.font_size.value;
- case LSM_SVG_LENGTH_TYPE_EXS:
- return length->value_unit * style->text.font_size.value * 0.5;
- }
-
- g_warning ("[LsmSvgLength::compute] Invalid length property");
-
- return 0.0;
-}
-
void
lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
- LsmSvgLength *default_value,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction)
+ LsmSvgLength *default_value)
{
const char *string;
char *length_type_str;
@@ -188,7 +129,6 @@ lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
} else {
attribute->length.value_unit = g_strtod (string, &length_type_str);
attribute->length.type = lsm_svg_length_type_from_string (length_type_str);
- attribute->length.value = lsm_svg_length_compute (&attribute->length, style, direction);
*default_value = attribute->length;
}
@@ -196,9 +136,7 @@ lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
void
lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
- LsmSvgLength *default_value,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction)
+ LsmSvgLength *default_value)
{
const char *string;
char *length_type_str;
@@ -214,7 +152,6 @@ lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribut
} else {
attribute->length.base.value_unit = g_strtod (string, &length_type_str);
attribute->length.base.type = lsm_svg_length_type_from_string (length_type_str);
- attribute->length.base.value = lsm_svg_length_compute (&attribute->length.base, style, direction);
attribute->length.animated = attribute->length.base;
*default_value = attribute->length.base;
@@ -234,9 +171,7 @@ lsm_svg_dash_array_attribute_finalize (void *abstract)
void
lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
- LsmSvgDashArray **default_value,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction)
+ LsmSvgDashArray **default_value)
{
const char *string;
@@ -274,8 +209,9 @@ lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
for (i = 0; i < n_dashes; i++) {
if (lsm_svg_str_parse_double (&iter, &length.value_unit)) {
length.type = lsm_svg_length_type_from_string (iter);
- attribute->value->dashes[i] =
- lsm_svg_length_compute (&length, style, direction);
+ /* FIXME */
+ attribute->value->dashes[i] = 0.0;
+/* lsm_svg_length_compute (&length, style, direction);*/
while (*iter != '\0' && *iter != ' ' && *iter != ',')
iter ++;
} else
@@ -312,10 +248,10 @@ lsm_svg_line_cap_attribute_parse (LsmDomEnumAttribute *attribute,
}
void
-lsm_svg_gradient_units_attribute_parse (LsmDomEnumAttribute *attribute,
+lsm_svg_pattern_units_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value)
{
- return lsm_dom_enum_attribute_parse (attribute, style_value, lsm_svg_gradient_units_from_string);
+ return lsm_dom_enum_attribute_parse (attribute, style_value, lsm_svg_pattern_units_from_string);
}
void
@@ -512,7 +448,7 @@ lsm_svg_color_attribute_parse (LsmSvgColorAttribute *attribute,
}
void
-lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute)
+lsm_svg_viewbox_attribute_parse (LsmSvgViewboxAttribute *attribute)
{
char *string;
@@ -536,18 +472,18 @@ lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute)
attribute->value.y = value[1];
attribute->value.width = value[2];
attribute->value.height = value[3];
- } else {
- attribute->value.x = 0;
- attribute->value.y = 0;
- attribute->value.width = 0;
- attribute->value.height = 0;
+
+ lsm_debug ("[LsmSvgViewboxAttribute::parse] viewbox = %g, %g, %g, %g",
+ value[0], value[1], value[2], value[3]);
+
+ return;
}
- } else {
- attribute->value.x = 0;
- attribute->value.y = 0;
- attribute->value.width = 0;
- attribute->value.height = 0;
}
+
+ attribute->value.x =
+ attribute->value.y =
+ attribute->value.width =
+ attribute->value.height = 0.0;
}
static void
diff --git a/src/lsmsvgattributes.h b/src/lsmsvgattributes.h
index 9cc43eb..eaa81f1 100644
--- a/src/lsmsvgattributes.h
+++ b/src/lsmsvgattributes.h
@@ -24,8 +24,10 @@
#define LSM_SVG_ATTRIBUTES_H
#include <lsmdomattributes.h>
+#include <lsmdomview.h>
#include <lsmsvg.h>
#include <lsmsvgenums.h>
+#include <lsmsvglength.h>
#include <lsmsvgmatrix.h>
G_BEGIN_DECLS
@@ -60,30 +62,12 @@ typedef struct {
} LsmSvgDashArrayAttribute;
typedef struct {
- double value;
- double value_unit;
- LsmSvgLengthType type;
-} LsmSvgLength;
-
-typedef struct {
- LsmSvgLength base;
- LsmSvgLength animated;
-} LsmSvgAnimatedLength;
-
-typedef struct {
LsmSvgPaintType type;
char *uri;
LsmSvgColor color;
} LsmSvgPaint;
typedef struct {
- double x;
- double y;
- double width;
- double height;
-} LsmSvgViewBox;
-
-typedef struct {
LsmDomAttribute attr;
LsmSvgLength length;
double value;
@@ -112,8 +96,8 @@ typedef struct {
typedef struct {
LsmDomAttribute attr;
- LsmSvgViewBox value;
-} LsmSvgViewBoxAttribute;
+ LsmBox value;
+} LsmSvgViewboxAttribute;
typedef struct {
LsmDomAttribute attr;
@@ -126,20 +110,14 @@ typedef struct {
void lsm_svg_double_attribute_parse (LsmSvgDoubleAttribute *attribute,
double *double_value);
void lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
- LsmSvgLength *default_value,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction);
+ LsmSvgLength *default_value);
void lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
- LsmSvgLength *default_value,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction);
+ LsmSvgLength *default_value);
void lsm_svg_dash_array_attribute_finalize (void *abstract);
void lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
- LsmSvgDashArray **default_value,
- const LsmSvgStyle *style,
- LsmSvgLengthDirection direction);
+ LsmSvgDashArray **default_value);
void lsm_svg_fill_rule_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
@@ -147,7 +125,7 @@ void lsm_svg_line_join_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
void lsm_svg_line_cap_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
-void lsm_svg_gradient_units_attribute_parse (LsmDomEnumAttribute *attribute,
+void lsm_svg_pattern_units_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
void lsm_svg_spread_method_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
@@ -161,7 +139,7 @@ void lsm_svg_color_attribute_parse (LsmSvgColorAttribute *attribute,
/* Attributes */
-void lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute);
+void lsm_svg_viewbox_attribute_parse (LsmSvgViewboxAttribute *attribute);
void lsm_svg_transform_attribute_parse (LsmSvgTransformAttribute *attribute);
G_END_DECLS
diff --git a/src/lsmsvgcircleelement.c b/src/lsmsvgcircleelement.c
index 5ac5190..669b790 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -40,23 +40,17 @@ lsm_svg_circle_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgCircleElement *circle = LSM_SVG_CIRCLE_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&circle->cx, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&circle->cx, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&circle->cy, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&circle->cy, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&circle->r, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ lsm_svg_animated_length_attribute_parse (&circle->r, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -67,11 +61,13 @@ static void
lsm_svg_circle_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgCircleElement *circle = LSM_SVG_CIRCLE_ELEMENT (self);
+ double cx, cy, r;
- lsm_svg_view_show_circle (view,
- circle->cx.length.base.value,
- circle->cy.length.base.value,
- circle->r.length.base.value);
+ cx = lsm_svg_view_normalize_length (view, &circle->cx.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ cy = lsm_svg_view_normalize_length (view, &circle->cy.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ r = lsm_svg_view_normalize_length (view, &circle->r.length.base, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+
+ lsm_svg_view_show_circle (view, cx, cy, r);
}
/* LsmSvgCircleElement implementation */
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index a26f37e..17f7783 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -40,29 +40,21 @@ lsm_svg_ellipse_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgEllipseElement *ellipse = LSM_SVG_ELLIPSE_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->cx, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&ellipse->cx, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->cy, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&ellipse->cy, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->rx, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&ellipse->rx, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->ry, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&ellipse->ry, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -73,12 +65,14 @@ static void
lsm_svg_ellipse_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgEllipseElement *ellipse = LSM_SVG_ELLIPSE_ELEMENT (self);
+ double cx, cy, rx, ry;
- lsm_svg_view_show_ellipse (view,
- ellipse->cx.length.base.value,
- ellipse->cy.length.base.value,
- ellipse->rx.length.base.value,
- ellipse->ry.length.base.value);
+ cx = lsm_svg_view_normalize_length (view, &ellipse->cx.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ cy = lsm_svg_view_normalize_length (view, &ellipse->cy.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ rx = lsm_svg_view_normalize_length (view, &ellipse->rx.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ ry = lsm_svg_view_normalize_length (view, &ellipse->ry.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ lsm_svg_view_show_ellipse (view, cx, cy, rx, ry);
}
/* LsmSvgEllipseElement implementation */
diff --git a/src/lsmsvgenums.c b/src/lsmsvgenums.c
index 6053178..f2f8d63 100644
--- a/src/lsmsvgenums.c
+++ b/src/lsmsvgenums.c
@@ -120,22 +120,22 @@ lsm_svg_line_cap_from_string (const char *string)
G_N_ELEMENTS (lsm_svg_line_cap_strings));
}
-static const char *lsm_svg_gradient_units_strings[] = {
+static const char *lsm_svg_pattern_units_strings[] = {
"userSpaseOnUse",
"objectBoundingBox"
};
const char *
-lsm_svg_gradient_units_to_string (LsmSvgGradientUnits units)
+lsm_svg_pattern_units_to_string (LsmSvgPatternUnits units)
{
- return lsm_svg_gradient_units_strings[CLAMP (units, 0, LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX)];
+ return lsm_svg_pattern_units_strings[CLAMP (units, 0, LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX)];
}
-LsmSvgGradientUnits
-lsm_svg_gradient_units_from_string (const char *string)
+LsmSvgPatternUnits
+lsm_svg_pattern_units_from_string (const char *string)
{
- return lsm_svg_value_from_string (string, lsm_svg_gradient_units_strings,
- G_N_ELEMENTS (lsm_svg_gradient_units_strings));
+ return lsm_svg_value_from_string (string, lsm_svg_pattern_units_strings,
+ G_N_ELEMENTS (lsm_svg_pattern_units_strings));
}
static const char *lsm_svg_spread_method_strings[] = {
diff --git a/src/lsmsvgenums.h b/src/lsmsvgenums.h
index fb42420..1a53db9 100644
--- a/src/lsmsvgenums.h
+++ b/src/lsmsvgenums.h
@@ -99,12 +99,12 @@ typedef enum {
} LsmSvgTransformType;
typedef enum {
- LSM_SVG_GRADIENT_UNITS_USER_SPACE_ON_USE,
- LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX
-} LsmSvgGradientUnits;
+ LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE,
+ LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX
+} LsmSvgPatternUnits;
-const char * lsm_svg_gradient_units_to_string (LsmSvgGradientUnits units);
-LsmSvgGradientUnits lsm_svg_gradient_units_from_string (const char *string);
+const char * lsm_svg_pattern_units_to_string (LsmSvgPatternUnits units);
+LsmSvgPatternUnits lsm_svg_pattern_units_from_string (const char *string);
typedef enum {
LSM_SVG_SPREAD_METHOD_PAD,
diff --git a/src/lsmsvggradientelement.c b/src/lsmsvggradientelement.c
index 80d4802..0d4053c 100644
--- a/src/lsmsvggradientelement.c
+++ b/src/lsmsvggradientelement.c
@@ -41,22 +41,16 @@ static void
_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
{
LsmSvgGradientElement *gradient = LSM_SVG_GRADIENT_ELEMENT (self);
- LsmSvgGradientUnits units;
+ LsmSvgPatternUnits units;
LsmSvgSpreadMethod method;
- units = LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX;
+ units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
method = LSM_SVG_SPREAD_METHOD_PAD;
- lsm_svg_gradient_units_attribute_parse (&gradient->units, &units);
+ lsm_svg_pattern_units_attribute_parse (&gradient->units, &units);
lsm_svg_spread_method_attribute_parse (&gradient->spread_method, &method);
lsm_svg_transform_attribute_parse (&gradient->transform);
- if (gradient->units.value == LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX) {
- parent_style->viewport.width = 1.0;
- parent_style->viewport.height = 1.0;
- parent_style->viewport.diagonal = 1.0;
- }
-
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -76,7 +70,8 @@ _gradient_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
stop = LSM_SVG_STOP_ELEMENT (iter);
- offset = lsm_svg_stop_element_get_offset (stop);
+ offset = lsm_svg_view_normalize_length (view, lsm_svg_stop_element_get_offset (stop),
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
color = lsm_svg_stop_element_get_color (stop);
opacity = lsm_svg_stop_element_get_opacity (stop);
diff --git a/src/lsmsvggraphic.c b/src/lsmsvggraphic.c
index 6f48b81..b2c557e 100644
--- a/src/lsmsvggraphic.c
+++ b/src/lsmsvggraphic.c
@@ -97,8 +97,7 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
if (graphic->text != NULL) {
lsm_dom_string_attribute_parse (&graphic->text->font_family, &parent_style->text.font_family);
- lsm_svg_length_attribute_parse (&graphic->text->font_size, &parent_style->text.font_size,
- parent_style, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ lsm_svg_length_attribute_parse (&graphic->text->font_size, &parent_style->text.font_size);
}
if (graphic->fill != NULL) {
@@ -115,16 +114,13 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
lsm_svg_paint_attribute_parse (&graphic->stroke->paint, &parent_style->stroke.paint,
&graphic->color.value);
- lsm_svg_length_attribute_parse (&graphic->stroke->width, &parent_style->stroke.width,
- parent_style, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ lsm_svg_length_attribute_parse (&graphic->stroke->width, &parent_style->stroke.width);
lsm_dom_double_attribute_parse (&graphic->stroke->opacity, &parent_style->stroke.opacity);
lsm_svg_line_join_attribute_parse (&graphic->stroke->line_join, &parent_style->stroke.line_join);
lsm_svg_line_cap_attribute_parse (&graphic->stroke->line_cap, &parent_style->stroke.line_cap);
lsm_svg_double_attribute_parse (&graphic->stroke->miter_limit, &parent_style->stroke.miter_limit);
- lsm_svg_dash_array_attribute_parse (&graphic->stroke->dash_array, &parent_style->stroke.dash_array,
- parent_style, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- lsm_svg_length_attribute_parse (&graphic->stroke->dash_offset, &parent_style->stroke.dash_offset,
- parent_style, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ lsm_svg_dash_array_attribute_parse (&graphic->stroke->dash_array, &parent_style->stroke.dash_array);
+ lsm_svg_length_attribute_parse (&graphic->stroke->dash_offset, &parent_style->stroke.dash_offset);
}
if (graphic->transform != NULL) {
diff --git a/src/lsmsvglength.c b/src/lsmsvglength.c
new file mode 100644
index 0000000..8da7927
--- /dev/null
+++ b/src/lsmsvglength.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+
+#include <math.h>
+#include <lsmsvglength.h>
+
+LsmSvgViewbox *
+lsm_svg_viewbox_new (double resolution_ppi,
+ const LsmBox *viewbox)
+{
+ LsmSvgViewbox *svg_viewbox;
+
+ svg_viewbox = g_new (LsmSvgViewbox, 1);
+ svg_viewbox->resolution_ppi = resolution_ppi;
+ svg_viewbox->viewbox = *viewbox;
+ svg_viewbox->diagonal = sqrt (viewbox->width * viewbox->width +
+ viewbox->height * viewbox->height) / sqrt (2.0);
+
+ return svg_viewbox;
+}
+
+void
+lsm_svg_viewbox_free (LsmSvgViewbox *viewbox)
+{
+ g_free (viewbox);
+}
+
+double
+lsm_svg_length_normalize (const LsmSvgLength *length,
+ const LsmSvgViewbox *viewbox,
+ double font_size,
+ LsmSvgLengthDirection direction)
+{
+ g_return_val_if_fail (length != NULL, 0.0);
+ g_return_val_if_fail (viewbox != NULL, 0.0);
+
+ switch (length->type) {
+ case LSM_SVG_LENGTH_TYPE_NUMBER:
+ case LSM_SVG_LENGTH_TYPE_UNKNOWN:
+ case LSM_SVG_LENGTH_TYPE_PX:
+ return length->value_unit;
+ case LSM_SVG_LENGTH_TYPE_PERCENTAGE:
+ switch (direction) {
+ case LSM_SVG_LENGTH_DIRECTION_HORIZONTAL:
+ return length->value_unit * viewbox->viewbox.width / 100.0;
+ case LSM_SVG_LENGTH_DIRECTION_VERTICAL:
+ return length->value_unit * viewbox->viewbox.height / 100.0;
+ case LSM_SVG_LENGTH_DIRECTION_DIAGONAL:
+ return length->value_unit * viewbox->diagonal / 100.0;
+ }
+ break;
+ case LSM_SVG_LENGTH_TYPE_PT:
+ return length->value_unit * viewbox->resolution_ppi / 72.0;
+ case LSM_SVG_LENGTH_TYPE_PC:
+ return length->value_unit * viewbox->resolution_ppi / 6.00;
+ case LSM_SVG_LENGTH_TYPE_CM:
+ return length->value_unit * viewbox->resolution_ppi / 2.54;
+ case LSM_SVG_LENGTH_TYPE_MM:
+ return length->value_unit * viewbox->resolution_ppi / 25.4;
+ case LSM_SVG_LENGTH_TYPE_IN:
+ return length->value_unit * viewbox->resolution_ppi;
+ case LSM_SVG_LENGTH_TYPE_EMS:
+ return length->value_unit * font_size;
+ case LSM_SVG_LENGTH_TYPE_EXS:
+ return length->value_unit * font_size * 0.5;
+ }
+
+ g_warning ("[LsmSvg::normalize_length] Invalid length property");
+
+ return 0.0;
+}
diff --git a/src/lsmsvglength.h b/src/lsmsvglength.h
new file mode 100644
index 0000000..70d96ec
--- /dev/null
+++ b/src/lsmsvglength.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_SVG_LENGTH
+#define LSM_SVG_LENGTH
+
+#include <lsmdomview.h>
+#include <lsmsvg.h>
+#include <lsmsvgenums.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ double resolution_ppi;
+ LsmBox viewbox;
+ double diagonal;
+} LsmSvgViewbox;
+
+LsmSvgViewbox * lsm_svg_viewbox_new (double resolution_ppi, const LsmBox *viewbox);
+void lsm_svg_viewbox_free (LsmSvgViewbox *viewbox);
+
+typedef struct {
+ double value_unit;
+ LsmSvgLengthType type;
+} LsmSvgLength;
+
+typedef struct {
+ LsmSvgLength base;
+ LsmSvgLength animated;
+} LsmSvgAnimatedLength;
+
+double lsm_svg_length_normalize (const LsmSvgLength *length,
+ const LsmSvgViewbox *viewbox,
+ double font_size,
+ LsmSvgLengthDirection direction);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvglineargradientelement.c b/src/lsmsvglineargradientelement.c
index d454eb8..2fd37cf 100644
--- a/src/lsmsvglineargradientelement.c
+++ b/src/lsmsvglineargradientelement.c
@@ -44,45 +44,50 @@ _linear_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->x1, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&linear->x1, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->y1, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&linear->y1, &length);
- length.value = 100.0;
length.value_unit = 100.0;
length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->x2, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&linear->x2, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->y2, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&linear->y2, &length);
}
static void
_linear_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgLinearGradientElement *linear = LSM_SVG_LINEAR_GRADIENT_ELEMENT (self);
+ gboolean is_object_bounding_box;
double x1, x2, y1, y2;
- x1 = linear->x1.length.base.value;
- y1 = linear->y1.length.base.value;
- x2 = linear->x2.length.base.value;
- y2 = linear->y2.length.base.value;
+ is_object_bounding_box = (LSM_SVG_GRADIENT_ELEMENT (self)->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);
+ }
+
+ x1 = lsm_svg_view_normalize_length (view, &linear->x1.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y1 = lsm_svg_view_normalize_length (view, &linear->y1.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ x2 = lsm_svg_view_normalize_length (view, &linear->x2.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y2 = lsm_svg_view_normalize_length (view, &linear->y2.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
lsm_debug ("[LsmSvgLinearGradientElement::render] Create linear %g, %g, %g, %g",
x1, y1, x2, y2);
+ if (is_object_bounding_box)
+ lsm_svg_view_pop_viewbox (view);
+
lsm_svg_view_create_linear_gradient (view, x1, y1, x2, y2);
LSM_SVG_ELEMENT_CLASS (parent_class)->render_paint (self, view);
diff --git a/src/lsmsvglineelement.c b/src/lsmsvglineelement.c
index 14e7ee6..a272bb3 100644
--- a/src/lsmsvglineelement.c
+++ b/src/lsmsvglineelement.c
@@ -21,6 +21,7 @@
#include <lsmsvglineelement.h>
#include <lsmsvgview.h>
+#include <lsmdebug.h>
static GObjectClass *parent_class;
@@ -40,29 +41,21 @@ lsm_svg_line_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgLineElement *line = LSM_SVG_LINE_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->x1, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&line->x1, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->y1, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&line->y1, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->x2, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&line->x2, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->y2, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&line->y2, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -73,11 +66,16 @@ static void
lsm_svg_line_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgLineElement *line = LSM_SVG_LINE_ELEMENT (self);
+ double x1, y1, x2, y2;
- lsm_svg_view_show_line (view,line->x1.length.base.value,
- line->y1.length.base.value,
- line->x2.length.base.value,
- line->y2.length.base.value);
+ x1 = lsm_svg_view_normalize_length (view, &line->x1.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y1 = lsm_svg_view_normalize_length (view, &line->y1.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ x2 = lsm_svg_view_normalize_length (view, &line->x2.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y2 = lsm_svg_view_normalize_length (view, &line->y2.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ lsm_debug ("[LsmSvgLineElement::graphic_render] %g, %g, %g, %g", x1, y1, x2, y2);
+
+ lsm_svg_view_show_line (view, x1, y1, x2, y2);
}
/* LsmSvgLineElement implementation */
diff --git a/src/lsmsvgpatternelement.c b/src/lsmsvgpatternelement.c
index 3c06ab2..8034a66 100644
--- a/src/lsmsvgpatternelement.c
+++ b/src/lsmsvgpatternelement.c
@@ -40,40 +40,32 @@ static void
_pattern_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
{
LsmSvgPatternElement *pattern = LSM_SVG_PATTERN_ELEMENT (self);
- LsmSvgGradientUnits units;
+ LsmSvgPatternUnits units;
LsmSvgLength length;
- units = LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX;
- lsm_svg_gradient_units_attribute_parse (&pattern->units, &units);
+ units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
+ lsm_svg_pattern_units_attribute_parse (&pattern->units, &units);
- units = LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX;
- lsm_svg_gradient_units_attribute_parse (&pattern->content_units, &units);
+ units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
+ lsm_svg_pattern_units_attribute_parse (&pattern->content_units, &units);
lsm_svg_transform_attribute_parse (&pattern->transform);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->x, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&pattern->x, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->y, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&pattern->y, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->width, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&pattern->width, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->height, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&pattern->height, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -82,23 +74,58 @@ static void
_pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgPatternElement *pattern = LSM_SVG_PATTERN_ELEMENT (self);
- double width, height;
+ double x, y, width, height;
+ gboolean is_object_bounding_box;
- width = pattern->width.length.base.value;
- height = pattern->height.length.base.value;
+ is_object_bounding_box = (pattern->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
- if (width < 1.0 || height < 1.0)
+ 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);
+ }
+
+ x = lsm_svg_view_normalize_length (view, &pattern->x.length.base,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &pattern->y.length.base,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ width = lsm_svg_view_normalize_length (view, &pattern->width.length.base,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ height = lsm_svg_view_normalize_length (view, &pattern->height.length.base,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ if (is_object_bounding_box)
+ lsm_svg_view_pop_viewbox (view);
+
+ if (width <= 0.0 || height <= 0.0)
return;
- lsm_debug ("[LsmSvgPatternElement::render_paint] Create pattern w = %g, h = %g",
- width, height);
+ lsm_debug ("[LsmSvgPatternElement::render_paint] Create pattern x = %g, y = %g, w = %g, h = %g",
+ x, y, width, height);
lsm_svg_view_create_surface_pattern (view, width, height,
pattern->units.value,
pattern->content_units.value,
&pattern->transform.matrix);
+ is_object_bounding_box = (pattern->content_units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+
+ if (is_object_bounding_box) {
+ LsmBox extents;
+ LsmSvgMatrix matrix;
+
+ extents = lsm_svg_view_get_extents (view);
+ lsm_svg_matrix_init_scale (&matrix, extents.width, extents.height);
+ lsm_svg_view_push_viewbox (view, &extents);
+ lsm_svg_view_push_transform (view, &matrix);
+ }
+
LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);
+
+ if (is_object_bounding_box) {
+ lsm_svg_view_pop_transform (view);
+ lsm_svg_view_pop_viewbox (view);
+ }
}
/* LsmSvgPatternElement implementation */
diff --git a/src/lsmsvgradialgradientelement.c b/src/lsmsvgradialgradientelement.c
index 5fec09e..34ac706 100644
--- a/src/lsmsvgradialgradientelement.c
+++ b/src/lsmsvgradialgradientelement.c
@@ -23,6 +23,7 @@
#include <lsmsvgview.h>
#include <lsmdebug.h>
#include <stdio.h>
+#include <math.h>
static GObjectClass *parent_class;
@@ -44,48 +45,65 @@ _radial_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
- length.value = 50.0;
length.value_unit = 50.0;
length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&radial->cx, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&radial->cx, &length);
- length.value = 50.0;
length.value_unit = 50.0;
length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&radial->cy, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&radial->cy, &length);
- length.value = 50.0;
length.value_unit = 50.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&radial->r, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
+ lsm_svg_animated_length_attribute_parse (&radial->r, &length);
length = radial->cx.length.base;
- lsm_svg_animated_length_attribute_parse (&radial->fx, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&radial->fx, &length);
length = radial->cy.length.base;
- lsm_svg_animated_length_attribute_parse (&radial->fy, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&radial->fy, &length);
}
static void
_radial_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgRadialGradientElement *radial = LSM_SVG_RADIAL_GRADIENT_ELEMENT (self);
+ gboolean is_object_bounding_box;
double cx, cy, fx, fy, r;
-
- cx = radial->cx.length.base.value;
- cy = radial->cy.length.base.value;
- r = radial->r.length.base.value;
- fx = radial->fx.length.base.value;
- fy = radial->fy.length.base.value;
+ double gradient_radius;
+
+ is_object_bounding_box = (LSM_SVG_GRADIENT_ELEMENT (self)->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);
+ }
+
+ cx = lsm_svg_view_normalize_length (view, &radial->cx.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ cy = lsm_svg_view_normalize_length (view, &radial->cy.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ r = lsm_svg_view_normalize_length (view, &radial->r.length.base, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ fx = lsm_svg_view_normalize_length (view, &radial->fx.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ fy = lsm_svg_view_normalize_length (view, &radial->fy.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ gradient_radius = sqrt ((fx - cx) * (fx - cx) + (fy - cy) * (fy - cy));
+ if (gradient_radius > r) {
+ if (gradient_radius > 0.0) {
+ fx = cx + ((fx - cx) * r / gradient_radius);
+ fy = cy + ((fy - cy) * r / gradient_radius);
+ } else {
+ fx = cx;
+ fy = cy;
+ }
+ }
lsm_debug ("[LsmSvgRadialElement::render] cx = %g, cy = %g, r = %g, fx = %g, fy = %g",
cx, cy, r, fx, fy);
+ if (is_object_bounding_box)
+ lsm_svg_view_pop_viewbox (view);
+
lsm_svg_view_create_radial_gradient (view, cx, cy, r, fx, fy);
LSM_SVG_ELEMENT_CLASS (parent_class)->render_paint (self, view);
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index fad65c7..3c2aa21 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -40,41 +40,29 @@ lsm_svg_rect_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgRectElement *rect = LSM_SVG_RECT_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->x, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&rect->x, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->y, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&rect->y, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->width, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&rect->width, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->height, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&rect->height, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->rx, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&rect->rx, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->ry, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&rect->ry, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -85,13 +73,16 @@ static void
lsm_svg_rect_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgRectElement *rect = LSM_SVG_RECT_ELEMENT (self);
+ double x, y;
double rx, ry;
double w, h;
- rx = rect->rx.length.base.value;
- ry = rect->ry.length.base.value;
- w = rect->width.length.base.value;
- h = rect->height.length.base.value;
+ x = lsm_svg_view_normalize_length (view, &rect->x.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &rect->y.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ rx = lsm_svg_view_normalize_length (view, &rect->rx.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ ry = lsm_svg_view_normalize_length (view, &rect->ry.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ w = lsm_svg_view_normalize_length (view, &rect->width.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ h = lsm_svg_view_normalize_length (view, &rect->height.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
/* SVG specification is so weird sometimes ... */
if (w == 0.0 || h == 0.0)
@@ -102,10 +93,7 @@ lsm_svg_rect_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
else if (!lsm_dom_attribute_is_defined (&rect->ry.attr))
ry = rx;
- lsm_svg_view_show_rectangle (view,
- rect->x.length.base.value,
- rect->y.length.base.value,
- w, h, rx, ry);
+ lsm_svg_view_show_rectangle (view, x, y, w, h, rx, ry);
}
/* LsmSvgRectElement implementation */
diff --git a/src/lsmsvgstopelement.c b/src/lsmsvgstopelement.c
index c9931f8..04196a7 100644
--- a/src/lsmsvgstopelement.c
+++ b/src/lsmsvgstopelement.c
@@ -43,22 +43,20 @@ _stop_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgStopElement *stop = LSM_SVG_STOP_ELEMENT (self);
LsmSvgLength length;
- length.value = 1.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&stop->offset, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ lsm_svg_length_attribute_parse (&stop->offset, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
/* LsmSvgStopElement implementation */
-double
+const LsmSvgLength *
lsm_svg_stop_element_get_offset (LsmSvgStopElement *self)
{
- g_return_val_if_fail (LSM_IS_SVG_STOP_ELEMENT (self), 0.0);
+ g_return_val_if_fail (LSM_IS_SVG_STOP_ELEMENT (self), NULL);
- return LSM_SVG_STOP_ELEMENT (self)->offset.length.value;
+ return &(LSM_SVG_STOP_ELEMENT (self)->offset.length);
}
const LsmSvgColor *
diff --git a/src/lsmsvgstopelement.h b/src/lsmsvgstopelement.h
index c821dd4..3355aca 100644
--- a/src/lsmsvgstopelement.h
+++ b/src/lsmsvgstopelement.h
@@ -50,7 +50,7 @@ GType lsm_svg_stop_element_get_type (void);
LsmDomNode * lsm_svg_stop_element_new (void);
-double lsm_svg_stop_element_get_offset (LsmSvgStopElement *self);
+const LsmSvgLength * lsm_svg_stop_element_get_offset (LsmSvgStopElement *self);
const LsmSvgColor * lsm_svg_stop_element_get_color (LsmSvgStopElement *self);
double lsm_svg_stop_element_get_opacity (LsmSvgStopElement *self);
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index 85bfdcf..20d6ac3 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -28,19 +28,9 @@
G_BEGIN_DECLS
struct _LsmSvgStyle {
+ LsmBox viewport;
LsmSvgColor color;
- double resolution_ppi;
-
- struct {
- double width;
- double height;
- double diagonal;
- double horizontal_scale;
- double vertical_scale;
- double diagonal_scale;
- } viewport;
-
struct {
LsmSvgPaint paint;
LsmSvgFillRule rule;
diff --git a/src/lsmsvgsvgelement.c b/src/lsmsvgsvgelement.c
index 703dd53..d553671 100644
--- a/src/lsmsvgsvgelement.c
+++ b/src/lsmsvgsvgelement.c
@@ -45,74 +45,47 @@ _svg_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
- length.value_unit = 0.0;
+ length.value_unit = 0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->x, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_length_attribute_parse (&svg->x, &length);
- length.value = 0.0;
- length.value_unit = 0.0;
+ length.value_unit = 0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->y, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_length_attribute_parse (&svg->y, &length);
- length.value = 0.0;
- length.value_unit = 0.0;
+ length.value_unit = parent_style->viewport.width;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->width, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_length_attribute_parse (&svg->width, &length);
- length.value = 0.0;
- length.value_unit = 0.0;
+ length.value_unit = parent_style->viewport.height;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->height, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_length_attribute_parse (&svg->height, &length);
- if (svg->width.length.value <= 0.0)
- svg->width.length.value = parent_style->viewport.width;
- if (svg->height.length.value <= 0.0)
- svg->height.length.value = parent_style->viewport.height;
-
- lsm_svg_view_box_attribute_parse (&svg->view_box);
-
- if (svg->view_box.value.width <= 0.0)
- svg->view_box.value.width = svg->width.length.value;
- if (svg->view_box.value.height <= 0.0)
- svg->view_box.value.height = svg->height.length.value;
-
- lsm_debug ("[LsmSvgSvgElement::update] height = %g px, width = %g px",
- svg->height.length.value,
- svg->width.length.value);
+ lsm_svg_viewbox_attribute_parse (&svg->viewbox);
lsm_debug ("[LsmSvgSvgElement::update] view_bbox = %g, %g, %g, %g\n",
- svg->view_box.value.x,
- svg->view_box.value.y,
- svg->view_box.value.width,
- svg->view_box.value.height);
-
- parent_style->viewport.width = svg->view_box.value.width;
- parent_style->viewport.height = svg->view_box.value.height;
- parent_style->viewport.diagonal= sqrt (pow (svg->view_box.value.width, 2.0) +
- pow (svg->view_box.value.height, 2.0)) / sqrt (2.0);
-
- parent_style->viewport.horizontal_scale = svg->width.length.value / svg->view_box.value.width;
- parent_style->viewport.vertical_scale = svg->height.length.value / svg->view_box.value.height;
- parent_style->viewport.diagonal_scale = sqrt (pow (parent_style->viewport.horizontal_scale, 2.0) +
- pow (parent_style->viewport.vertical_scale, 2.0)) / sqrt (2.0);
- parent_style->viewport.horizontal_scale =
- parent_style->viewport.vertical_scale =
- parent_style->viewport.diagonal_scale = parent_style->resolution_ppi / 72.0;
-
- lsm_debug ("[LsmSvgSvgElement::update] viewport = %g, %g",
- parent_style->viewport.width, parent_style->viewport.height);
- lsm_debug ("[LsmSvgSvgElement::update] viewport_scale = %g, %g",
- parent_style->viewport.horizontal_scale, parent_style->viewport.vertical_scale);
+ svg->viewbox.value.x,
+ svg->viewbox.value.y,
+ svg->viewbox.value.width,
+ svg->viewbox.value.height);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
+
+ parent_style->viewport = svg->viewbox.value;
}
void
lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *height)
{
LsmDomDocument *document;
+ LsmSvgViewbox *svg_viewbox;
+ LsmBox viewport;
double resolution_ppi;
+ double svg_x;
+ double svg_y;
+ double svg_width;
+ double svg_height;
+ double font_size;
g_return_if_fail (LSM_IS_SVG_SVG_ELEMENT (self));
@@ -120,11 +93,34 @@ lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *heig
g_return_if_fail (LSM_IS_DOM_DOCUMENT (document));
resolution_ppi = lsm_dom_document_get_resolution (document);
+ viewport = lsm_dom_document_get_viewport_px (document);
+
+ svg_viewbox = lsm_svg_viewbox_new (resolution_ppi, &viewport);
+ font_size = 10 * resolution_ppi / 72.0;
+
+ svg_x = lsm_svg_length_normalize (&self->x.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ svg_y = lsm_svg_length_normalize (&self->y.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ svg_width = lsm_svg_length_normalize (&self->width.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ svg_height = lsm_svg_length_normalize (&self->height.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
if (width != NULL)
- *width = self->width.length.value * 72.0 / resolution_ppi;
+ *width = svg_width * 72.0 / resolution_ppi;
if (height != NULL)
- *height = self->height.length.value * 72.0 / resolution_ppi;
+ *height = svg_height * 72.0 / resolution_ppi;
+
+ self->svg_box.x = svg_x;
+ self->svg_box.y = svg_y;
+ self->svg_box.width = svg_width;
+ self->svg_box.height = svg_height;
+
+ lsm_debug ("[LsmSvgSvgElement::measure] Size = %g, %g, %g, %g",
+ svg_x, svg_y, svg_width, svg_height);
+
+ lsm_svg_viewbox_free (svg_viewbox);
}
/* LsmSvgGraphic implementation */
@@ -133,23 +129,37 @@ static void
lsm_svg_svg_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
- LsmSvgMatrix matrix;
+ const LsmBox *viewbox;
+ gboolean is_viewbox_defined;
- if (svg->view_box.value.width <= 0.0 ||
- svg->view_box.value.height <= 0.0)
- return;
+ is_viewbox_defined = lsm_dom_attribute_is_defined ((LsmDomAttribute *) &svg->viewbox);
- lsm_svg_matrix_init (&matrix,
- svg->width.length.value / svg->view_box.value.width,
- 0, 0,
- svg->height.length.value / svg->view_box.value.height,
- 0, 0);
+ if (is_viewbox_defined) {
+ LsmSvgMatrix matrix;
- lsm_svg_view_push_transform (view, &matrix);
+ if (svg->viewbox.value.width <= 0.0 ||
+ svg->viewbox.value.height <= 0.0)
+ return;
+
+ viewbox = &svg->viewbox.value;
+
+ lsm_svg_matrix_init (&matrix,
+ svg->svg_box.width / svg->viewbox.value.width, 0.0,
+ 0.0 , svg->svg_box.height / svg->viewbox.value.height,
+ -svg->viewbox.value.x,-svg->viewbox.value.y);
+
+ lsm_svg_view_push_transform (view, &matrix);
+ } else
+ viewbox = &svg->svg_box;
+
+ lsm_svg_view_push_viewbox (view, viewbox);
LSM_SVG_GRAPHIC_CLASS (parent_class)->graphic_render (self, view);
- lsm_svg_view_pop_transform (view);
+ lsm_svg_view_pop_viewbox (view);
+
+ if (is_viewbox_defined)
+ lsm_svg_view_pop_transform (view);
}
/* LsmSvgSvgElement implementation */
@@ -175,16 +185,15 @@ lsm_svg_svg_element_update (LsmSvgSvgElement *svg_element)
style = lsm_svg_svg_element_get_default_style (svg_element);
- style->resolution_ppi = lsm_dom_document_get_resolution (document);
- lsm_dom_document_get_viewport (document, &style->viewport.width, &style->viewport.height);
- style->viewport.diagonal = sqrt (pow (style->viewport.width, 2.0) + pow (style->viewport.height, 2.0)) /
- sqrt (2.0);
- style->viewport.horizontal_scale =
- style->viewport.vertical_scale =
- style->viewport.diagonal_scale = style->resolution_ppi / 72.0;
+ style->viewport = lsm_dom_document_get_viewport_px (document);
- lsm_svg_element_update (LSM_SVG_ELEMENT (svg_element),
- lsm_svg_svg_element_get_default_style (svg_element));
+ lsm_svg_element_update (LSM_SVG_ELEMENT (svg_element), style);
+}
+
+void
+lsm_svg_svg_element_render (LsmSvgSvgElement *svg, LsmSvgView *view)
+{
+ lsm_svg_element_render (LSM_SVG_ELEMENT (svg), view);
}
LsmDomNode *
@@ -250,15 +259,15 @@ lsm_svg_svg_element_class_init (LsmSvgSvgElementClass *s_svg_class)
s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x",
- offsetof (LsmSvgSvgElement, x));
+ offsetof (LsmSvgSvgElement, x));
lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgSvgElement, y));
+ offsetof (LsmSvgSvgElement, y));
lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgSvgElement, width));
+ offsetof (LsmSvgSvgElement, width));
lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgSvgElement, height));
+ offsetof (LsmSvgSvgElement, height));
lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "viewBox",
- offsetof (LsmSvgSvgElement, view_box));
+ offsetof (LsmSvgSvgElement, viewbox));
}
G_DEFINE_TYPE (LsmSvgSvgElement, lsm_svg_svg_element, LSM_TYPE_SVG_GRAPHIC)
diff --git a/src/lsmsvgsvgelement.h b/src/lsmsvgsvgelement.h
index b32e617..a5f7137 100644
--- a/src/lsmsvgsvgelement.h
+++ b/src/lsmsvgsvgelement.h
@@ -46,7 +46,9 @@ struct _GSvgSvgElement {
LsmSvgLengthAttribute width;
LsmSvgLengthAttribute height;
- LsmSvgViewBoxAttribute view_box;
+ LsmSvgViewboxAttribute viewbox;
+
+ LsmBox svg_box;
};
struct _GSvgSvgElementClass {
@@ -60,6 +62,7 @@ LsmDomNode * lsm_svg_svg_element_new (void);
LsmSvgStyle * lsm_svg_svg_element_get_default_style (LsmSvgSvgElement *svg_element);
void lsm_svg_svg_element_update (LsmSvgSvgElement *svg_element);
void lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *height);
+void lsm_svg_svg_element_render (LsmSvgSvgElement *svg_element, LsmSvgView *view);
G_END_DECLS
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index 9209afc..f89c44e 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -47,17 +47,13 @@ lsm_svg_text_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgTextElement *text = LSM_SVG_TEXT_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&text->x, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&text->x, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&text->y, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&text->y, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -71,6 +67,7 @@ lsm_svg_text_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
LsmDomNode *node = LSM_DOM_NODE (self);
LsmDomNode *iter;
GString *string = g_string_new ("");
+ double x, y;
if (node->first_child == NULL)
return;
@@ -81,8 +78,10 @@ lsm_svg_text_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
}
}
- lsm_svg_view_show_text (view, g_strstrip (string->str),
- text->x.length.base.value, text->y.length.base.value);
+ x = lsm_svg_view_normalize_length (view, &text->x.length.base, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &text->y.length.base, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ lsm_svg_view_show_text (view, g_strstrip (string->str), x, y);
g_string_free (string, TRUE);
}
diff --git a/src/lsmsvguseelement.c b/src/lsmsvguseelement.c
index 7c83ab2..51775ac 100644
--- a/src/lsmsvguseelement.c
+++ b/src/lsmsvguseelement.c
@@ -49,29 +49,21 @@ lsm_svg_use_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgUseElement *use_element = LSM_SVG_USE_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->x, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&use_element->x, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->y, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&use_element->y, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->width, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ lsm_svg_animated_length_attribute_parse (&use_element->width, &length);
- length.value = 0.0;
length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->height, &length, parent_style,
- LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_animated_length_attribute_parse (&use_element->height, &length);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
@@ -86,6 +78,7 @@ lsm_svg_use_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
LsmDomElement *element;
LsmSvgMatrix matrix;
const char *id;
+ double x, y, width, height;
document = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
if (document == NULL) {
@@ -109,18 +102,25 @@ lsm_svg_use_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
return;
}
-/* if (use_element->width.length.base.value <= 0.0 ||*/
-/* use_element->height.length.base.value <= 0.0)*/
+ width = lsm_svg_view_normalize_length (view, &use_element->width.length.base,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ height = lsm_svg_view_normalize_length (view, &use_element->height.length.base,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+/* if (width <= 0.0 || height <= 0.0)*/
/* return;*/
lsm_debug ("[LsmSvgUseElement::graphic_render] Use '%s'", id);
- lsm_svg_matrix_init_translate (&matrix,
- use_element->x.length.base.value,
- use_element->y.length.base.value);
+ x = lsm_svg_view_normalize_length (view, &use_element->x.length.base,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &use_element->y.length.base,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ lsm_svg_matrix_init_translate (&matrix, x, y);
lsm_svg_view_push_transform (view, &matrix);
+
lsm_svg_element_render (LSM_SVG_ELEMENT (element), view);
+
lsm_svg_view_pop_transform (view);
}
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index d96e974..0d3af8a 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -40,14 +40,28 @@ struct _GSvgViewPatternData {
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
- LsmSvgGradientUnits units;
- LsmSvgGradientUnits content_units;
+ LsmBox extents;
+
+ LsmSvgPatternUnits units;
+ LsmSvgPatternUnits content_units;
LsmSvgSpreadMethod spread_method;
};
+LsmBox
+lsm_svg_view_get_extents (LsmSvgView *view)
+{
+ LsmBox null_box = {.x = 0.0, .y = 0.0, .width = 0.0, .height = 0.0};
+
+ g_return_val_if_fail (LSM_IS_SVG_VIEW (view), null_box);
+ g_return_val_if_fail (view->pattern_data != NULL, null_box);
+
+ return view->pattern_data->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);
@@ -55,11 +69,19 @@ _start_pattern (LsmSvgView *view)
view->pattern_data = g_new (LsmSvgViewPatternData, 1);
view->pattern_data->old_cairo = view->dom_view.cairo;
view->pattern_data->pattern = NULL;
- view->pattern_data->units = LSM_SVG_GRADIENT_UNITS_USER_SPACE_ON_USE;
+ 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->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);
}
@@ -90,22 +112,20 @@ static void
_set_pattern (LsmSvgView *view, cairo_pattern_t *pattern)
{
g_return_if_fail (view->pattern_data != NULL);
-
- if (view->pattern_data->pattern != NULL)
- cairo_pattern_destroy (view->pattern_data->pattern);
+ g_return_if_fail (view->pattern_data->pattern == NULL);
view->pattern_data->pattern = pattern;
}
void
lsm_svg_view_create_radial_gradient (LsmSvgView *view,
- double cx, double cy,
- double r,
- double fx, double fy)
+ double cx, double cy,
+ double r,
+ double fx, double fy)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- _set_pattern (view, cairo_pattern_create_radial (cx, cy, 0, fx, fy, r));
+ _set_pattern (view, cairo_pattern_create_radial (fx, fy, 0, cx, cy, r));
}
void
@@ -133,7 +153,7 @@ lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset, const Lsm
void
lsm_svg_view_set_gradient_properties (LsmSvgView *view,
LsmSvgSpreadMethod method,
- LsmSvgGradientUnits units,
+ LsmSvgPatternUnits units,
const LsmSvgMatrix *matrix)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
@@ -155,8 +175,8 @@ lsm_svg_view_set_gradient_properties (LsmSvgView *view,
void
lsm_svg_view_create_surface_pattern (LsmSvgView *view,
double width, double height,
- LsmSvgGradientUnits units,
- LsmSvgGradientUnits content_units,
+ LsmSvgPatternUnits units,
+ LsmSvgPatternUnits content_units,
const LsmSvgMatrix *matrix)
{
cairo_surface_t *surface;
@@ -166,6 +186,14 @@ lsm_svg_view_create_surface_pattern (LsmSvgView *view,
g_return_if_fail (view->pattern_data != NULL);
g_return_if_fail (view->dom_view.cairo == NULL);
+ if (units == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX) {
+ width = width * view->pattern_data->extents.width;
+ height = height * view->pattern_data->extents.height;
+ }
+
+ 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);
@@ -610,6 +638,53 @@ _emit_svg_path (cairo_t *cr, char const *path)
}
}
+double
+lsm_svg_view_normalize_length (LsmSvgView *view, const LsmSvgLength *length, LsmSvgLengthDirection direction)
+{
+ double font_size;
+
+ g_return_val_if_fail (LSM_IS_SVG_VIEW (view), 0.0);
+
+ /* TODO cache font size */
+ if (view->text_stack != NULL && view->viewbox_stack != NULL) {
+ LsmSvgTextAttributeBag *text;
+
+ text = view->text_stack->data;
+ font_size = lsm_svg_length_normalize (&text->font_size.length, view->viewbox_stack->data,
+ 0.0, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ } else
+ font_size = 0.0;
+
+ 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_transform (LsmSvgView *view, const LsmSvgMatrix *matrix)
{
@@ -684,8 +759,13 @@ lsm_svg_view_pop_text_attributes (LsmSvgView *view)
view->text_stack = g_slist_delete_link (view->text_stack, view->text_stack);
}
+typedef enum {
+ LSM_SVG_VIEW_PAINT_OPERATION_FILL,
+ LSM_SVG_VIEW_PAINT_OPERATION_STROKE
+} LsmSvgViewPaintOperation;
+
static void
-_paint_uri (LsmSvgView *view, const char *uri)
+_paint_uri (LsmSvgView *view, LsmSvgViewPaintOperation operation, const char *uri)
{
cairo_t *cairo;
LsmDomElement *element;
@@ -710,18 +790,22 @@ _paint_uri (LsmSvgView *view, const char *uri)
g_free (filename);
#endif
- if (view->pattern_data->units == LSM_SVG_GRADIENT_UNITS_OBJECT_BOUNDING_BOX) {
+ if (LSM_IS_SVG_GRADIENT_ELEMENT (element) &&
+ view->pattern_data->units == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX) {
cairo_matrix_t matrix;
- double x1, x2, y1, y2;
- cairo_path_extents (cairo, &x1, &y1, &x2, &y2);
- if (x2 <= x1 || y2 <= y1) {
+ if (view->pattern_data->extents.width <= 0.0 ||
+ view->pattern_data->extents.height <= 0.0) {
_end_pattern (view);
return;
}
- cairo_matrix_init_scale (&matrix, 1.0 / (x2 - x1), 1.0 / (y2 - y1));
- cairo_matrix_translate (&matrix, -x1, -y1);
+ cairo_matrix_init_scale (&matrix,
+ 1.0 / view->pattern_data->extents.width,
+ 1.0 / view->pattern_data->extents.height);
+ cairo_matrix_translate (&matrix,
+ -view->pattern_data->extents.x,
+ -view->pattern_data->extents.y);
cairo_matrix_multiply (&matrix, &view->pattern_data->matrix, &matrix);
cairo_pattern_set_matrix (view->pattern_data->pattern, &matrix);
@@ -747,7 +831,8 @@ _paint_uri (LsmSvgView *view, const char *uri)
}
static gboolean
-_set_color (LsmSvgView *view, const LsmSvgPaint *paint, double opacity)
+_set_color (LsmSvgView *view, LsmSvgViewPaintOperation operation,
+ const LsmSvgPaint *paint, double opacity)
{
cairo_t *cairo = view->dom_view.cairo;
@@ -765,7 +850,7 @@ _set_color (LsmSvgView *view, const LsmSvgPaint *paint, double opacity)
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, paint->uri);
+ _paint_uri (view, operation, paint->uri);
break;
default:
return FALSE;
@@ -788,13 +873,17 @@ _paint (LsmSvgView *view)
fill = view->fill_stack->data;
stroke = view->stroke_stack->data;
- if (_set_color (view, &fill->paint.paint, fill->opacity.value)) {
+ if (_set_color (view, LSM_SVG_VIEW_PAINT_OPERATION_FILL,
+ &fill->paint.paint, fill->opacity.value)) {
cairo_set_fill_rule (cairo, fill->rule.value == LSM_SVG_FILL_RULE_EVEN_ODD ?
CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
cairo_fill_preserve (cairo);
}
- if (_set_color (view, &stroke->paint.paint, stroke->opacity.value)) {
+ if (_set_color (view, LSM_SVG_VIEW_PAINT_OPERATION_STROKE,
+ &stroke->paint.paint, stroke->opacity.value)) {
+ double line_width;
+
switch (stroke->line_join.value) {
case LSM_SVG_LINE_JOIN_MITER:
cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
@@ -817,15 +906,23 @@ _paint (LsmSvgView *view)
cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE);
}
+ line_width = lsm_svg_view_normalize_length (view, &stroke->width.length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+
cairo_set_miter_limit (cairo, stroke->miter_limit.value);
- cairo_set_line_width (cairo, stroke->width.length.value);
+ cairo_set_line_width (cairo, line_width);
+
+ if (stroke->dash_array.value != NULL) {
+ double dash_offset;
+
+ dash_offset = lsm_svg_view_normalize_length (view, &stroke->dash_offset.length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- if (stroke->dash_array.value != NULL)
cairo_set_dash (cairo,
stroke->dash_array.value->dashes,
stroke->dash_array.value->n_dashes,
- stroke->dash_offset.length.value);
- else
+ dash_offset);
+ } else
cairo_set_dash (cairo, NULL, 0, 0.0);
cairo_stroke (cairo);
@@ -986,6 +1083,7 @@ lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y
PangoLayoutIter *iter;
PangoRectangle ink_rect;
LsmSvgTextAttributeBag *text;
+ double font_size;
int baseline;
if (string == NULL)
@@ -999,8 +1097,10 @@ lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y
pango_layout = view->dom_view.pango_layout;
font_description = view->dom_view.font_description;
+ font_size = lsm_svg_view_normalize_length (view, &text->font_size.length, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+
pango_font_description_set_family (font_description, text->font_family.value);
- pango_font_description_set_size (font_description, text->font_size.length.value * PANGO_SCALE);
+ pango_font_description_set_size (font_description, font_size * PANGO_SCALE);
pango_layout_set_text (pango_layout, string, -1);
pango_layout_set_font_description (pango_layout, font_description);
@@ -1064,12 +1164,20 @@ lsm_svg_view_render (LsmDomView *view)
lsm_svg_svg_element_update (svg_element);
+ svg_view->viewbox_stack = NULL;
svg_view->fill_stack = NULL;
svg_view->stroke_stack = NULL;
svg_view->text_stack = NULL;
- lsm_svg_element_render (LSM_SVG_ELEMENT (svg_element), LSM_SVG_VIEW (view));
+ svg_view->resolution_ppi = lsm_dom_document_get_resolution (view->document);
+
+ lsm_svg_svg_element_render (svg_element, svg_view);
+ if (svg_view->viewbox_stack != NULL) {
+ g_warning ("[LsmSvgView::render] Dangling viewport in stack");
+ g_slist_free (svg_view->viewbox_stack);
+ svg_view->viewbox_stack = NULL;
+ }
if (svg_view->fill_stack != NULL) {
g_warning ("[LsmSvgView::render] Dangling fill attribute in stack");
g_slist_free (svg_view->fill_stack);
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index f3110be..3207f36 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -43,6 +43,9 @@ typedef struct _GSvgViewPatternData LsmSvgViewPatternData;
struct _GSvgView {
LsmDomView dom_view;
+ double resolution_ppi;
+
+ GSList *viewbox_stack;
GSList *fill_stack;
GSList *stroke_stack;
GSList *text_stack;
@@ -60,6 +63,8 @@ GType lsm_svg_view_get_type (void);
LsmSvgView * lsm_svg_view_new (LsmSvgDocument *document);
+LsmBox lsm_svg_view_get_extents (LsmSvgView *view);
+
void lsm_svg_view_create_radial_gradient (LsmSvgView *view, double cx, double cy,
double r, double fx, double fy);
void lsm_svg_view_create_linear_gradient (LsmSvgView *view, double x1, double y1,
@@ -68,14 +73,18 @@ void lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset,
const LsmSvgColor *color, double opacity);
void lsm_svg_view_set_gradient_properties (LsmSvgView *view,
LsmSvgSpreadMethod method,
- LsmSvgGradientUnits units,
+ LsmSvgPatternUnits units,
const LsmSvgMatrix *matrix);
void lsm_svg_view_create_surface_pattern (LsmSvgView *view, double width, double height,
- LsmSvgGradientUnits units,
- LsmSvgGradientUnits content_units,
+ LsmSvgPatternUnits units,
+ LsmSvgPatternUnits content_units,
const LsmSvgMatrix *matrix);
+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_transform (LsmSvgView *view, const LsmSvgMatrix *matrix);
void lsm_svg_view_pop_transform (LsmSvgView *view);
void lsm_svg_view_push_fill_attributes (LsmSvgView *view, LsmSvgFillAttributeBag *fill);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]