[lasem] [SVG] A first try at handling viewport correctly.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [lasem] [SVG] A first try at handling viewport correctly.
- Date: Fri, 8 May 2009 13:32:00 -0400 (EDT)
commit 9e48a6eb91d6727458b8de84fb3f1311b8b7817a
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Fri May 8 18:05:24 2009 +0200
[SVG] A first try at handling viewport correctly.
There's still some issues with gradients and pattern, when units are
the object bounding box.
---
src/lasemrender.c | 26 ++++++---
src/lasemtest.c | 19 ++++---
src/lsmdomattributes.c | 2 -
src/lsmdomdocument.c | 51 ++++++++++++++++
src/lsmdomdocument.h | 30 +++++++---
src/lsmdomview.c | 53 ++++++++++++++---
src/lsmdomview.h | 9 ++-
src/lsmmathmlview.c | 8 +--
src/lsmsvg.h | 2 +-
src/lsmsvgattributebags.c | 12 ++--
src/lsmsvgattributes.c | 118 ++++++++++++++++++++++++-------------
src/lsmsvgattributes.h | 20 +++++--
src/lsmsvgcircleelement.c | 9 ++-
src/lsmsvgellipseelement.c | 12 +++-
src/lsmsvgenums.h | 6 ++
src/lsmsvggradientelement.c | 12 +++-
src/lsmsvggraphic.c | 20 ++++---
src/lsmsvglineargradientelement.c | 28 +++++----
src/lsmsvglineelement.c | 12 +++-
src/lsmsvgpatternelement.c | 12 +++-
src/lsmsvgradialgradientelement.c | 41 +++++++------
src/lsmsvgrectelement.c | 18 ++++--
src/lsmsvgstopelement.c | 3 +-
src/lsmsvgstyle.h | 15 ++++-
src/lsmsvgsvgelement.c | 100 ++++++++++++++++++++++++-------
src/lsmsvgtextelement.c | 6 +-
src/lsmsvguseelement.c | 12 +++-
src/lsmsvgview.c | 2 +-
28 files changed, 464 insertions(+), 194 deletions(-)
diff --git a/src/lasemrender.c b/src/lasemrender.c
index 9b3b21a..af70dda 100644
--- a/src/lasemrender.c
+++ b/src/lasemrender.c
@@ -92,7 +92,8 @@ int main(int argc, char **argv)
char *mime;
char *buffer = NULL;
size_t size;
- double height, width;
+ double height_pt, width_pt;
+ unsigned int height, width;
gboolean success;
g_type_init ();
@@ -186,28 +187,37 @@ int main(int argc, char **argv)
if (mathml != NULL) {
document = lsm_dom_document_new_from_memory (mathml);
+ lsm_dom_document_set_resolution (document, option_ppi);
+
if (document != NULL) {
view = lsm_dom_document_create_view (document);
lsm_dom_view_set_debug (view, option_debug);
- lsm_dom_view_measure (view, &width, &height);
+ width_pt = 2.0;
+ height_pt = 2.0;
+
+ lsm_dom_view_get_size (view, &width_pt, &height_pt);
+ lsm_dom_view_get_size_px (view, &width, &height);
switch (format) {
case FORMAT_PDF:
- surface = cairo_pdf_surface_create (output_filename, width, height);
+ surface = cairo_pdf_surface_create (output_filename,
+ width_pt, height_pt);
break;
case FORMAT_PS:
- surface = cairo_ps_surface_create (output_filename, width, height);
+ surface = cairo_ps_surface_create (output_filename,
+ width_pt, height_pt);
break;
case FORMAT_PNG:
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- width * option_ppi / 72.0 + 0.5,
- height * option_ppi / 72.0 + 0.5);
+ width,
+ height);
break;
case FORMAT_SVG:
default:
- surface = cairo_svg_surface_create (output_filename, width, height);
+ surface = cairo_svg_surface_create (output_filename,
+ width_pt, height_pt);
break;
}
@@ -236,7 +246,7 @@ int main(int argc, char **argv)
g_object_unref (document);
- lsm_debug ("width = %g pt, height = %g pt", width, height);
+ lsm_debug ("width = %g pt, height = %g pt", width_pt, height_pt);
} else
g_warning ("Can't load %s", input_filename);
} else
diff --git a/src/lasemtest.c b/src/lasemtest.c
index 122d4b2..dd8da14 100644
--- a/src/lasemtest.c
+++ b/src/lasemtest.c
@@ -39,7 +39,6 @@
#include <../itex2mml/itex2MML.h>
-#define TEST_WIDTH 480
#define XML_FILENAME "lasemtest.xml"
static const char *fail_face = "", *normal_face = "";
@@ -71,7 +70,7 @@ lasem_test_render (char const *filename)
char *reference_png_filename;
char *test_name;
char *mime;
- double width, height;
+ unsigned int width, height;
gboolean is_xml, success;
gboolean is_svg;
gboolean is_mathml;
@@ -106,9 +105,11 @@ lasem_test_render (char const *filename)
view = lsm_dom_document_create_view (document);
- lsm_dom_view_measure (LSM_DOM_VIEW (view), &width, &height);
+ lsm_dom_document_set_viewport_px (document, 480.0, 360.0);
+ lsm_dom_document_set_resolution (document, 96.0);
+ lsm_dom_view_get_size_px (LSM_DOM_VIEW (view), &width, &height);
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width + 2.5, height + 2.5);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width + 2, height + 2);
cairo = cairo_create (surface);
cairo_surface_destroy (surface);
@@ -125,6 +126,11 @@ lasem_test_render (char const *filename)
lasem_test_html ("<table border=\"1\" cellpadding=\"8\">\n");
lasem_test_html ("<tr>");
+
+ lasem_test_html ("<td><a href=\"%s\"><img border=\"0\" src=\"%s\"/></a></td>",
+ filename, png_filename);
+ lasem_test_html ("<td><img src=\"%s\"/></td>", reference_png_filename);
+
lasem_test_html ("<td>");
if (is_mathml) {
@@ -145,13 +151,10 @@ lasem_test_render (char const *filename)
if (is_svg) {
lasem_test_html ("<object type=\"image/svg+xml\" data=\"");
lasem_test_html (filename);
- lasem_test_html ("\" width=\"320\"/>");
+ lasem_test_html ("\" width=\"480\"/>");
}
lasem_test_html ("</td>");
- lasem_test_html ("<td><a href=\"%s\"><img border=\"0\" src=\"%s\"/></a></td>",
- filename, png_filename);
- lasem_test_html ("<td><img src=\"%s\"/></td>", reference_png_filename);
lasem_test_html ("</tr>\n");
lasem_test_html ("</table>\n");
diff --git a/src/lsmdomattributes.c b/src/lsmdomattributes.c
index a871c1d..3898164 100644
--- a/src/lsmdomattributes.c
+++ b/src/lsmdomattributes.c
@@ -106,8 +106,6 @@ lsm_dom_attribute_map_add_bag_attribute (LsmDomAttributeMap *map,
attribute_infos->attribute_offset = attribute_offset;
attribute_infos->attribute_class = attribute_class;
- lsm_debug ("name = %s - attribute_offset = %d", name, attribute_offset);
-
g_hash_table_insert (map->attribute_hash, (char *) name, attribute_infos);
if (bag_class != NULL) {
diff --git a/src/lsmdomdocument.c b/src/lsmdomdocument.c
index d6e902a..d96a6ba 100644
--- a/src/lsmdomdocument.c
+++ b/src/lsmdomdocument.c
@@ -84,6 +84,54 @@ lsm_dom_document_create_view (LsmDomDocument *self)
return LSM_DOM_DOCUMENT_GET_CLASS (self)->create_view (self);
}
+double
+lsm_dom_document_get_resolution (LsmDomDocument *self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), 0.0);
+
+ return self->resolution_ppi;
+}
+
+void
+lsm_dom_document_set_resolution (LsmDomDocument *self, double ppi)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ if (ppi < 0.0)
+ self->resolution_ppi = LSM_DOM_DOCUMENT_DEFAULT_RESOLUTION;
+ else
+ self->resolution_ppi = ppi;
+}
+
+void
+lsm_dom_document_set_viewport (LsmDomDocument *self, double width, double height)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ self->viewport_width = width;
+ self->viewport_height = height;
+}
+
+void
+lsm_dom_document_set_viewport_px (LsmDomDocument *self, double width, double height)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ self->viewport_width = width * 72.0 / self->resolution_ppi;
+ self->viewport_height = height * 72.0 / self->resolution_ppi;
+}
+
+void
+lsm_dom_document_get_viewport (LsmDomDocument *self, double *width, double *height)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ if (width != NULL)
+ *width = self->viewport_width;
+ if (height != NULL)
+ *height = self->viewport_height;
+}
+
LsmDomElement *
lsm_dom_document_get_element_by_id (LsmDomDocument *self, const char *id)
{
@@ -125,6 +173,9 @@ 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;
}
static void
diff --git a/src/lsmdomdocument.h b/src/lsmdomdocument.h
index 64cb5a8..1ef081b 100644
--- a/src/lsmdomdocument.h
+++ b/src/lsmdomdocument.h
@@ -29,6 +29,10 @@
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_TYPE_DOM_DOCUMENT (lsm_dom_document_get_type ())
#define LSM_DOM_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_DOCUMENT, LsmDomDocument))
#define LSM_DOM_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_DOCUMENT, LsmDomDocumentClass))
@@ -43,28 +47,38 @@ struct _GDomDocument {
GHashTable * ids;
GHashTable * elements;
+
+ /* Not really a document property, but that simplifies things greatly */
+ double resolution_ppi;
+ double viewport_width;
+ double viewport_height;
};
struct _GDomDocumentClass {
LsmDomNodeClass parent_class;
- LsmDomElement * (*get_document_element) (LsmDomDocument* self);
- LsmDomElement * (*create_element) (LsmDomDocument* self, const char *tag_name);
- LsmDomText * (*create_text_node) (LsmDomDocument* self, const char *data);
+ LsmDomElement * (*get_document_element) (LsmDomDocument* self);
+ LsmDomElement * (*create_element) (LsmDomDocument* self, const char *tag_name);
+ LsmDomText * (*create_text_node) (LsmDomDocument* self, const char *data);
- LsmDomView* (*create_view) (LsmDomDocument *self);
+ LsmDomView* (*create_view) (LsmDomDocument *self);
};
GType lsm_dom_document_get_type (void);
LsmDomElement* lsm_dom_document_get_document_element (LsmDomDocument* self);
-LsmDomElement* lsm_dom_document_create_element (LsmDomDocument* self, const char *tag_name);
-LsmDomText* lsm_dom_document_create_text_node (LsmDomDocument* self, const char *data);
-LsmDomElement * lsm_dom_document_get_element_by_id (LsmDomDocument *self, const char *id);
+LsmDomElement* lsm_dom_document_create_element (LsmDomDocument* self, const char *tag_name);
+LsmDomText* lsm_dom_document_create_text_node (LsmDomDocument* self, const char *data);
+LsmDomElement * lsm_dom_document_get_element_by_id (LsmDomDocument *self, const char *id);
-void lsm_dom_document_register_element (LsmDomDocument *self, LsmDomElement *element, const char *id);
+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);
G_END_DECLS
diff --git a/src/lsmdomview.c b/src/lsmdomview.c
index a524dbf..2a80075 100644
--- a/src/lsmdomview.c
+++ b/src/lsmdomview.c
@@ -26,16 +26,19 @@
static GObjectClass *parent_class;
void
-lsm_dom_view_measure (LsmDomView *view, double *width, double *height)
+lsm_dom_view_get_size (LsmDomView *view, double *width, double *height)
{
LsmDomViewClass *view_class;
-
- if (width != NULL)
- *width = 0.0;
- if (height != NULL)
- *height = 0.0;
+ double dummy_width = 0.0;
+ double dummy_height = 0.0;
g_return_if_fail (LSM_IS_DOM_VIEW (view));
+ g_return_if_fail (view->document != NULL);
+
+ if (width == NULL)
+ width = &dummy_width;
+ if (height == NULL)
+ height = &dummy_height;
view_class = LSM_DOM_VIEW_GET_CLASS (view);
if (view_class->measure != NULL)
@@ -43,16 +46,50 @@ lsm_dom_view_measure (LsmDomView *view, double *width, double *height)
}
void
+lsm_dom_view_get_size_px (LsmDomView *view, unsigned int *width, unsigned int *height)
+{
+ double resolution_ppi;
+ double width_pt;
+ double height_pt;
+
+ g_return_if_fail (LSM_IS_DOM_VIEW (view));
+ g_return_if_fail (view->document != NULL);
+
+ resolution_ppi = lsm_dom_document_get_resolution (view->document);
+ g_return_if_fail (resolution_ppi > 0.0);
+
+ width_pt = width != NULL ? *width * 72.0 / resolution_ppi : 0.0;
+ height_pt = height != NULL ? *height * 72.0 / resolution_ppi : 0.0;
+
+ lsm_dom_view_get_size (view, &width_pt, &height_pt);
+
+ if (width != NULL)
+ *width = (double) (0.5 + width_pt * resolution_ppi / 72.0);
+ if (height != NULL)
+ *height = (double) (0.5 + height_pt * resolution_ppi / 72.0);
+}
+
+void
lsm_dom_view_render (LsmDomView *view, double x, double y)
{
LsmDomViewClass *view_class;
+ double resolution_ppi;
g_return_if_fail (LSM_IS_DOM_VIEW (view));
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (view->document));
g_return_if_fail (view->cairo != NULL);
+ resolution_ppi = lsm_dom_document_get_resolution (view->document);
+
+ cairo_save (view->cairo);
+
+ cairo_translate (view->cairo, x, y);
+
view_class = LSM_DOM_VIEW_GET_CLASS (view);
- if (view_class->measure != NULL)
- view_class->render (view, x, y);
+ if (view_class->render != NULL)
+ view_class->render (view);
+
+ cairo_restore (view->cairo);
}
void
diff --git a/src/lsmdomview.h b/src/lsmdomview.h
index 1aab9e3..dce3d6f 100644
--- a/src/lsmdomview.h
+++ b/src/lsmdomview.h
@@ -56,16 +56,17 @@ struct _GDomViewClass {
GType document_type;
- void (*measure) (LsmDomView *view, double *width, double *height);
- void (*render) (LsmDomView *view, double x, double y);
+ void (*measure) (LsmDomView *view, double *width, double *height);
+ void (*render) (LsmDomView *view);
};
GType lsm_dom_view_get_type (void);
void lsm_dom_view_render (LsmDomView *view, double x, double y);
-void lsm_dom_view_measure (LsmDomView *view, double *width, double *height);
+void lsm_dom_view_get_size (LsmDomView *view, double *width, double *height);
+void lsm_dom_view_get_size_px (LsmDomView *view, unsigned int *width, unsigned int *height);
-void lsm_dom_view_set_document (LsmDomView *view, LsmDomDocument *document);
+void lsm_dom_view_set_document (LsmDomView *view, LsmDomDocument *document);
void lsm_dom_view_set_cairo (LsmDomView *view, cairo_t *cr);
void lsm_dom_view_set_debug (LsmDomView *view, gboolean debug);
diff --git a/src/lsmmathmlview.c b/src/lsmmathmlview.c
index e94c443..a606977 100644
--- a/src/lsmmathmlview.c
+++ b/src/lsmmathmlview.c
@@ -960,7 +960,7 @@ lsm_mathml_view_measure (LsmDomView *dom_view, double *width, double *height)
}
static void
-lsm_mathml_view_render (LsmDomView *dom_view, double x, double y)
+lsm_mathml_view_render (LsmDomView *dom_view)
{
LsmMathmlView *view = LSM_MATHML_VIEW (dom_view);
LsmMathmlMathElement *math_element;
@@ -977,15 +977,11 @@ lsm_mathml_view_render (LsmDomView *dom_view, double x, double y)
cairo = view->dom_view.cairo;
- cairo_save (view->dom_view.cairo);
-
- cairo_translate (cairo, x, y + bbox->height);
+ cairo_translate (cairo, 0, bbox->height);
lsm_mathml_math_element_render (math_element, view);
lsm_debug ("[LsmMathmlView::render] cairo status = %s", cairo_status_to_string (cairo_status (cairo)));
-
- cairo_restore (cairo);
}
LsmMathmlView *
diff --git a/src/lsmsvg.h b/src/lsmsvg.h
index ee1f513..6bf6b06 100644
--- a/src/lsmsvg.h
+++ b/src/lsmsvg.h
@@ -49,7 +49,7 @@ typedef struct _GSvgStopElement LsmSvgStopElement;
typedef struct _GSvgPatternElement LsmSvgPatternElement;
typedef struct _GSvgView LsmSvgView;
-typedef struct _GSvgStyle LsmSvgStyle;
+typedef struct _LsmSvgStyle LsmSvgStyle;
G_END_DECLS
diff --git a/src/lsmsvgattributebags.c b/src/lsmsvgattributebags.c
index 1dec313..e1f2d15 100644
--- a/src/lsmsvgattributebags.c
+++ b/src/lsmsvgattributebags.c
@@ -184,14 +184,14 @@ void
lsm_dom_attribute_map_add_text_attribute_bag (LsmDomAttributeMap *map, ptrdiff_t bag_offset)
{
lsm_dom_attribute_map_add_bag_attribute (map, "font-family",
- offsetof (LsmSvgTextAttributeBag, font_family),
- &lsm_dom_string_attribute_class,
- bag_offset, &lsm_svg_text_attribute_bag_class);
+ offsetof (LsmSvgTextAttributeBag, font_family),
+ &lsm_dom_string_attribute_class,
+ bag_offset, &lsm_svg_text_attribute_bag_class);
lsm_dom_attribute_map_add_bag_attribute (map, "font-size",
- offsetof (LsmSvgTextAttributeBag, font_size),
- NULL,
- bag_offset, &lsm_svg_text_attribute_bag_class);
+ offsetof (LsmSvgTextAttributeBag, font_size),
+ NULL,
+ bag_offset, &lsm_svg_text_attribute_bag_class);
}
static void *
diff --git a/src/lsmsvgattributes.c b/src/lsmsvgattributes.c
index 99cce39..ba5e4a5 100644
--- a/src/lsmsvgattributes.c
+++ b/src/lsmsvgattributes.c
@@ -22,6 +22,7 @@
#include <lsmsvgattributes.h>
#include <lsmsvgcolors.h>
#include <lsmsvgutils.h>
+#include <lsmsvgstyle.h>
#include <lsmdebug.h>
#include <string.h>
#include <stdlib.h>
@@ -75,6 +76,19 @@ lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin)
return duplicate;
}
+static const char *
+lsm_svg_attribute_get_value (LsmDomAttribute *attribute)
+{
+ const char *string;
+
+ string = lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
+
+ if (g_strcmp0 (string, "inherit") == 0)
+ return NULL;
+
+ return string;
+}
+
const LsmSvgColor lsm_svg_color_null = {0.0, 0.0, 0.0};
void
@@ -86,10 +100,7 @@ lsm_svg_double_attribute_parse (LsmSvgDoubleAttribute *attribute,
g_return_if_fail (attribute != NULL);
g_return_if_fail (double_value != NULL);
- string = lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
-
- if (g_strcmp0 (string, "inherit") == 0)
- string = NULL;
+ string = lsm_svg_attribute_get_value ((LsmDomAttribute *) attribute);
if (string == NULL) {
attribute->value = *double_value;
@@ -101,40 +112,67 @@ lsm_svg_double_attribute_parse (LsmSvgDoubleAttribute *attribute,
}
static double
-lsm_svg_length_compute (const LsmSvgLength *length, double viewbox, double font_size)
+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;
+ return length->value_unit * viewport_scale;
case LSM_SVG_LENGTH_TYPE_PC:
- return length->value_unit * 72.0 / 6.0;
+ return length->value_unit * 72.0 * viewport_scale / 6.0;
case LSM_SVG_LENGTH_TYPE_CM:
- return length->value_unit * 72.0 / 2.54;
+ return length->value_unit * 72.0 * viewport_scale / 2.54;
case LSM_SVG_LENGTH_TYPE_MM:
- return length->value_unit * 72.0 / 25.4;
+ return length->value_unit * 72.0 * viewport_scale / 25.4;
case LSM_SVG_LENGTH_TYPE_IN:
- return length->value_unit * 72.0;
+ return length->value_unit * 72.0 * viewport_scale;
case LSM_SVG_LENGTH_TYPE_EMS:
- return length->value_unit * font_size;
+ return length->value_unit * style->text.font_size.value;
case LSM_SVG_LENGTH_TYPE_EXS:
- return length->value_unit * font_size * 0.5;
- case LSM_SVG_LENGTH_TYPE_PERCENTAGE:
- return viewbox * length->value_unit / 100.0;
- case LSM_SVG_LENGTH_TYPE_NUMBER:
- case LSM_SVG_LENGTH_TYPE_UNKNOWN:
- return length->value_unit;
+ 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,
- double font_size)
+ const LsmSvgStyle *style,
+ LsmSvgLengthDirection direction)
{
const char *string;
char *length_type_str;
@@ -142,6 +180,7 @@ lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
g_return_if_fail (attribute != NULL);
string = lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
+
if (string == NULL) {
g_return_if_fail (default_value != NULL);
@@ -149,8 +188,7 @@ 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,
- default_value->value, font_size);
+ attribute->length.value = lsm_svg_length_compute (&attribute->length, style, direction);
*default_value = attribute->length;
}
@@ -159,7 +197,8 @@ lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
void
lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
LsmSvgLength *default_value,
- double font_size)
+ const LsmSvgStyle *style,
+ LsmSvgLengthDirection direction)
{
const char *string;
char *length_type_str;
@@ -175,8 +214,7 @@ 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,
- default_value->value, font_size);
+ attribute->length.base.value = lsm_svg_length_compute (&attribute->length.base, style, direction);
attribute->length.animated = attribute->length.base;
*default_value = attribute->length.base;
@@ -196,15 +234,15 @@ lsm_svg_dash_array_attribute_finalize (void *abstract)
void
lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
- LsmSvgDashArray **default_value)
+ LsmSvgDashArray **default_value,
+ const LsmSvgStyle *style,
+ LsmSvgLengthDirection direction)
{
const char *string;
g_return_if_fail (attribute != NULL);
- string = lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
- if (g_strcmp0 (string, "inherit") == 0)
- string = NULL;
+ string = lsm_svg_attribute_get_value ((LsmDomAttribute *) attribute);
if (string == NULL) {
lsm_svg_dash_array_free (attribute->value);
@@ -236,8 +274,8 @@ 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,
- 0.0, 0.0);
+ attribute->value->dashes[i] =
+ lsm_svg_length_compute (&length, style, direction);
while (*iter != '\0' && *iter != ' ' && *iter != ',')
iter ++;
} else
@@ -395,7 +433,7 @@ lsm_svg_paint_attribute_parse (LsmSvgPaintAttribute *attribute,
g_return_if_fail (attribute != NULL);
- string = (char *) lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
+ string = (char *) lsm_svg_attribute_get_value ((LsmDomAttribute *) attribute);
if (string == NULL) {
g_free (attribute->paint.uri);
@@ -460,10 +498,7 @@ lsm_svg_color_attribute_parse (LsmSvgColorAttribute *attribute,
g_return_if_fail (attribute != NULL);
- string = (char *) lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
-
- if (g_strcmp0 (string, "inherit") == 0)
- string = NULL;
+ string = (char *) lsm_svg_attribute_get_value ((LsmDomAttribute *) attribute);
if (string == NULL) {
attribute->value = *default_value;
@@ -477,19 +512,15 @@ lsm_svg_color_attribute_parse (LsmSvgColorAttribute *attribute,
}
void
-lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute,
- LsmSvgViewBox *default_value)
+lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute)
{
char *string;
g_return_if_fail (attribute != NULL);
string = (char *) lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
- if (string == NULL) {
- g_return_if_fail (default_value != NULL);
- attribute->value = *default_value;
- } else {
+ if (string != NULL) {
unsigned int i;
double value[4];
@@ -511,8 +542,11 @@ lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute,
attribute->value.width = 0;
attribute->value.height = 0;
}
-
- *default_value = attribute->value;
+ } else {
+ attribute->value.x = 0;
+ attribute->value.y = 0;
+ attribute->value.width = 0;
+ attribute->value.height = 0;
}
}
diff --git a/src/lsmsvgattributes.h b/src/lsmsvgattributes.h
index ca66f49..9cc43eb 100644
--- a/src/lsmsvgattributes.h
+++ b/src/lsmsvgattributes.h
@@ -120,19 +120,27 @@ typedef struct {
LsmSvgMatrix matrix;
} LsmSvgTransformAttribute;
+
+/* Properties */
+
void lsm_svg_double_attribute_parse (LsmSvgDoubleAttribute *attribute,
double *double_value);
void lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
LsmSvgLength *default_value,
- double font_size);
+ const LsmSvgStyle *style,
+ LsmSvgLengthDirection direction);
void lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
LsmSvgLength *default_value,
- double font_size);
+ const LsmSvgStyle *style,
+ LsmSvgLengthDirection direction);
void lsm_svg_dash_array_attribute_finalize (void *abstract);
void lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
- LsmSvgDashArray **default_value);
+ LsmSvgDashArray **default_value,
+ const LsmSvgStyle *style,
+ LsmSvgLengthDirection direction);
+
void lsm_svg_fill_rule_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
void lsm_svg_line_join_attribute_parse (LsmDomEnumAttribute *attribute,
@@ -150,8 +158,10 @@ void lsm_svg_paint_attribute_parse (LsmSvgPaintAttribute *attribute,
void lsm_svg_color_attribute_parse (LsmSvgColorAttribute *attribute,
LsmSvgColor *default_value,
const LsmSvgColor *current_color);
-void lsm_svg_view_box_attribute_parse (LsmSvgViewBoxAttribute *attribute,
- LsmSvgViewBox *default_value);
+
+/* Attributes */
+
+void lsm_svg_view_box_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 07a3283..5ac5190 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -43,17 +43,20 @@ lsm_svg_circle_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&circle->cx, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&circle->cy, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&circle->r, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index 17f6c51..a26f37e 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -43,22 +43,26 @@ lsm_svg_ellipse_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&ellipse->cx, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&ellipse->cy, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&ellipse->rx, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&ellipse->ry, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgenums.h b/src/lsmsvgenums.h
index a061c39..fb42420 100644
--- a/src/lsmsvgenums.h
+++ b/src/lsmsvgenums.h
@@ -40,6 +40,12 @@ typedef enum {
} LsmSvgPaintType;
typedef enum {
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL
+} LsmSvgLengthDirection;
+
+typedef enum {
LSM_SVG_LENGTH_TYPE_UNKNOWN,
LSM_SVG_LENGTH_TYPE_NUMBER,
LSM_SVG_LENGTH_TYPE_PERCENTAGE,
diff --git a/src/lsmsvggradientelement.c b/src/lsmsvggradientelement.c
index 6b891f0..80d4802 100644
--- a/src/lsmsvggradientelement.c
+++ b/src/lsmsvggradientelement.c
@@ -51,6 +51,12 @@ _gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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);
}
@@ -87,9 +93,9 @@ _gradient_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
}
lsm_svg_view_set_gradient_properties (view,
- gradient->spread_method.value,
- gradient->units.value,
- &gradient->transform.matrix);
+ gradient->spread_method.value,
+ gradient->units.value,
+ &gradient->transform.matrix);
}
/* LsmSvgGradientElement implementation */
diff --git a/src/lsmsvggraphic.c b/src/lsmsvggraphic.c
index ffd771b..6f48b81 100644
--- a/src/lsmsvggraphic.c
+++ b/src/lsmsvggraphic.c
@@ -95,6 +95,12 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
default_opacity = 1.0;
lsm_svg_double_attribute_parse (&graphic->opacity, &default_opacity); /* FIXME handle inherit */
+ 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);
+ }
+
if (graphic->fill != NULL) {
lsm_debug ("[LsmSvgGraphic::update] fill");
@@ -109,24 +115,22 @@ 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, 0.0);
+ lsm_svg_length_attribute_parse (&graphic->stroke->width, &parent_style->stroke.width,
+ parent_style, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
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);
- lsm_svg_length_attribute_parse (&graphic->stroke->dash_offset, &parent_style->stroke.dash_offset, 0.0);
+ 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);
}
if (graphic->transform != NULL) {
lsm_svg_transform_attribute_parse (&graphic->transform->transform);
}
- 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, 0.0);
- }
-
if (graphic->stop != NULL) {
lsm_svg_color_attribute_parse (&graphic->stop->color,
&parent_style->stop.color,
diff --git a/src/lsmsvglineargradientelement.c b/src/lsmsvglineargradientelement.c
index 0cb5a7e..d454eb8 100644
--- a/src/lsmsvglineargradientelement.c
+++ b/src/lsmsvglineargradientelement.c
@@ -42,27 +42,31 @@ _linear_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgLinearGradientElement *linear = LSM_SVG_LINEAR_GRADIENT_ELEMENT (self);
LsmSvgLength length;
+ 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_NUMBER;
- lsm_svg_animated_length_attribute_parse (&linear->x1, &length, 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);
length.value = 0.0;
length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&linear->y1, &length, 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);
- length.value = 1.0;
- length.value_unit = 1.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&linear->x2, &length, 0.0);
+ 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);
length.value = 0.0;
length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&linear->y2, &length, 0.0);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
+ length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
+ lsm_svg_animated_length_attribute_parse (&linear->y2, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
}
static void
diff --git a/src/lsmsvglineelement.c b/src/lsmsvglineelement.c
index bbce4a6..14e7ee6 100644
--- a/src/lsmsvglineelement.c
+++ b/src/lsmsvglineelement.c
@@ -43,22 +43,26 @@ lsm_svg_line_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&line->x1, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&line->y1, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&line->x2, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&line->y2, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgpatternelement.c b/src/lsmsvgpatternelement.c
index 3e230a6..3c06ab2 100644
--- a/src/lsmsvgpatternelement.c
+++ b/src/lsmsvgpatternelement.c
@@ -54,22 +54,26 @@ _pattern_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&pattern->x, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&pattern->y, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&pattern->width, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&pattern->height, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgradialgradientelement.c b/src/lsmsvgradialgradientelement.c
index 1d5e8c1..5fec09e 100644
--- a/src/lsmsvgradialgradientelement.c
+++ b/src/lsmsvgradialgradientelement.c
@@ -42,32 +42,33 @@ _radial_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
LsmSvgRadialGradientElement *radial = LSM_SVG_RADIAL_GRADIENT_ELEMENT (self);
LsmSvgLength length;
- length.value = 0.5;
- length.value_unit = 0.5;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&radial->cx, &length, 0.0);
+ LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
- length.value = 0.5;
- length.value_unit = 0.5;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&radial->cy, &length, 0.0);
+ 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);
- length.value = 0.5;
- length.value_unit = 0.5;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&radial->r, &length, 0.0);
+ 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);
- length.value = 0.5;
- length.value_unit = 0.5;
+ length.value = 50.0;
+ length.value_unit = 50.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&radial->fx, &length, 0.0);
+ lsm_svg_animated_length_attribute_parse (&radial->r, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- length.value = 0.5;
- length.value_unit = 0.5;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&radial->fy, &length, 0.0);
+ length = radial->cx.length.base;
+ lsm_svg_animated_length_attribute_parse (&radial->fx, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
+ length = radial->cy.length.base;
+ lsm_svg_animated_length_attribute_parse (&radial->fy, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
}
static void
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index 1055d44..fad65c7 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -43,32 +43,38 @@ lsm_svg_rect_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&rect->x, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&rect->y, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&rect->width, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&rect->height, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&rect->rx, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&rect->ry, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgstopelement.c b/src/lsmsvgstopelement.c
index 957b453..c9931f8 100644
--- a/src/lsmsvgstopelement.c
+++ b/src/lsmsvgstopelement.c
@@ -45,7 +45,8 @@ _stop_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
length.value = 1.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&stop->offset, &length, 0.0);
+ lsm_svg_length_attribute_parse (&stop->offset, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index ce8303d..85bfdcf 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -27,9 +27,20 @@
G_BEGIN_DECLS
-struct _GSvgStyle {
+struct _LsmSvgStyle {
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;
@@ -59,7 +70,7 @@ struct _GSvgStyle {
};
LsmSvgStyle * lsm_svg_style_new (void);
-void lsm_svg_style_free (LsmSvgStyle *style);
+void lsm_svg_style_free (LsmSvgStyle *style);
LsmSvgStyle * lsm_svg_style_duplicate (const LsmSvgStyle *style);
G_END_DECLS
diff --git a/src/lsmsvgsvgelement.c b/src/lsmsvgsvgelement.c
index 61ed0d8..703dd53 100644
--- a/src/lsmsvgsvgelement.c
+++ b/src/lsmsvgsvgelement.c
@@ -23,6 +23,8 @@
#include <lsmsvgstyle.h>
#include <lsmsvgview.h>
#include <lsmdebug.h>
+#include <lsmdomdocument.h>
+#include <math.h>
#include <stdio.h>
static GObjectClass *parent_class;
@@ -42,31 +44,40 @@ _svg_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
{
LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
LsmSvgLength length;
- LsmSvgViewBox view_box = {0,0,0,0};
- lsm_svg_view_box_attribute_parse (&svg->view_box, &view_box);
-
- length.value = svg->view_box.value.x;
- length.value_unit = svg->view_box.value.x;
+ length.value = 0.0;
+ length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->x, &length, 0.0);
+ lsm_svg_length_attribute_parse (&svg->x, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- length.value = svg->view_box.value.y;
- length.value_unit = svg->view_box.value.y;
+ length.value = 0.0;
+ length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->y, &length, 0.0);
+ lsm_svg_length_attribute_parse (&svg->y, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- length.value = svg->view_box.value.width;
- length.value_unit = svg->view_box.value.width;
+ length.value = 0.0;
+ length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->width, &length, 0.0);
+ lsm_svg_length_attribute_parse (&svg->width, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- length.value = svg->view_box.value.height;
- length.value_unit = svg->view_box.value.height;
+ length.value = 0.0;
+ length.value_unit = 0.0;
length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->height, &length, 0.0);
+ lsm_svg_length_attribute_parse (&svg->height, &length, parent_style, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ 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);
- lsm_debug ("[LsmSvgSvgElement::update] height = %g, width = %g",
+ 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);
@@ -76,18 +87,44 @@ _svg_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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);
+
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
void
lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *height)
{
+ LsmDomDocument *document;
+ double resolution_ppi;
+
g_return_if_fail (LSM_IS_SVG_SVG_ELEMENT (self));
+ document = LSM_DOM_DOCUMENT (LSM_DOM_NODE (self)->parent_node);
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (document));
+
+ resolution_ppi = lsm_dom_document_get_resolution (document);
+
if (width != NULL)
- *width = self->width.length.value;
+ *width = self->width.length.value * 72.0 / resolution_ppi;
if (height != NULL)
- *height = self->height.length.value;
+ *height = self->height.length.value * 72.0 / resolution_ppi;
}
/* LsmSvgGraphic implementation */
@@ -103,10 +140,11 @@ lsm_svg_svg_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
return;
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);
+ svg->width.length.value / svg->view_box.value.width,
+ 0, 0,
+ svg->height.length.value / svg->view_box.value.height,
+ 0, 0);
+
lsm_svg_view_push_transform (view, &matrix);
LSM_SVG_GRAPHIC_CLASS (parent_class)->graphic_render (self, view);
@@ -127,6 +165,24 @@ lsm_svg_svg_element_get_default_style (LsmSvgSvgElement *svg_element)
void
lsm_svg_svg_element_update (LsmSvgSvgElement *svg_element)
{
+ LsmDomDocument *document;
+ LsmSvgStyle *style;
+
+ g_return_if_fail (LSM_IS_SVG_SVG_ELEMENT (svg_element));
+
+ document = LSM_DOM_DOCUMENT (LSM_DOM_NODE (svg_element)->parent_node);
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (document));
+
+ 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;
+
lsm_svg_element_update (LSM_SVG_ELEMENT (svg_element),
lsm_svg_svg_element_get_default_style (svg_element));
}
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index 83a3196..9209afc 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -50,12 +50,14 @@ lsm_svg_text_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&text->x, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&text->y, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvguseelement.c b/src/lsmsvguseelement.c
index c884ccb..7c83ab2 100644
--- a/src/lsmsvguseelement.c
+++ b/src/lsmsvguseelement.c
@@ -52,22 +52,26 @@ lsm_svg_use_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&use_element->x, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&use_element->y, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&use_element->width, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
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, 0.0);
+ lsm_svg_animated_length_attribute_parse (&use_element->height, &length, parent_style,
+ LSM_SVG_LENGTH_DIRECTION_VERTICAL);
LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
}
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 1e05a20..d96e974 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -1051,7 +1051,7 @@ lsm_svg_view_measure (LsmDomView *view, double *width, double *height)
}
static void
-lsm_svg_view_render (LsmDomView *view, double x, double y)
+lsm_svg_view_render (LsmDomView *view)
{
LsmSvgView *svg_view;
LsmSvgSvgElement *svg_element;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]