[lasem] Rework of property handling. Use for SVG.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [lasem] Rework of property handling. Use for SVG.
- Date: Fri, 7 Aug 2009 09:40:37 +0000 (UTC)
commit c417ea79a4a791e2ab441da714a8b1ac854e0805
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Fri Aug 7 11:37:17 2009 +0200
Rework of property handling. Use for SVG.
.gitignore | 1 +
src/Makefile.am | 51 ++--
src/lasemrender.c | 150 +++------
src/lasemtest.c | 7 +-
src/lsmdom.h | 17 +-
src/lsmdomdocument.c | 81 +++++
src/lsmdomdocument.h | 12 +-
src/lsmdomnode.h | 24 +-
src/lsmdomparser.c | 134 +++++++-
src/lsmdomparser.h | 9 +-
src/lsmdomview.c | 3 +
src/lsmmathmldocument.c | 2 +
src/lsmmathmldocument.h | 2 +
src/lsmmathmlmathelement.c | 2 +
src/lsmmathmltableelement.c | 2 +
src/lsmsvgattributebags.c | 272 ---------------
src/lsmsvgattributebags.h | 77 -----
src/lsmsvgattributes.c | 659 ------------------------------------
src/lsmsvgattributes.h | 105 ++-----
src/lsmsvgcircleelement.c | 77 +++---
src/lsmsvgcircleelement.h | 12 +-
src/lsmsvgclippathelement.c | 70 +++--
src/lsmsvgclippathelement.h | 10 +-
src/lsmsvgdefselement.c | 2 +-
src/lsmsvgdefselement.h | 6 +-
src/lsmsvgdocument.h | 2 +-
src/lsmsvgelement.c | 199 +++++++-----
src/lsmsvgelement.h | 21 +-
src/lsmsvgellipseelement.c | 90 +++---
src/lsmsvgellipseelement.h | 14 +-
src/lsmsvgenums.c | 2 +-
src/lsmsvggelement.c | 5 +-
src/lsmsvggelement.h | 6 +-
src/lsmsvggradientelement.c | 115 ++++----
src/lsmsvggradientelement.h | 16 +-
src/lsmsvggraphic.c | 296 ----------------
src/lsmsvggraphic.h | 67 ----
src/lsmsvgimageelement.c | 181 ++++++-----
src/lsmsvgimageelement.h | 16 +-
src/lsmsvglineargradientelement.c | 90 +++---
src/lsmsvglineargradientelement.h | 8 +-
src/lsmsvglineelement.c | 91 +++---
src/lsmsvglineelement.h | 14 +-
src/lsmsvgmaskelement.c | 153 +++++----
src/lsmsvgmaskelement.h | 22 +-
src/lsmsvgmatrix.c | 25 ++
src/lsmsvgmatrix.h | 7 +
src/lsmsvgpathelement.c | 28 +-
src/lsmsvgpathelement.h | 10 +-
src/lsmsvgpatternelement.c | 200 +++++++-----
src/lsmsvgpatternelement.h | 22 +-
src/lsmsvgpolygonelement.c | 23 +-
src/lsmsvgpolygonelement.h | 8 +-
src/lsmsvgpolylineelement.c | 23 +-
src/lsmsvgpolylineelement.h | 8 +-
src/lsmsvgradialgradientelement.c | 117 ++++---
src/lsmsvgradialgradientelement.h | 10 +-
src/lsmsvgrectelement.c | 139 ++++----
src/lsmsvgrectelement.h | 20 +-
src/lsmsvgstopelement.c | 70 ++---
src/lsmsvgstopelement.h | 10 +-
src/lsmsvgstyle.c | 463 +++++++++++++++++++++++++-
src/lsmsvgstyle.h | 162 +++++++---
src/lsmsvgsvgelement.c | 205 +++++-------
src/lsmsvgsvgelement.h | 10 +-
src/lsmsvgsymbolelement.c | 13 +-
src/lsmsvgsymbolelement.h | 6 +-
src/lsmsvgtextelement.c | 70 ++--
src/lsmsvgtextelement.h | 10 +-
src/lsmsvgtraits.c | 666 +++++++++++++++++++++++++++++++++++++
src/lsmsvgtraits.h | 77 +++++
src/lsmsvguseelement.c | 104 +++---
src/lsmsvguseelement.h | 16 +-
src/lsmsvgutils.c | 132 --------
src/lsmsvgutils.h | 70 ----
src/lsmsvgview.c | 443 +++++++++++--------------
src/lsmsvgview.h | 26 +-
test/.gitignore | 1 -
78 files changed, 3125 insertions(+), 3264 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index ba0eeca..1832f85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,4 +24,5 @@ tags
*.swp
lasem.svg
lasem.pc
+lasemtest.xml
manugen
diff --git a/src/Makefile.am b/src/Makefile.am
index dc76bd8..0d989f6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,7 +7,8 @@ INCLUDES = \
AM_CFLAGS =\
-Wall\
-Werror \
- -g
+ -g \
+ -O0
lib_LTLIBRARIES = liblasem.la
@@ -17,6 +18,10 @@ liblasem_la_LIBADD = \
liblasem_la_SOURCES = \
lsmdebug.c \
+ lsmstr.c \
+ lsmtraits.c \
+ lsmproperties.c \
+ lsmattributes.c \
lsmdomnode.c \
lsmdomnodelist.c \
lsmdomdocument.c \
@@ -60,9 +65,15 @@ liblasem_la_SOURCES = \
lsmmathmlaligngroupelement.c \
lsmmathmlutils.c \
lsmmathmllayoututils.c \
+ lsmsvgenums.c \
+ lsmsvgtraits.c \
+ lsmsvgstyle.c \
+ lsmsvgcolors.c \
+ lsmsvglength.c \
+ lsmsvgview.c \
+ lsmsvgmatrix.c \
lsmsvgdocument.c \
lsmsvgelement.c \
- lsmsvggraphic.c \
lsmsvgclippathelement.c \
lsmsvgsvgelement.c \
lsmsvguseelement.c \
@@ -83,20 +94,16 @@ liblasem_la_SOURCES = \
lsmsvgradialgradientelement.c \
lsmsvgstopelement.c \
lsmsvgpatternelement.c \
- lsmsvgmaskelement.c \
- lsmsvgenums.c \
- lsmsvgattributes.c \
- lsmsvgattributebags.c \
- lsmsvgstyle.c \
- lsmsvgcolors.c \
- lsmsvglength.c \
- lsmsvgutils.c \
- lsmsvgview.c \
- lsmsvgmatrix.c
+ lsmsvgmaskelement.c
liblasem_ladir = $(includedir)/lasem
liblasem_la_HEADERS = \
+ lsm.h \
+ lsmstr.h \
lsmdebug.h \
+ lsmtraits.h \
+ lsmproperties.h \
+ lsmattributes.h \
lsmdom.h \
lsmdomnode.h \
lsmdomnodelist.h \
@@ -143,9 +150,16 @@ liblasem_la_HEADERS = \
lsmmathmlutils.h \
lsmmathmllayoututils.h \
lsmsvg.h \
+ lsmsvgenums.h \
+ lsmsvgtraits.h \
+ lsmsvgattributes.h \
+ lsmsvgstyle.h \
+ lsmsvgcolors.h \
+ lsmsvglength.h \
+ lsmsvgview.h \
+ lsmsvgmatrix.h \
lsmsvgdocument.h \
lsmsvgelement.h \
- lsmsvggraphic.h \
lsmsvgclippathelement.h \
lsmsvgsvgelement.h \
lsmsvggelement.h \
@@ -166,16 +180,7 @@ liblasem_la_HEADERS = \
lsmsvgradialgradientelement.h \
lsmsvgstopelement.h \
lsmsvgpatternelement.h \
- lsmsvgmaskelement.h \
- lsmsvgenums.h \
- lsmsvgattributes.h \
- lsmsvgattributebags.h \
- lsmsvgstyle.h \
- lsmsvgcolors.h \
- lsmsvglength.h \
- lsmsvgutils.h \
- lsmsvgview.h \
- lsmsvgmatrix.h
+ lsmsvgmaskelement.h
bin_PROGRAMS = lasemtest lasemrender
diff --git a/src/lasemrender.c b/src/lasemrender.c
index 32c89ab..b93cc01 100644
--- a/src/lasemrender.c
+++ b/src/lasemrender.c
@@ -85,16 +85,11 @@ int main(int argc, char **argv)
cairo_surface_t *surface;
GError *error = NULL;
GOptionContext *context;
- GFile *file;
FileFormat format;
char *output_filename;
char *input_filename;
- char *mime;
- char *buffer = NULL;
- size_t size;
double height_pt, width_pt;
unsigned int height, width;
- gboolean success;
g_type_init ();
@@ -164,102 +159,69 @@ int main(int argc, char **argv)
g_free (directory);
}
- mime = g_content_type_guess (input_filename, NULL, 0, NULL);
- file = g_file_new_for_path (input_filename);
+ document = lsm_dom_document_new_from_path (input_filename, NULL);
+ if (document == NULL)
+ document = lsm_dom_document_new_from_url (input_filename, NULL);
- success = g_file_load_contents (file, NULL, &buffer, &size, NULL, NULL);
- if (!success) {
- g_object_unref (file);
- file = g_file_new_for_uri (input_filename);
- success = g_file_load_contents (file, NULL, &buffer, &size, NULL, NULL);
- }
+ if (document != NULL) {
+ lsm_dom_document_set_resolution (document, option_ppi);
+
+ view = lsm_dom_document_create_view (document);
+
+ lsm_dom_view_set_debug (view, option_debug);
- if (success) {
- char *mathml;
+ width_pt = 2.0;
+ height_pt = 2.0;
- if (strcmp (mime, "text/mathml") == 0 ||
- strcmp (mime, "image/svg+xml") == 0)
- mathml = buffer;
- else {
- mathml = itex2MML_parse (buffer, size);
- g_free (buffer);
- buffer = NULL;
+ lsm_dom_view_get_size (view, &width_pt, &height_pt);
+ lsm_dom_view_get_size_pixels (view, &width, &height);
+
+ switch (format) {
+ case FORMAT_PDF:
+ surface = cairo_pdf_surface_create (output_filename,
+ width_pt, height_pt);
+ break;
+ case FORMAT_PS:
+ surface = cairo_ps_surface_create (output_filename,
+ width_pt, height_pt);
+ break;
+ case FORMAT_PNG:
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ width,
+ height);
+ break;
+ case FORMAT_SVG:
+ default:
+ surface = cairo_svg_surface_create (output_filename,
+ width_pt, height_pt);
+ break;
}
- 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);
-
- width_pt = 2.0;
- height_pt = 2.0;
-
- lsm_dom_view_get_size (view, &width_pt, &height_pt);
- lsm_dom_view_get_size_pixels (view, &width, &height);
-
- switch (format) {
- case FORMAT_PDF:
- surface = cairo_pdf_surface_create (output_filename,
- width_pt, height_pt);
- break;
- case FORMAT_PS:
- surface = cairo_ps_surface_create (output_filename,
- width_pt, height_pt);
- break;
- case FORMAT_PNG:
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- width,
- height);
- break;
- case FORMAT_SVG:
- default:
- surface = cairo_svg_surface_create (output_filename,
- width_pt, height_pt);
- break;
- }
-
- cairo = cairo_create (surface);
- cairo_surface_destroy (surface);
-
- lsm_dom_view_set_cairo (view, cairo);
-
- lsm_dom_view_render (view, 0, 0);
-
- switch (format) {
- case FORMAT_PNG:
- cairo_surface_write_to_png (cairo_get_target (cairo),
- output_filename);
- break;
- default:
- break;
- }
-
- cairo_destroy (cairo);
-
- g_object_unref (view);
-
- g_object_unref (document);
-
- lsm_debug ("width = %g pt, height = %g pt", width_pt, height_pt);
- } else
- g_warning ("Can't load %s", input_filename);
- } else
- g_warning ("Invalid document");
-
- if (mathml == buffer)
- g_free (mathml);
- else
- itex2MML_free_string (mathml);
-
- g_object_unref (file);
+ cairo = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ lsm_dom_view_set_cairo (view, cairo);
+
+ lsm_dom_view_render (view, 0, 0);
+
+ switch (format) {
+ case FORMAT_PNG:
+ cairo_surface_write_to_png (cairo_get_target (cairo),
+ output_filename);
+ break;
+ default:
+ break;
+ }
+
+ cairo_destroy (cairo);
+
+ g_object_unref (view);
+
+ g_object_unref (document);
+
+ lsm_debug ("width = %g pt, height = %g pt", width_pt, height_pt);
} else
g_warning ("Can't load %s", input_filename);
- g_free (mime);
-
return (0);
}
diff --git a/src/lasemtest.c b/src/lasemtest.c
index 4a3a16e..bf385f6 100644
--- a/src/lasemtest.c
+++ b/src/lasemtest.c
@@ -115,10 +115,13 @@ lasem_test_render (char const *filename)
if (is_xml)
xml = buffer;
- else
+ else {
xml = itex2MML_parse (buffer, size);
+ size = 0;
+ }
- document = lsm_dom_document_new_from_memory (xml);
+ document = lsm_dom_document_new_from_memory (xml, size, NULL);
+ lsm_dom_document_set_path (document, filename);
view = lsm_dom_document_create_view (document);
diff --git a/src/lsmdom.h b/src/lsmdom.h
index d9a131c..ac4d61d 100644
--- a/src/lsmdom.h
+++ b/src/lsmdom.h
@@ -20,28 +20,13 @@
* Emmanuel Pacaud <emmanuel gnome org>
*/
-
#ifndef LSM_DOM_H
#define LSM_DOM_H
-#include <glib-object.h>
+#include <lsm.h>
G_BEGIN_DECLS
-typedef struct {
- double x1;
- double y1;
- double x2;
- double y2;
-} LsmExtents;
-
-typedef struct {
- double x;
- double y;
- double width;
- double height;
-} LsmBox;
-
typedef struct _LsmDomNode LsmDomNode;
typedef struct _LsmDomElement LsmDomElement;
typedef struct _LsmDomDocument LsmDomDocument;
diff --git a/src/lsmdomdocument.c b/src/lsmdomdocument.c
index 8dd9879..c8062f1 100644
--- a/src/lsmdomdocument.c
+++ b/src/lsmdomdocument.c
@@ -21,8 +21,13 @@
#include <lsmdomdocument.h>
#include <lsmdomelement.h>
+#include <lsmstr.h>
#include <lsmdebug.h>
#include <lsmdomtext.h>
+#include <gio/gio.h>
+#include <string.h>
+
+static GObjectClass *parent_class;
/* LsmDomNode implementation */
@@ -185,6 +190,76 @@ lsm_dom_document_register_element (LsmDomDocument *self, LsmDomElement *element,
}
}
+const char *
+lsm_dom_document_get_url (LsmDomDocument *self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+
+ return self->url;
+}
+
+void
+lsm_dom_document_set_path (LsmDomDocument *self, const char *path)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ g_free (self->url);
+
+ if (path == NULL) {
+ self->url = NULL;
+ return;
+ }
+
+ self->url = lsm_str_to_uri (path);
+}
+
+void
+lsm_dom_document_set_url (LsmDomDocument *self, const char *url)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+ g_return_if_fail (url == NULL || lsm_str_is_uri (url));
+
+ g_free (self->url);
+ self->url = g_strdup (url);
+}
+
+void *
+lsm_dom_document_get_href_data (LsmDomDocument *self, const char *href, gsize *size)
+{
+ GFile *file;
+ char *data = NULL;
+
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+ g_return_val_if_fail (href != NULL, NULL);
+
+ if (strncmp (href, "data:", 5) == 0) {
+ while (*href != '\0' && *href != ',')
+ href++;
+ return g_base64_decode (href, size);
+ }
+
+ file = g_file_new_for_uri (href);
+
+ if (!g_file_load_contents (file, NULL, &data, size, NULL, NULL) && self->url != NULL) {
+ GFile *document_file;
+ GFile *parent_file;
+
+ g_object_unref (file);
+
+ document_file = g_file_new_for_uri (self->url);
+ parent_file = g_file_get_parent (document_file);
+ file = g_file_resolve_relative_path (parent_file, href);
+ g_object_unref (document_file);
+ g_object_unref (parent_file);
+
+ g_file_load_contents (file, NULL, &data, size, NULL, NULL);
+ }
+
+ g_object_unref (file);
+
+ return data;
+}
+
static void
lsm_dom_document_init (LsmDomDocument *document)
{
@@ -205,6 +280,10 @@ lsm_dom_document_finalize (GObject *object)
g_hash_table_unref (document->elements);
g_hash_table_unref (document->ids);
+
+ g_free (document->url);
+
+ parent_class->finalize (object);
}
/* LsmDomDocument class */
@@ -215,6 +294,8 @@ lsm_dom_document_class_init (LsmDomDocumentClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
+
object_class->finalize = lsm_dom_document_finalize;
node_class->get_node_name = lsm_dom_document_get_node_name;
diff --git a/src/lsmdomdocument.h b/src/lsmdomdocument.h
index 3321d36..78697ec 100644
--- a/src/lsmdomdocument.h
+++ b/src/lsmdomdocument.h
@@ -45,8 +45,10 @@ typedef struct _LsmDomDocumentClass LsmDomDocumentClass;
struct _LsmDomDocument {
LsmDomNode node;
- GHashTable * ids;
- GHashTable * elements;
+ GHashTable * ids;
+ GHashTable * elements;
+
+ char * url;
/* Not really a document property, but that simplifies things greatly */
double resolution_ppi;
@@ -82,6 +84,12 @@ void lsm_dom_document_set_viewport_px (LsmDomDocument *self, const LsmBox *vi
LsmBox lsm_dom_document_get_viewport (LsmDomDocument *self);
LsmBox lsm_dom_document_get_viewport_px (LsmDomDocument *self);
+const char * lsm_dom_document_get_url (LsmDomDocument *self);
+void lsm_dom_document_set_url (LsmDomDocument *self, const char *url);
+void lsm_dom_document_set_path (LsmDomDocument *self, const char *path);
+
+void * lsm_dom_document_get_href_data (LsmDomDocument *self, const char *href, gsize *size);
+
G_END_DECLS
#endif
diff --git a/src/lsmdomnode.h b/src/lsmdomnode.h
index 86cae17..8305525 100644
--- a/src/lsmdomnode.h
+++ b/src/lsmdomnode.h
@@ -89,30 +89,30 @@ struct _LsmDomNodeClass {
GType lsm_dom_node_get_type (void);
-const char* lsm_dom_node_get_node_name (LsmDomNode* self);
-const char* lsm_dom_node_get_node_value (LsmDomNode* self);
-void lsm_dom_node_set_node_value (LsmDomNode* self, const char* new_value);
-LsmDomNodeType lsm_dom_node_get_node_type (LsmDomNode* self);
-LsmDomNode* lsm_dom_node_get_parent_node (LsmDomNode* self);
+const char* lsm_dom_node_get_node_name (LsmDomNode* self);
+const char* lsm_dom_node_get_node_value (LsmDomNode* self);
+void lsm_dom_node_set_node_value (LsmDomNode* self, const char* new_value);
+LsmDomNodeType lsm_dom_node_get_node_type (LsmDomNode* self);
+LsmDomNode* lsm_dom_node_get_parent_node (LsmDomNode* self);
#if 0
LsmDomNodeList* lsm_dom_node_get_child_nodes (LsmDomNode* self);
#endif
-LsmDomNode* lsm_dom_node_get_first_child (LsmDomNode* self);
-LsmDomNode* lsm_dom_node_get_last_child (LsmDomNode* self);
+LsmDomNode* lsm_dom_node_get_first_child (LsmDomNode* self);
+LsmDomNode* lsm_dom_node_get_last_child (LsmDomNode* self);
LsmDomNode* lsm_dom_node_get_previous_sibling (LsmDomNode* self);
-LsmDomNode* lsm_dom_node_get_next_sibling (LsmDomNode* self);
+LsmDomNode* lsm_dom_node_get_next_sibling (LsmDomNode* self);
#if 0
LsmDomNamedNodeMap* lsm_dom_node_get_attributes (LsmDomNode* self);
#endif
LsmDomNode* lsm_dom_node_insert_before (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* ref_child);
-LsmDomNode* lsm_dom_node_replace_child (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* old_child);
+LsmDomNode* lsm_dom_node_replace_child (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* old_child);
LsmDomNode* lsm_dom_node_append_child (LsmDomNode* self, LsmDomNode* new_child);
LsmDomNode* lsm_dom_node_remove_child (LsmDomNode* self, LsmDomNode* old_child);
-gboolean lsm_dom_node_has_child_nodes (LsmDomNode* self);
+gboolean lsm_dom_node_has_child_nodes (LsmDomNode* self);
-void lsm_dom_node_changed (LsmDomNode *self);
+void lsm_dom_node_changed (LsmDomNode *self);
-LsmDomDocument* lsm_dom_node_get_owner_document (LsmDomNode* self);
+LsmDomDocument* lsm_dom_node_get_owner_document (LsmDomNode* self);
void lsm_dom_node_dump (LsmDomNode *self);
diff --git a/src/lsmdomparser.c b/src/lsmdomparser.c
index 8d3bbef..66024f4 100644
--- a/src/lsmdomparser.c
+++ b/src/lsmdomparser.c
@@ -24,8 +24,11 @@
#include <lsmmathmlpresentationtoken.h>
#include <lsmmathmlentitydictionary.h>
#include <lsmsvgtextelement.h>
+#include <lsmstr.h>
#include <libxml/parser.h>
+#include <gio/gio.h>
#include <string.h>
+#include <../itex2mml/itex2MML.h>
typedef enum {
STATE
@@ -256,37 +259,134 @@ static xmlSAXHandler sax_handler = {
.entityDecl = lsm_dom_parser_declare_entity
};
-LsmDomDocument *
-lsm_dom_document_new_from_file (const char *filename)
+static GQuark
+lsm_dom_document_error_quark (void)
+{
+ static GQuark q = 0;
+
+ if (q == 0) {
+ q = g_quark_from_static_string ("mrp-error-quark");
+ }
+
+ return q;
+}
+
+#define LSM_DOM_DOCUMENT_ERROR lsm_dom_document_error_quark ()
+
+typedef enum {
+ LSM_DOM_DOCUMENT_ERROR_INVALID_XML
+} LsmDomDocumentError;
+
+static void
+_dummy_error (const char *msg)
+{
+}
+
+static LsmDomDocument *
+lsm_dom_document_new_from_contents (const char *contents, gsize size, GError **error)
{
static LsmDomSaxParserState state;
+ char *mime;
+ char *xml;
+
+ state.document = NULL;
- if (xmlSAXUserParseFile (&sax_handler, &state, filename) < 0) {
+ mime = g_content_type_guess (NULL, (guchar *) contents, size, NULL);
+ lsm_debug ("[LsmDomDocument::new_from_contents] mime = '%s'", mime);
+ if (g_strcmp0 (mime, "image/svg+xml") == 0 ||
+ g_strcmp0 (mime, "text/mathml") == 0 ||
+ g_strcmp0 (mime, "application/xml") == 0) {
+ xml = (char *) contents;
+ } else {
+ itex2MML_error = _dummy_error;
+
+ xml = itex2MML_parse (contents, size);
+ size = strlen (contents);
+ }
+
+ if (xmlSAXUserParseMemory (&sax_handler, &state, xml, size) < 0) {
if (state.document != NULL)
g_object_unref (state.document);
- g_warning ("[LsmDomParser::from_file] invalid document");
- return NULL;
+ state.document = NULL;
+
+ lsm_debug ("[LsmDomParser::from_memory] invalid document");
+
+ g_set_error (error,
+ LSM_DOM_DOCUMENT_ERROR,
+ LSM_DOM_DOCUMENT_ERROR_INVALID_XML,
+ "Invalid document.");
}
- return LSM_DOM_DOCUMENT (state.document);
+ if (xml != contents)
+ itex2MML_free_string (xml);
+
+ return state.document;
}
LsmDomDocument *
-lsm_dom_document_new_from_memory (const char *buffer)
+lsm_dom_document_new_from_memory (const char *buffer, gsize size, GError **error)
{
- static LsmDomSaxParserState state;
+ g_return_val_if_fail (buffer != NULL, NULL);
- if (buffer == NULL)
- return NULL;
+ if (size < 1)
+ size = strlen (buffer);
- state.document = NULL;
+ return lsm_dom_document_new_from_contents (buffer, size, error);
+}
- if (xmlSAXUserParseMemory (&sax_handler, &state, buffer, strlen (buffer)) < 0) {
- if (state.document != NULL)
- g_object_unref (state.document);
- g_warning ("[LsmDomParser::from_memory] invalid document");
+static LsmDomDocument *
+lsm_dom_document_new_from_file (GFile *file, GError **error)
+{
+ LsmDomDocument *document;
+ gsize size = 0;
+ char *contents = NULL;
+
+ if (!g_file_load_contents (file, NULL, &contents, &size, NULL, error))
return NULL;
- }
- return LSM_DOM_DOCUMENT (state.document);
+ document = lsm_dom_document_new_from_contents (contents, size, error);
+
+ g_free (contents);
+
+ return document;
+}
+
+LsmDomDocument *
+lsm_dom_document_new_from_path (const char *path, GError **error)
+{
+ LsmDomDocument *document;
+ GFile *file;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ file = g_file_new_for_path (path);
+
+ document = lsm_dom_document_new_from_file (file, error);
+
+ g_object_unref (file);
+
+ if (document != NULL)
+ lsm_dom_document_set_path (document, path);
+
+ return document;
+}
+
+LsmDomDocument *
+lsm_dom_document_new_from_url (const char *url, GError **error)
+{
+ LsmDomDocument *document;
+ GFile *file;
+
+ g_return_val_if_fail (url != NULL, NULL);
+
+ file = g_file_new_for_uri (url);
+
+ document = lsm_dom_document_new_from_file (file, error);
+
+ g_object_unref (file);
+
+ if (document != NULL)
+ lsm_dom_document_set_url (document, url);
+
+ return document;
}
diff --git a/src/lsmdomparser.h b/src/lsmdomparser.h
index 1af26b8..51e6a78 100644
--- a/src/lsmdomparser.h
+++ b/src/lsmdomparser.h
@@ -26,8 +26,13 @@
G_BEGIN_DECLS
-LsmDomDocument * lsm_dom_document_new_from_file (const char *filename);
-LsmDomDocument * lsm_dom_document_new_from_memory (const char *buffer);
+typedef enum {
+ LSM_DOM_DOCUMENT_ERROR_INVALID_XML
+} LsmDomDocumentError;
+
+LsmDomDocument * lsm_dom_document_new_from_memory (const char *buffer, gsize size, GError *error);
+LsmDomDocument * lsm_dom_document_new_from_path (const char *path, GError *error);
+LsmDomDocument * lsm_dom_document_new_from_url (const char *url, GError *error);
G_END_DECLS
diff --git a/src/lsmdomview.c b/src/lsmdomview.c
index 1b7cbb1..0f9c4c8 100644
--- a/src/lsmdomview.c
+++ b/src/lsmdomview.c
@@ -90,6 +90,9 @@ lsm_dom_view_render (LsmDomView *view, double x, double y)
view_class->render (view);
cairo_restore (view->cairo);
+
+ lsm_debug ("[LsmDomView::render] cairo status = %s",
+ cairo_status_to_string (cairo_status (view->cairo)));
}
void
diff --git a/src/lsmmathmldocument.c b/src/lsmmathmldocument.c
index 83d7d3a..2532456 100644
--- a/src/lsmmathmldocument.c
+++ b/src/lsmmathmldocument.c
@@ -168,6 +168,7 @@ lsm_mathml_document_class_init (LsmMathmlDocumentClass *m_document_class)
G_DEFINE_TYPE (LsmMathmlDocument, lsm_mathml_document, LSM_TYPE_DOM_DOCUMENT)
+#if 0
static void
_dummy_error (const char *msg)
{
@@ -194,3 +195,4 @@ lsm_mathml_document_new_from_itex (const char *itex)
return document;
}
+#endif
diff --git a/src/lsmmathmldocument.h b/src/lsmmathmldocument.h
index 59a2046..e8c47e9 100644
--- a/src/lsmmathmldocument.h
+++ b/src/lsmmathmldocument.h
@@ -50,7 +50,9 @@ GType lsm_mathml_document_get_type (void);
LsmMathmlDocument * lsm_mathml_document_new (void);
LsmMathmlMathElement * lsm_mathml_document_get_root_element (const LsmMathmlDocument *document);
+#if 0
LsmMathmlDocument * lsm_mathml_document_new_from_itex (const char *itex);
+#endif
G_END_DECLS
diff --git a/src/lsmmathmlmathelement.c b/src/lsmmathmlmathelement.c
index 2ae7673..e494c65 100644
--- a/src/lsmmathmlmathelement.c
+++ b/src/lsmmathmlmathelement.c
@@ -181,6 +181,8 @@ lsm_mathml_math_element_finalize (GObject *object)
LsmMathmlMathElement *math_element = LSM_MATHML_MATH_ELEMENT (object);
lsm_mathml_style_free (math_element->default_style);
+
+ parent_class->finalize (object);
}
/* LsmMathmlMathElement class */
diff --git a/src/lsmmathmltableelement.c b/src/lsmmathmltableelement.c
index c4fa903..31c869a 100644
--- a/src/lsmmathmltableelement.c
+++ b/src/lsmmathmltableelement.c
@@ -457,6 +457,8 @@ lsm_mathml_table_element_finalize (GObject *object)
table->widths = NULL;
table->heights = NULL;
table->depths = NULL;
+
+ parent_class->finalize (object);
}
/* LsmMathmlTableElement class */
diff --git a/src/lsmsvgattributes.h b/src/lsmsvgattributes.h
index 4db88ad..806ac81 100644
--- a/src/lsmsvgattributes.h
+++ b/src/lsmsvgattributes.h
@@ -23,135 +23,70 @@
#ifndef LSM_SVG_ATTRIBUTES_H
#define LSM_SVG_ATTRIBUTES_H
-#include <lsmdomattributes.h>
+#include <lsmattributes.h>
#include <lsmdomview.h>
#include <lsmsvg.h>
#include <lsmsvgenums.h>
+#include <lsmsvgtraits.h>
#include <lsmsvglength.h>
#include <lsmsvgmatrix.h>
G_BEGIN_DECLS
typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
double value;
} LsmSvgDoubleAttribute;
typedef struct {
- double red;
- double green;
- double blue;
-} LsmSvgColor;
-
-extern const LsmSvgColor lsm_svg_color_null;
-
-typedef struct {
- unsigned int n_dashes;
- LsmSvgLength *dashes;
-} LsmSvgDashArray;
-
-extern const LsmSvgDashArray lsm_svg_dash_array_null;
-
-LsmSvgDashArray * lsm_svg_dash_array_new (unsigned int n_dashes);
-void lsm_svg_dash_array_free (LsmSvgDashArray *array);
-LsmSvgDashArray * lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin);
-
-typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmSvgDashArray *value;
} LsmSvgDashArrayAttribute;
typedef struct {
- LsmSvgPaintType type;
- char *uri;
- LsmSvgColor color;
-} LsmSvgPaint;
-
-typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmSvgLength length;
- double value;
} LsmSvgLengthAttribute;
typedef struct {
- LsmDomAttribute attr;
- LsmSvgAnimatedLength length;
- double value;
-} LsmSvgAnimatedLengthAttribute;
-
-typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmSvgPaint paint;
} LsmSvgPaintAttribute;
typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
char *value;
} LsmSvgStringAttribute;
typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmSvgColor value;
} LsmSvgColorAttribute;
typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmBox value;
} LsmSvgViewboxAttribute;
typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmSvgMatrix matrix;
} LsmSvgTransformAttribute;
typedef struct {
- gboolean defer;
- LsmSvgAlign align;
- LsmSvgMeetOrSlice meet_or_slice;
-} LsmSvgPreserveAspectRatio;
-
-typedef struct {
- LsmDomAttribute attr;
+ LsmAttribute base;
LsmSvgPreserveAspectRatio value;
} LsmSvgPreserveAspectRatioAttribute;
-/* Properties */
-
-void lsm_svg_double_attribute_parse (LsmSvgDoubleAttribute *attribute,
- double *double_value);
-void lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
- LsmSvgLength *default_value);
-void lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
- LsmSvgLength *default_value);
-
-void lsm_svg_dash_array_attribute_finalize (void *abstract);
-
-void lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
- LsmSvgDashArray **default_value);
-
-void lsm_svg_fill_rule_attribute_parse (LsmDomEnumAttribute *attribute,
- unsigned int *style_value);
-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_pattern_units_attribute_parse (LsmDomEnumAttribute *attribute,
- unsigned int *style_value);
-void lsm_svg_spread_method_attribute_parse (LsmDomEnumAttribute *attribute,
- unsigned int *style_value);
-void lsm_svg_paint_attribute_finalize (void *abstract);
-void lsm_svg_paint_attribute_parse (LsmSvgPaintAttribute *attribute,
- LsmSvgPaint *default_value,
- const LsmSvgColor *current_color);
-void lsm_svg_color_attribute_parse (LsmSvgColorAttribute *attribute,
- LsmSvgColor *default_value,
- const LsmSvgColor *current_color);
-
-/* Attributes */
-
-void lsm_svg_viewbox_attribute_parse (LsmSvgViewboxAttribute *attribute);
-void lsm_svg_transform_attribute_parse (LsmSvgTransformAttribute *attribute);
-void lsm_svg_preserve_aspect_ratio_attribute_parse (LsmSvgPreserveAspectRatioAttribute *attribute);
+typedef struct {
+ LsmAttribute base;
+ LsmSvgSpreadMethod value;
+} LsmSvgSpreadMethodAtttribute;
+
+typedef struct {
+ LsmAttribute base;
+ LsmSvgPatternUnits value;
+} LsmSvgPatternUnitsAttribute;
G_END_DECLS
diff --git a/src/lsmsvgcircleelement.c b/src/lsmsvgcircleelement.c
index 5371a7d..8407424 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -35,40 +35,19 @@ lsm_svg_circle_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
-static void
-lsm_svg_circle_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgCircleElement *circle = LSM_SVG_CIRCLE_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&circle->cx, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&circle->cy, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&circle->r, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
static void
-lsm_svg_circle_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_circle_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgCircleElement *circle = LSM_SVG_CIRCLE_ELEMENT (self);
double cx, cy, r;
- 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);
+ cx = lsm_svg_view_normalize_length (view, &circle->cx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ cy = lsm_svg_view_normalize_length (view, &circle->cy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ r = lsm_svg_view_normalize_length (view, &circle->r.length, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- lsm_debug ("[LsmSvgCircleElement::graphic_render] cx = %g, cy = %g, r = %g",
+ lsm_debug ("[LsmSvgCircleElement::render] cx = %g, cy = %g, r = %g",
cx, cy, r);
lsm_svg_view_show_circle (view, cx, cy, r);
@@ -82,25 +61,51 @@ lsm_svg_circle_element_new (void)
return g_object_new (LSM_TYPE_SVG_CIRCLE_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+
static void
lsm_svg_circle_element_init (LsmSvgCircleElement *self)
{
+ self->cx.length = length_default;
+ self->cy.length = length_default;
+ self->r.length = length_default;
}
static void
lsm_svg_circle_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgCircleElement class */
+static const LsmAttributeInfos lsm_svg_circle_element_attribute_infos[] = {
+ {
+ .name = "cx",
+ .attribute_offset = offsetof (LsmSvgCircleElement, cx),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "cy",
+ .attribute_offset = offsetof (LsmSvgCircleElement, cy),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "r",
+ .attribute_offset = offsetof (LsmSvgCircleElement, r),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ }
+};
+
static void
lsm_svg_circle_element_class_init (LsmSvgCircleElementClass *s_rect_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_rect_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
@@ -108,18 +113,12 @@ lsm_svg_circle_element_class_init (LsmSvgCircleElementClass *s_rect_class)
d_node_class->get_node_name = lsm_svg_circle_element_get_node_name;
- s_element_class->update = lsm_svg_circle_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_circle_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_circle_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "cx",
- offsetof (LsmSvgCircleElement, cx));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "cy",
- offsetof (LsmSvgCircleElement, cy));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "r",
- offsetof (LsmSvgCircleElement, r));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_circle_element_attribute_infos),
+ lsm_svg_circle_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgCircleElement, lsm_svg_circle_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgCircleElement, lsm_svg_circle_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgcircleelement.h b/src/lsmsvgcircleelement.h
index 83541b7..b8696b8 100644
--- a/src/lsmsvgcircleelement.h
+++ b/src/lsmsvgcircleelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_CIRCLE_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,15 +37,15 @@ G_BEGIN_DECLS
typedef struct _LsmSvgCircleElementClass LsmSvgCircleElementClass;
struct _LsmSvgCircleElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute cx;
- LsmSvgAnimatedLengthAttribute cy;
- LsmSvgAnimatedLengthAttribute r;
+ LsmSvgLengthAttribute cx;
+ LsmSvgLengthAttribute cy;
+ LsmSvgLengthAttribute r;
};
struct _LsmSvgCircleElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_circle_element_get_type (void);
diff --git a/src/lsmsvgclippathelement.c b/src/lsmsvgclippathelement.c
index 0bbdcdf..9409733 100644
--- a/src/lsmsvgclippathelement.c
+++ b/src/lsmsvgclippathelement.c
@@ -37,22 +37,21 @@ _clip_path_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
static void
-_clip_path_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgClipPathElement *pattern = LSM_SVG_CLIP_PATH_ELEMENT (self);
- LsmSvgPatternUnits units;
-
- units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
- lsm_svg_pattern_units_attribute_parse (&pattern->units, &units);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
-static void
-_clip_path_element_render_clip (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_clip_path_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgClipPathElement *clip = LSM_SVG_CLIP_PATH_ELEMENT (self);
gboolean is_object_bounding_box;
+ LsmSvgStyle *style;
+
+ if (!clip->enable_rendering) {
+ lsm_debug ("[LsmSvgClipPathElement::render] Direct rendering not allowed");
+ return;
+ } else {
+ clip->enable_rendering = FALSE;
+ }
+
+ style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
+ lsm_svg_view_push_style (view, style);
is_object_bounding_box = (clip->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
@@ -73,6 +72,15 @@ _clip_path_element_render_clip (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_pop_matrix (view);
lsm_svg_view_pop_viewbox (view);
}
+
+ lsm_svg_view_pop_style (view);
+ lsm_svg_style_free (style);
+}
+
+static void
+lsm_svg_clip_path_element_enable_rendering (LsmSvgElement *element)
+{
+ LSM_SVG_CLIP_PATH_ELEMENT (element)->enable_rendering = TRUE;
}
LsmDomNode *
@@ -81,22 +89,26 @@ lsm_svg_clip_path_element_new (void)
return g_object_new (LSM_TYPE_SVG_CLIP_PATH_ELEMENT, NULL);
}
+static const LsmSvgPatternUnits units_default = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
+
static void
lsm_svg_clip_path_element_init (LsmSvgClipPathElement *self)
{
- /* Hack - Force the creation of the attribute bags,
- making sure the properties will be inherited from the
- pattern element ancestor, not the referencing one. */
-
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "transform", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "font-family", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stop-color", NULL);
+ self->enable_rendering = FALSE;
+ self->units.value = units_default;
}
/* LsmSvgClipPathElement class */
+static const LsmAttributeInfos lsm_svg_clip_path_element_attribute_infos[] = {
+ {
+ .name = "clipPathUnits",
+ .trait_class = &lsm_svg_pattern_units_trait_class,
+ .attribute_offset = offsetof (LsmSvgClipPathElement, units),
+ .trait_default = &units_default
+ }
+};
+
static void
lsm_svg_clip_path_element_class_init (LsmSvgClipPathElementClass *klass)
{
@@ -107,14 +119,14 @@ lsm_svg_clip_path_element_class_init (LsmSvgClipPathElementClass *klass)
d_node_class->get_node_name = _clip_path_element_get_node_name;
- s_element_class->update = _clip_path_element_update;
- s_element_class->render_clip = _clip_path_element_render_clip;
- s_element_class->render = NULL;
+ s_element_class->render = lsm_svg_clip_path_element_render;
+ s_element_class->enable_rendering = lsm_svg_clip_path_element_enable_rendering;
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "clipPathUnits",
- offsetof (LsmSvgClipPathElement, units));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_clip_path_element_attribute_infos),
+ lsm_svg_clip_path_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgClipPathElement, lsm_svg_clip_path_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgClipPathElement, lsm_svg_clip_path_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgclippathelement.h b/src/lsmsvgclippathelement.h
index 9959a1e..5794396 100644
--- a/src/lsmsvgclippathelement.h
+++ b/src/lsmsvgclippathelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_CLIP_PATH_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,13 +37,15 @@ G_BEGIN_DECLS
typedef struct _LsmSvgClipPathElementClass LsmSvgClipPathElementClass;
struct _LsmSvgClipPathElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmDomEnumAttribute units;
+ LsmSvgPatternUnitsAttribute units;
+
+ gboolean enable_rendering;
};
struct _LsmSvgClipPathElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_clip_path_element_get_type (void);
diff --git a/src/lsmsvgdefselement.c b/src/lsmsvgdefselement.c
index 957816e..fbde796 100644
--- a/src/lsmsvgdefselement.c
+++ b/src/lsmsvgdefselement.c
@@ -65,4 +65,4 @@ lsm_svg_defs_element_class_init (LsmSvgDefsElementClass *s_g_class)
s_element_class->render = NULL;
}
-G_DEFINE_TYPE (LsmSvgDefsElement, lsm_svg_defs_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgDefsElement, lsm_svg_defs_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgdefselement.h b/src/lsmsvgdefselement.h
index 21c84fd..3c0c3f3 100644
--- a/src/lsmsvgdefselement.h
+++ b/src/lsmsvgdefselement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_DEFS_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,11 +37,11 @@ G_BEGIN_DECLS
typedef struct _LsmSvgDefsElementClass LsmSvgDefsElementClass;
struct _LsmSvgDefsElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
};
struct _LsmSvgDefsElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_defs_element_get_type (void);
diff --git a/src/lsmsvgdocument.h b/src/lsmsvgdocument.h
index 17de642..ba173a9 100644
--- a/src/lsmsvgdocument.h
+++ b/src/lsmsvgdocument.h
@@ -46,7 +46,7 @@ struct _LsmSvgDocumentClass {
GType lsm_svg_document_get_type (void);
-LsmSvgDocument * lsm_svg_document_new (void);
+LsmSvgDocument * lsm_svg_document_new (void);
LsmSvgSvgElement * lsm_svg_document_get_root_element (const LsmSvgDocument *document);
G_END_DECLS
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index 26299b2..8c5ab53 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -20,8 +20,14 @@
*/
#include <lsmdebug.h>
+#include <lsmattributes.h>
+#include <lsmproperties.h>
#include <lsmdomdocument.h>
#include <lsmsvgelement.h>
+#include <lsmsvgpatternelement.h>
+#include <lsmsvggradientelement.h>
+#include <lsmsvgclippathelement.h>
+#include <lsmsvgmaskelement.h>
#include <lsmsvgview.h>
#include <string.h>
@@ -38,13 +44,6 @@ lsm_svg_element_can_append_child (LsmDomNode *self, LsmDomNode *child)
static gboolean
lsm_svg_element_child_changed (LsmDomNode *parent, LsmDomNode *child)
{
- LsmSvgElement *element = LSM_SVG_ELEMENT (parent);
-
- if (element->need_children_update)
- return FALSE;
-
- element->need_children_update = TRUE;
-
return TRUE;
}
@@ -53,68 +52,40 @@ lsm_svg_element_child_changed (LsmDomNode *parent, LsmDomNode *child)
static void
lsm_svg_element_set_attribute (LsmDomElement *self, const char* name, const char *value)
{
- LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_GET_CLASS(self);
+ LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_GET_CLASS (self);
+ LsmSvgElement *s_element = LSM_SVG_ELEMENT (self);
lsm_debug ("[LsmSvgElement::set_attribute] node = %s, name = %s, value = %s",
lsm_dom_node_get_node_name (LSM_DOM_NODE (self)), name, value);
- lsm_dom_attribute_map_set_attribute (s_element_class->attributes, self,
- name, value);
+ /* TODO Avoid double hash table lookup */
+ if (!lsm_attribute_manager_set_attribute (s_element_class->attribute_manager,
+ self, name, value))
+ lsm_svg_property_bag_set_property (&s_element->property_bag, name, value);
+
+ if (g_strcmp0 (name, "id") == 0) {
+ LsmDomDocument *document;
+
+ document = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
+ if (document != NULL)
+ lsm_dom_document_register_element (document, LSM_DOM_ELEMENT (self), value);
+ }
}
const char *
lsm_svg_element_get_attribute (LsmDomElement *self, const char *name)
{
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_GET_CLASS(self);
+ LsmSvgElement *s_element = LSM_SVG_ELEMENT (self);
+ const char *value;
- return lsm_dom_attribute_map_get_attribute (s_element_class->attributes, self, name);
-}
-
-/* LsmSvgElement implementation */
-
-void
-lsm_svg_element_update (LsmSvgElement *self, const LsmSvgStyle *parent_style)
-{
- LsmSvgElementClass *element_class;
- LsmSvgStyle *style;
- LsmDomDocument *document;
- LsmDomNode *node;
-
- g_return_if_fail (LSM_IS_SVG_ELEMENT (self));
- g_return_if_fail (parent_style != NULL);
-
- if (!self->need_update && !self->need_children_update) {
- lsm_debug ("[Element::update] %s already up to date",
- lsm_dom_node_get_node_name (LSM_DOM_NODE (self)));
- return;
- }
-
- document = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
- if (document != NULL)
- lsm_dom_document_register_element (document, LSM_DOM_ELEMENT (self), self->id.value);
-
- element_class = LSM_SVG_ELEMENT_GET_CLASS (self);
-
- style = lsm_svg_style_duplicate (parent_style);
- g_return_if_fail (style != NULL);
-
- lsm_debug ("[Element::update] update %s",
- lsm_dom_node_get_node_name (LSM_DOM_NODE (self)));
+ /* TODO Avoid double hash table lookup */
+ value = lsm_attribute_manager_get_attribute (s_element_class->attribute_manager,
+ self, name);
+ if (value != NULL)
+ return value;
- if (element_class->update != NULL)
- element_class->update (self, style);
-
- for (node = LSM_DOM_NODE (self)->first_child; node != NULL; node = node->next_sibling)
- if (LSM_IS_SVG_ELEMENT (node)) {
- if (self->need_update)
- LSM_SVG_ELEMENT (node)->need_update = TRUE;
- lsm_svg_element_update (LSM_SVG_ELEMENT (node), style);
- }
-
- lsm_svg_style_free (style);
-
- self->need_update = FALSE;
- self->need_children_update = FALSE;
+ return lsm_svg_property_bag_get_property (&s_element->property_bag, name);
}
/* LsmSvgElement implementation */
@@ -126,20 +97,32 @@ _render (LsmSvgElement *element, LsmSvgView *view)
lsm_debug ("[LsmSvgElement::_render");
+ lsm_svg_view_push_group_opacity (view);
+
for (node = LSM_DOM_NODE (element)->first_child; node != NULL; node = node->next_sibling)
if (LSM_IS_SVG_ELEMENT (node))
lsm_svg_element_render (LSM_SVG_ELEMENT (node), view);
+
+ lsm_svg_view_pop_group_opacity (view);
}
void
lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view)
{
LsmSvgElementClass *element_class;
+ const LsmSvgStyle *parent_style;
+ LsmSvgStyle *style;
g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
+ parent_style = lsm_svg_view_get_current_style (view);
+ style = lsm_svg_style_new_inherited (parent_style, &element->property_bag);
+
+ if (!lsm_svg_matrix_is_identity (&element->transform.matrix))
+ lsm_svg_view_push_matrix (view, &element->transform.matrix);
lsm_svg_view_push_element (view, element);
+ lsm_svg_view_push_style (view, style);
element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
if (element_class->render != NULL) {
@@ -150,41 +133,72 @@ lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view)
element_class->render (element, view);
}
+ lsm_svg_view_pop_style (view);
lsm_svg_view_pop_element (view);
+
+ if (!lsm_svg_matrix_is_identity (&element->transform.matrix))
+ lsm_svg_view_pop_matrix (view);
+
+ lsm_svg_style_free (style);
}
-void
-lsm_svg_element_render_paint (LsmSvgElement *element, LsmSvgView *view)
+static void
+lsm_svg_element_enable_rendering (LsmSvgElement *element)
{
LsmSvgElementClass *element_class;
g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
- if (element_class->render_paint != NULL) {
- lsm_debug ("[LsmSvgElement::render_paint] Render %s (%s)",
- lsm_dom_node_get_node_name (LSM_DOM_NODE (element)),
- element->id.value != NULL ? element->id.value : "no id");
+ g_return_if_fail (element_class->enable_rendering != NULL);
- element_class->render_paint (element, view);
- }
+ element_class->enable_rendering (element);
}
void
-lsm_svg_element_render_clip (LsmSvgElement *element, LsmSvgView *view)
+lsm_svg_element_force_render (LsmSvgElement *element, LsmSvgView *view)
{
- LsmSvgElementClass *element_class;
+ g_return_if_fail (LSM_IS_SVG_PATTERN_ELEMENT (element) ||
+ LSM_IS_SVG_GRADIENT_ELEMENT (element) ||
+ LSM_IS_SVG_MASK_ELEMENT (element) ||
+ LSM_IS_SVG_CLIP_PATH_ELEMENT (element));
- g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
+ lsm_svg_element_enable_rendering (element);
+ lsm_svg_element_render (element, view);
+}
- element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
- if (element_class->render_clip != NULL) {
- lsm_debug ("[LsmSvgElement::render_clip] Render %s (%s)",
- lsm_dom_node_get_node_name (LSM_DOM_NODE (element)),
- element->id.value != NULL ? element->id.value : "no id");
+static void
+_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExtents *extents)
+{
+ LsmDomNode *node;
+ gboolean first_child = TRUE;
+ LsmExtents element_extents = {0.0, 0.0, 0.0, 0.0};
+
+ lsm_debug ("[LsmSvgGraphic::_graphic_get_extents]");
- element_class->render_clip (element, view);
+ for (node = LSM_DOM_NODE (self)->first_child; node != NULL; node = node->next_sibling) {
+ if (LSM_IS_SVG_ELEMENT (node)) {
+ LsmExtents child_extents;
+
+ lsm_svg_element_get_extents (LSM_SVG_ELEMENT (node), view, &child_extents);
+
+ if (!lsm_svg_matrix_is_identity (&self->transform.matrix))
+ lsm_svg_matrix_transform_bounding_box (&self->transform.matrix,
+ &child_extents.x1, &child_extents.y1,
+ &child_extents.x2, &child_extents.y2);
+ if (first_child) {
+ element_extents = child_extents;
+ first_child = FALSE;
+ } else {
+ element_extents.x1 = MIN (element_extents.x1, child_extents.x1);
+ element_extents.y1 = MIN (element_extents.y1, child_extents.y1);
+ element_extents.x2 = MAX (element_extents.x2, child_extents.x2);
+ element_extents.y2 = MAX (element_extents.y2, child_extents.y2);
+ }
+ }
}
+
+ *extents = element_extents;
}
void
@@ -214,17 +228,42 @@ lsm_svg_element_get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtent
static void
lsm_svg_element_init (LsmSvgElement *element)
{
- element->need_update = TRUE;
+ lsm_svg_matrix_init_identity (&element->transform.matrix);
}
static void
lsm_svg_element_finalize (GObject *object)
{
+ LsmSvgElement *svg_element = LSM_SVG_ELEMENT (object);
+
+ lsm_svg_property_bag_clean (&svg_element->property_bag);
+
parent_class->finalize (object);
}
/* LsmSvgElement class */
+static const LsmSvgMatrix matrix_default = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, LSM_SVG_MATRIX_FLAGS_IDENTITY};
+
+static const LsmAttributeInfos lsm_svg_attribute_infos[] = {
+ {
+ .name = "id",
+ .trait_class = &lsm_null_trait_class,
+ .attribute_offset = offsetof (LsmSvgElement, id)
+ },
+ {
+ .name = "class",
+ .trait_class = &lsm_null_trait_class,
+ .attribute_offset = offsetof (LsmSvgElement, class_name)
+ },
+ {
+ .name = "transform",
+ .attribute_offset = offsetof (LsmSvgElement, transform),
+ .trait_class = &lsm_svg_matrix_trait_class,
+ .trait_default = &matrix_default
+ }
+};
+
static void
lsm_svg_element_class_init (LsmSvgElementClass *s_element_class)
{
@@ -242,14 +281,10 @@ lsm_svg_element_class_init (LsmSvgElementClass *s_element_class)
d_element_class->get_attribute = lsm_svg_element_get_attribute;
d_element_class->set_attribute = lsm_svg_element_set_attribute;
- s_element_class->update = NULL;
s_element_class->render = _render;
- s_element_class->render_paint = NULL;
-
- s_element_class->attributes = lsm_dom_attribute_map_new ();
-
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "id",
- offsetof (LsmSvgElement, id));
+ s_element_class->get_extents = _get_extents;
+ s_element_class->attribute_manager = lsm_attribute_manager_new (G_N_ELEMENTS (lsm_svg_attribute_infos),
+ lsm_svg_attribute_infos);
}
G_DEFINE_ABSTRACT_TYPE (LsmSvgElement, lsm_svg_element, LSM_TYPE_DOM_ELEMENT)
diff --git a/src/lsmsvgelement.h b/src/lsmsvgelement.h
index 0a877c3..4138219 100644
--- a/src/lsmsvgelement.h
+++ b/src/lsmsvgelement.h
@@ -24,8 +24,8 @@
#define LSM_SVG_ELEMENT_H
#include <lsmsvg.h>
+#include <lsmattributes.h>
#include <lsmsvgattributes.h>
-#include <lsmsvgattributebags.h>
#include <lsmsvgstyle.h>
#include <lsmdomelement.h>
#include <cairo.h>
@@ -44,32 +44,27 @@ typedef struct _LsmSvgElementClass LsmSvgElementClass;
struct _LsmSvgElement {
LsmDomElement element;
- LsmDomAttribute id;
+ LsmPropertyBag property_bag;
- /* View */
-
- gboolean need_update;
- gboolean need_children_update;
+ LsmAttribute id;
+ LsmAttribute class_name;
+ LsmSvgTransformAttribute transform;
};
struct _LsmSvgElementClass {
LsmDomElementClass parent_class;
- LsmDomAttributeMap *attributes;
+ LsmAttributeManager *attribute_manager;
- void (*update) (LsmSvgElement *element, LsmSvgStyle *style);
+ void (*enable_rendering) (LsmSvgElement *element);
void (*render) (LsmSvgElement *element, LsmSvgView *view);
- void (*render_paint) (LsmSvgElement *element, LsmSvgView *view);
- void (*render_clip) (LsmSvgElement *element, LsmSvgView *view);
void (*get_extents) (LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
};
GType lsm_svg_element_get_type (void);
-void lsm_svg_element_update (LsmSvgElement *element, const LsmSvgStyle *style);
void lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view);
-void lsm_svg_element_render_paint (LsmSvgElement *element, LsmSvgView *view);
-void lsm_svg_element_render_clip (LsmSvgElement *element, LsmSvgView *view);
+void lsm_svg_element_force_render (LsmSvgElement *element, LsmSvgView *view);
void lsm_svg_element_get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
G_END_DECLS
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index 17f7783..f394a77 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -34,43 +34,18 @@ lsm_svg_ellipse_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
-static void
-lsm_svg_ellipse_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgEllipseElement *ellipse = LSM_SVG_ELLIPSE_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->cx, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->cy, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->rx, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_animated_length_attribute_parse (&ellipse->ry, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
static void
-lsm_svg_ellipse_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_ellipse_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgEllipseElement *ellipse = LSM_SVG_ELLIPSE_ELEMENT (self);
double cx, cy, rx, ry;
- 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);
+ cx = lsm_svg_view_normalize_length (view, &ellipse->cx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ cy = lsm_svg_view_normalize_length (view, &ellipse->cy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ rx = lsm_svg_view_normalize_length (view, &ellipse->rx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ ry = lsm_svg_view_normalize_length (view, &ellipse->ry.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
lsm_svg_view_show_ellipse (view, cx, cy, rx, ry);
}
@@ -83,25 +58,58 @@ lsm_svg_ellipse_element_new (void)
return g_object_new (LSM_TYPE_SVG_ELLIPSE_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+
static void
lsm_svg_ellipse_element_init (LsmSvgEllipseElement *self)
{
+ self->cx.length = length_default;
+ self->cy.length = length_default;
+ self->rx.length = length_default;
+ self->ry.length = length_default;
}
static void
lsm_svg_ellipse_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgEllipseElement class */
+static const LsmAttributeInfos lsm_svg_ellipse_element_attribute_infos[] = {
+ {
+ .name = "cx",
+ .attribute_offset = offsetof (LsmSvgEllipseElement, cx),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "cy",
+ .attribute_offset = offsetof (LsmSvgEllipseElement, cy),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "rx",
+ .attribute_offset = offsetof (LsmSvgEllipseElement, rx),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "ry",
+ .attribute_offset = offsetof (LsmSvgEllipseElement, ry),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ }
+};
+
static void
lsm_svg_ellipse_element_class_init (LsmSvgEllipseElementClass *s_rect_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_rect_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
@@ -109,20 +117,12 @@ lsm_svg_ellipse_element_class_init (LsmSvgEllipseElementClass *s_rect_class)
d_node_class->get_node_name = lsm_svg_ellipse_element_get_node_name;
- s_element_class->update = lsm_svg_ellipse_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_ellipse_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_ellipse_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "cx",
- offsetof (LsmSvgEllipseElement, cx));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "cy",
- offsetof (LsmSvgEllipseElement, cy));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "rx",
- offsetof (LsmSvgEllipseElement, rx));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "ry",
- offsetof (LsmSvgEllipseElement, ry));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_ellipse_element_attribute_infos),
+ lsm_svg_ellipse_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgEllipseElement, lsm_svg_ellipse_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgEllipseElement, lsm_svg_ellipse_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgellipseelement.h b/src/lsmsvgellipseelement.h
index d5e6d74..87a6760 100644
--- a/src/lsmsvgellipseelement.h
+++ b/src/lsmsvgellipseelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_ELLIPSE_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,16 +37,16 @@ G_BEGIN_DECLS
typedef struct _LsmSvgEllipseElementClass LsmSvgEllipseElementClass;
struct _LsmSvgEllipseElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute cx;
- LsmSvgAnimatedLengthAttribute cy;
- LsmSvgAnimatedLengthAttribute rx;
- LsmSvgAnimatedLengthAttribute ry;
+ LsmSvgLengthAttribute cx;
+ LsmSvgLengthAttribute cy;
+ LsmSvgLengthAttribute rx;
+ LsmSvgLengthAttribute ry;
};
struct _LsmSvgEllipseElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_ellipse_element_get_type (void);
diff --git a/src/lsmsvgenums.c b/src/lsmsvgenums.c
index 1247354..ce02e1d 100644
--- a/src/lsmsvgenums.c
+++ b/src/lsmsvgenums.c
@@ -38,7 +38,7 @@ lsm_svg_value_from_string (const char *string, const char **strings, unsigned in
}
static const char *lsm_svg_length_type_strings[] = {
- "",
+ "?",
"",
"%",
"em",
diff --git a/src/lsmsvggelement.c b/src/lsmsvggelement.c
index fb2a8c8..f3565ad 100644
--- a/src/lsmsvggelement.c
+++ b/src/lsmsvggelement.c
@@ -35,7 +35,7 @@ lsm_svg_g_element_get_node_name (LsmDomNode *node)
/* GGElement implementation */
-/* LsmSvgGraphic implementation */
+/* LsmSvgElement implementation */
/* LsmSvgGElement implementation */
@@ -52,6 +52,7 @@ lsm_svg_g_element_init (LsmSvgGElement *self)
/* LsmSvgGElement class */
+
static void
lsm_svg_g_element_class_init (LsmSvgGElementClass *s_g_class)
{
@@ -62,4 +63,4 @@ lsm_svg_g_element_class_init (LsmSvgGElementClass *s_g_class)
d_node_class->get_node_name = lsm_svg_g_element_get_node_name;
}
-G_DEFINE_TYPE (LsmSvgGElement, lsm_svg_g_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgGElement, lsm_svg_g_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvggelement.h b/src/lsmsvggelement.h
index f44e05a..cbb1ae1 100644
--- a/src/lsmsvggelement.h
+++ b/src/lsmsvggelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_G_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,11 +37,11 @@ G_BEGIN_DECLS
typedef struct _LsmSvgGElementClass LsmSvgGElementClass;
struct _LsmSvgGElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
};
struct _LsmSvgGElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_g_element_get_type (void);
diff --git a/src/lsmsvggradientelement.c b/src/lsmsvggradientelement.c
index 2b441b7..d7d1ef7 100644
--- a/src/lsmsvggradientelement.c
+++ b/src/lsmsvggradientelement.c
@@ -38,95 +38,94 @@ lsm_svg_gradient_element_can_append_child (LsmDomNode *parent, LsmDomNode *child
/* LsmSvgElement implementation */
static void
-_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
+lsm_svg_gradient_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgGradientElement *gradient = LSM_SVG_GRADIENT_ELEMENT (self);
- LsmSvgPatternUnits units;
- LsmSvgSpreadMethod method;
+ LsmSvgGradientElementClass *gradient_class = LSM_SVG_GRADIENT_ELEMENT_GET_CLASS (self);
- units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
- method = LSM_SVG_SPREAD_METHOD_PAD;
+ if (!gradient->enable_rendering)
+ return;
- 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);
+ gradient->enable_rendering = FALSE;
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
-static void
-_gradient_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
-{
- LsmSvgGradientElement *gradient = LSM_SVG_GRADIENT_ELEMENT (self);
- LsmDomNode *iter;
- double last_offset = 0.0;
-
- for (iter = LSM_DOM_NODE (self)->first_child; iter != NULL; iter = iter->next_sibling) {
- if (LSM_IS_SVG_STOP_ELEMENT (iter)) {
- LsmSvgStopElement *stop;
- const LsmSvgColor *color;
- double offset;
- double opacity;
-
- stop = LSM_SVG_STOP_ELEMENT (iter);
-
- offset = lsm_svg_stop_element_get_offset (stop);
- color = lsm_svg_stop_element_get_color (stop);
- opacity = lsm_svg_stop_element_get_opacity (stop);
-
- if (offset < last_offset)
- offset = last_offset;
- else
- last_offset = offset;
-
- lsm_debug ("[LsmSvgGradientElement::render] Add stop at %g (%g,%g,%g,%g)",
- offset, color->red, color->green, color->blue, opacity);
+ g_return_if_fail (gradient_class->create_gradient != NULL);
- lsm_svg_view_add_gradient_color_stop (view, offset, color, opacity);
- }
- }
+ gradient_class->create_gradient (self, view);
lsm_svg_view_set_gradient_properties (view,
gradient->spread_method.value,
gradient->units.value,
&gradient->transform.matrix);
+
+ LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);
+}
+
+static void
+lsm_svg_gradient_element_enable_rendering (LsmSvgElement *element)
+{
+ LSM_SVG_GRADIENT_ELEMENT (element)->enable_rendering = TRUE;
}
/* LsmSvgGradientElement implementation */
+static const LsmSvgPatternUnits units_default = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
+static const LsmSvgSpreadMethod spread_method_default = LSM_SVG_SPREAD_METHOD_PAD;
+static const LsmSvgMatrix matrix_default = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0, LSM_SVG_MATRIX_FLAGS_IDENTITY};
+
static void
lsm_svg_gradient_element_init (LsmSvgGradientElement *self)
{
+ self->enable_rendering = FALSE;
+ self->units.value = units_default;
+ self->spread_method.value = spread_method_default;
+ lsm_svg_matrix_init_identity (&self->transform.matrix);
}
/* LsmSvgGradientElement class */
+static const LsmAttributeInfos lsm_svg_gradient_element_attribute_infos[] = {
+ {
+ .name = "gradientUnits",
+ .attribute_offset = offsetof (LsmSvgGradientElement, units),
+ .trait_class = &lsm_svg_pattern_units_trait_class,
+ .trait_default = &units_default
+ },
+ {
+ .name = "gradientTransform",
+ .attribute_offset = offsetof (LsmSvgGradientElement, transform),
+ .trait_class = &lsm_svg_matrix_trait_class,
+ .trait_default = &matrix_default
+ },
+ {
+ .name = "spreadMethod",
+ .attribute_offset = offsetof (LsmSvgGradientElement, spread_method),
+ .trait_class = &lsm_svg_spread_method_trait_class,
+ .trait_default = &spread_method_default
+ },
+ {
+ .name = "xlink:href",
+ .attribute_offset = offsetof (LsmSvgGradientElement, href),
+ .trait_class = &lsm_null_trait_class
+ }
+};
+
static void
lsm_svg_gradient_element_class_init (LsmSvgGradientElementClass *klass)
{
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
d_node_class->can_append_child = lsm_svg_gradient_element_can_append_child;
- s_element_class->update = _gradient_element_update;
- s_element_class->render_paint = s_element_class->render;
- s_element_class->render = NULL;
- s_graphic_class->graphic_render = _gradient_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
-
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "gradientUnits",
- offsetof (LsmSvgGradientElement, units));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "gradientTransform",
- offsetof (LsmSvgGradientElement, transform));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "spreadMethod",
- offsetof (LsmSvgGradientElement, spread_method));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "xlink:href",
- offsetof (LsmSvgGradientElement, href));
+ s_element_class->render = lsm_svg_gradient_element_render;
+ s_element_class->enable_rendering = lsm_svg_gradient_element_enable_rendering;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_gradient_element_attribute_infos),
+ lsm_svg_gradient_element_attribute_infos);
}
-G_DEFINE_ABSTRACT_TYPE (LsmSvgGradientElement, lsm_svg_gradient_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_ABSTRACT_TYPE (LsmSvgGradientElement, lsm_svg_gradient_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvggradientelement.h b/src/lsmsvggradientelement.h
index cad2a35..6bb0c3a 100644
--- a/src/lsmsvggradientelement.h
+++ b/src/lsmsvggradientelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_GRADIENT_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,16 +37,20 @@ G_BEGIN_DECLS
typedef struct _LsmSvgGradientElementClass LsmSvgGradientElementClass;
struct _LsmSvgGradientElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
LsmSvgTransformAttribute transform;
- LsmDomEnumAttribute units;
- LsmDomEnumAttribute spread_method;
- LsmDomAttribute href;
+ LsmSvgPatternUnitsAttribute units;
+ LsmSvgSpreadMethodAtttribute spread_method;
+ LsmAttribute href;
+
+ gboolean enable_rendering;
};
struct _LsmSvgGradientElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
+
+ void (*create_gradient) (LsmSvgElement *self, LsmSvgView *view);
};
GType lsm_svg_gradient_element_get_type (void);
diff --git a/src/lsmsvgimageelement.c b/src/lsmsvgimageelement.c
index 61057fd..9ae0451 100644
--- a/src/lsmsvgimageelement.c
+++ b/src/lsmsvgimageelement.c
@@ -36,104 +36,75 @@ lsm_svg_image_element_get_node_name (LsmDomNode *node)
return "image";
}
-static gboolean
-lsm_svg_use_can_append_child (LsmDomNode *node, LsmDomNode *child)
-{
- return FALSE;
-}
-
-/* LsmSvgElement implementation */
-
static void
-lsm_svg_image_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
+lsm_svg_image_element_set_attribute (LsmDomElement *self, const char *name, const char *value)
{
LsmSvgImageElement *image_element = LSM_SVG_IMAGE_ELEMENT (self);
- LsmSvgLength length;
- const char *href;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&image_element->x, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&image_element->y, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&image_element->width, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&image_element->height, &length);
- lsm_svg_preserve_aspect_ratio_attribute_parse (&image_element->preserve_aspect_ratio);
+ LSM_DOM_ELEMENT_CLASS (parent_class)->set_attribute (self, name, value);
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-
- if (image_element->pixbuf != NULL) {
+ if (g_strcmp0 (name, "xlink:href") == 0 && image_element->pixbuf != NULL) {
g_object_unref (image_element->pixbuf);
image_element->pixbuf = NULL;
}
+}
- href = image_element->href.value;
+static gboolean
+lsm_svg_use_can_append_child (LsmDomNode *node, LsmDomNode *child)
+{
+ return FALSE;
+}
- if (href != NULL) {
- GdkPixbufLoader *loader;
- void *image_data;
- gsize data_size;
- int result;
+/* LsmSvgElement implementation */
- if (strncmp (href, "data:", 5) == 0) {
+/* LsmSvgGraphic implementation */
- lsm_debug ("[LsmSvgImageElement::update] Found inlined image");
+static void
+lsm_svg_image_element_render (LsmSvgElement *self, LsmSvgView *view)
+{
+ LsmSvgImageElement *image;
+ LsmBox viewport;
+ LsmBox viewbox;
- while (*href != '\0' && *href != ',')
- href++;
+ image = LSM_SVG_IMAGE_ELEMENT (self);
- image_data = g_base64_decode (href, &data_size);
- } else {
- image_data = NULL;
- data_size = 0;
- }
+ if (image->pixbuf == NULL) {
+ LsmDomDocument *document;
+ char *data;
+ gsize size;
+
+ document = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
+ data = lsm_dom_document_get_href_data (document, image->href.value, &size);
+
+ if (data != NULL) {
+ GdkPixbufLoader *loader;
+ int result;
- if (image_data != NULL) {
loader = gdk_pixbuf_loader_new ();
- result = gdk_pixbuf_loader_write (loader, image_data, data_size, NULL);
+ result = gdk_pixbuf_loader_write (loader, (guchar *) data, size, NULL);
- g_free (image_data);
+ g_free (data);
gdk_pixbuf_loader_close (loader, NULL);
- image_element->pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
- g_object_ref (image_element->pixbuf);
+ image->pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ g_object_ref (image->pixbuf);
g_object_unref (loader);
}
}
-}
-
-/* LsmSvgGraphic implementation */
-
-static void
-lsm_svg_image_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
-{
- LsmSvgImageElement *image;
- LsmBox viewport;
- LsmBox viewbox;
- image = LSM_SVG_IMAGE_ELEMENT (self);
if (image->pixbuf == NULL)
return;
- viewport.x = lsm_svg_view_normalize_length (view, &image->x.length.base,
+ viewport.x = lsm_svg_view_normalize_length (view, &image->x.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- viewport.y = lsm_svg_view_normalize_length (view, &image->y.length.base,
+ viewport.y = lsm_svg_view_normalize_length (view, &image->y.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- viewport.width = lsm_svg_view_normalize_length (view, &image->width.length.base,
+ viewport.width = lsm_svg_view_normalize_length (view, &image->width.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- viewport.height = lsm_svg_view_normalize_length (view, &image->height.length.base,
+ viewport.height = lsm_svg_view_normalize_length (view, &image->height.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
lsm_debug ("[LsmSvgImageElement::graphic_render] viewport %g, %g, %g, %g",
@@ -159,10 +130,22 @@ lsm_svg_image_element_new (void)
return g_object_new (LSM_TYPE_SVG_IMAGE_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+static const LsmSvgPreserveAspectRatio preserve_aspect_ratio_default = {
+ .defer = FALSE,
+ .align = LSM_SVG_ALIGN_X_MID_Y_MID,
+ .meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET
+};
+
static void
lsm_svg_image_element_init (LsmSvgImageElement *self)
{
self->pixbuf = NULL;
+ self->x.length = length_default;
+ self->y.length = length_default;
+ self->width.length = length_default;
+ self->height.length = length_default;
+ self->preserve_aspect_ratio.value = preserve_aspect_ratio_default;
}
static void
@@ -172,17 +155,57 @@ lsm_svg_image_element_finalize (GObject *gobject)
if (image->pixbuf != NULL)
g_object_unref (image->pixbuf);
+
+ parent_class->finalize (gobject);
}
/* LsmSvgImageElement class */
+static const LsmAttributeInfos lsm_svg_image_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgImageElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgImageElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "width",
+ .attribute_offset = offsetof (LsmSvgImageElement, width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "height",
+ .attribute_offset = offsetof (LsmSvgImageElement, height),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "xlink:href",
+ .attribute_offset = offsetof (LsmSvgImageElement, href),
+ .trait_class = &lsm_null_trait_class
+ },
+ {
+ .name = "preserveAspectRatio",
+ .attribute_offset = offsetof (LsmSvgImageElement, preserve_aspect_ratio),
+ .trait_class = &lsm_svg_preserve_aspect_ratio_trait_class,
+ .trait_default = &preserve_aspect_ratio_default
+ }
+};
+
static void
lsm_svg_image_element_class_init (LsmSvgImageElementClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
+ LsmDomElementClass *d_element_class = LSM_DOM_ELEMENT_CLASS (klass);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
@@ -191,24 +214,14 @@ lsm_svg_image_element_class_init (LsmSvgImageElementClass *klass)
d_node_class->get_node_name = lsm_svg_image_element_get_node_name;
d_node_class->can_append_child = lsm_svg_use_can_append_child;
- s_element_class->update = lsm_svg_image_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_image_element_graphic_render;
+ d_element_class->set_attribute = lsm_svg_image_element_set_attribute;
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_image_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x",
- offsetof (LsmSvgImageElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgImageElement, y));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgImageElement, width));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgImageElement, height));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "xlink:href",
- offsetof (LsmSvgImageElement, href));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "preserveAspectRatio",
- offsetof (LsmSvgImageElement, preserve_aspect_ratio));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_image_element_attribute_infos),
+ lsm_svg_image_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgImageElement, lsm_svg_image_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgImageElement, lsm_svg_image_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgimageelement.h b/src/lsmsvgimageelement.h
index d2d63d2..fc637cf 100644
--- a/src/lsmsvgimageelement.h
+++ b/src/lsmsvgimageelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_IMAGE_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
G_BEGIN_DECLS
@@ -38,14 +38,14 @@ G_BEGIN_DECLS
typedef struct _LsmSvgImageElementClass LsmSvgImageElementClass;
struct _LsmSvgImageElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute x;
- LsmSvgAnimatedLengthAttribute y;
- LsmSvgAnimatedLengthAttribute width;
- LsmSvgAnimatedLengthAttribute height;
+ LsmSvgLengthAttribute x;
+ LsmSvgLengthAttribute y;
+ LsmSvgLengthAttribute width;
+ LsmSvgLengthAttribute height;
- LsmDomAttribute href;
+ LsmAttribute href;
LsmSvgPreserveAspectRatioAttribute preserve_aspect_ratio;
@@ -53,7 +53,7 @@ struct _LsmSvgImageElement {
};
struct _LsmSvgImageElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_image_element_get_type (void);
diff --git a/src/lsmsvglineargradientelement.c b/src/lsmsvglineargradientelement.c
index 2fd37cf..c27f650 100644
--- a/src/lsmsvglineargradientelement.c
+++ b/src/lsmsvglineargradientelement.c
@@ -37,32 +37,7 @@ lsm_svg_linear_gradient_element_get_node_name (LsmDomNode *node)
/* GLinearGradientElement implementation */
static void
-_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_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->x1, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->y1, &length);
-
- length.value_unit = 100.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->x2, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&linear->y2, &length);
-}
-
-static void
-_linear_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_linear_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgLinearGradientElement *linear = LSM_SVG_LINEAR_GRADIENT_ELEMENT (self);
gboolean is_object_bounding_box;
@@ -77,10 +52,10 @@ _linear_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
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);
+ x1 = lsm_svg_view_normalize_length (view, &linear->x1.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y1 = lsm_svg_view_normalize_length (view, &linear->y1.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ x2 = lsm_svg_view_normalize_length (view, &linear->x2.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y2 = lsm_svg_view_normalize_length (view, &linear->y2.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
lsm_debug ("[LsmSvgLinearGradientElement::render] Create linear %g, %g, %g, %g",
x1, y1, x2, y2);
@@ -89,8 +64,6 @@ _linear_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
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);
}
/* LsmSvgLinearGradientElement implementation */
@@ -101,25 +74,60 @@ lsm_svg_linear_gradient_element_new (void)
return g_object_new (LSM_TYPE_SVG_LINEAR_GRADIENT_ELEMENT, NULL);
}
+static const LsmSvgLength x1_y1_y2_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+static const LsmSvgLength x2_default = { .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+
static void
lsm_svg_linear_gradient_element_init (LsmSvgLinearGradientElement *self)
{
-
+ self->x1.length = x1_y1_y2_default;
+ self->y1.length = x1_y1_y2_default;
+ self->x2.length = x2_default;
+ self->y2.length = x1_y1_y2_default;
}
static void
lsm_svg_linear_gradient_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgLinearGradientElement class */
+static const LsmAttributeInfos lsm_svg_linear_gradient_element_attribute_infos[] = {
+ {
+ .name = "x1",
+ .attribute_offset = offsetof (LsmSvgLinearGradientElement, x1),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x1_y1_y2_default
+ },
+ {
+ .name = "y1",
+ .attribute_offset = offsetof (LsmSvgLinearGradientElement, y1),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x1_y1_y2_default
+ },
+ {
+ .name = "x2",
+ .attribute_offset = offsetof (LsmSvgLinearGradientElement, x2),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x2_default
+ },
+ {
+ .name = "y2",
+ .attribute_offset = offsetof (LsmSvgLinearGradientElement, y2),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x1_y1_y2_default
+ }
+};
+
static void
lsm_svg_linear_gradient_element_class_init (LsmSvgLinearGradientElementClass *s_svg_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_svg_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_svg_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_svg_class);
+ LsmSvgGradientElementClass *s_gradient_class = LSM_SVG_GRADIENT_ELEMENT_CLASS (s_svg_class);
parent_class = g_type_class_peek_parent (s_svg_class);
@@ -127,19 +135,13 @@ lsm_svg_linear_gradient_element_class_init (LsmSvgLinearGradientElementClass *s_
d_node_class->get_node_name = lsm_svg_linear_gradient_element_get_node_name;
- s_element_class->update = _linear_gradient_element_update;
- s_element_class->render_paint = _linear_gradient_element_render_paint;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_linear_gradient_element_attribute_infos),
+ lsm_svg_linear_gradient_element_attribute_infos);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x1",
- offsetof (LsmSvgLinearGradientElement, x1));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y1",
- offsetof (LsmSvgLinearGradientElement, y1));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x2",
- offsetof (LsmSvgLinearGradientElement, x2));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y2",
- offsetof (LsmSvgLinearGradientElement, y2));
+ s_gradient_class->create_gradient = lsm_svg_linear_gradient_element_create_gradient;
}
G_DEFINE_TYPE (LsmSvgLinearGradientElement, lsm_svg_linear_gradient_element, LSM_TYPE_SVG_GRADIENT_ELEMENT)
diff --git a/src/lsmsvglineargradientelement.h b/src/lsmsvglineargradientelement.h
index 4a5127e..7797355 100644
--- a/src/lsmsvglineargradientelement.h
+++ b/src/lsmsvglineargradientelement.h
@@ -39,10 +39,10 @@ typedef struct _LsmSvgLinearGradientElementClass LsmSvgLinearGradientElementClas
struct _LsmSvgLinearGradientElement {
LsmSvgGradientElement gradient;
- LsmSvgAnimatedLengthAttribute x1;
- LsmSvgAnimatedLengthAttribute y1;
- LsmSvgAnimatedLengthAttribute x2;
- LsmSvgAnimatedLengthAttribute y2;
+ LsmSvgLengthAttribute x1;
+ LsmSvgLengthAttribute y1;
+ LsmSvgLengthAttribute x2;
+ LsmSvgLengthAttribute y2;
};
struct _LsmSvgLinearGradientElementClass {
diff --git a/src/lsmsvglineelement.c b/src/lsmsvglineelement.c
index a272bb3..c7f5b70 100644
--- a/src/lsmsvglineelement.c
+++ b/src/lsmsvglineelement.c
@@ -35,45 +35,20 @@ lsm_svg_line_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
-static void
-lsm_svg_line_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgLineElement *line = LSM_SVG_LINE_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->x1, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->y1, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->x2, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&line->y2, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
static void
-lsm_svg_line_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_line_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgLineElement *line = LSM_SVG_LINE_ELEMENT (self);
double x1, y1, x2, y2;
- 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);
+ x1 = lsm_svg_view_normalize_length (view, &line->x1.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y1 = lsm_svg_view_normalize_length (view, &line->y1.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ x2 = lsm_svg_view_normalize_length (view, &line->x2.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y2 = lsm_svg_view_normalize_length (view, &line->y2.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- lsm_debug ("[LsmSvgLineElement::graphic_render] %g, %g, %g, %g", x1, y1, x2, y2);
+ lsm_debug ("[LsmSvgLineElement::render] %g, %g, %g, %g", x1, y1, x2, y2);
lsm_svg_view_show_line (view, x1, y1, x2, y2);
}
@@ -86,38 +61,62 @@ lsm_svg_line_element_new (void)
return g_object_new (LSM_TYPE_SVG_LINE_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+
static void
lsm_svg_line_element_init (LsmSvgLineElement *self)
{
+ self->x1.length = length_default;
+ self->x2.length = length_default;
+ self->y1.length = length_default;
+ self->y2.length = length_default;
}
/* LsmSvgLineElement class */
+static const LsmAttributeInfos lsm_svg_line_element_attribute_infos[] = {
+ {
+ .name = "x1",
+ .attribute_offset = offsetof (LsmSvgLineElement, x1),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y1",
+ .attribute_offset = offsetof (LsmSvgLineElement, y1),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "x2",
+ .attribute_offset = offsetof (LsmSvgLineElement, x2),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y2",
+ .attribute_offset = offsetof (LsmSvgLineElement, y2),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ }
+};
+
static void
lsm_svg_line_element_class_init (LsmSvgLineElementClass *s_rect_class)
{
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
d_node_class->get_node_name = lsm_svg_line_element_get_node_name;
- s_element_class->update = lsm_svg_line_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_line_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_line_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x1",
- offsetof (LsmSvgLineElement, x1));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y1",
- offsetof (LsmSvgLineElement, y1));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x2",
- offsetof (LsmSvgLineElement, x2));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y2",
- offsetof (LsmSvgLineElement, y2));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_line_element_attribute_infos),
+ lsm_svg_line_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgLineElement, lsm_svg_line_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgLineElement, lsm_svg_line_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvglineelement.h b/src/lsmsvglineelement.h
index deeff47..45b9234 100644
--- a/src/lsmsvglineelement.h
+++ b/src/lsmsvglineelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_LINE_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,16 +37,16 @@ G_BEGIN_DECLS
typedef struct _LsmSvgLineElementClass LsmSvgLineElementClass;
struct _LsmSvgLineElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute x1;
- LsmSvgAnimatedLengthAttribute y1;
- LsmSvgAnimatedLengthAttribute x2;
- LsmSvgAnimatedLengthAttribute y2;
+ LsmSvgLengthAttribute x1;
+ LsmSvgLengthAttribute y1;
+ LsmSvgLengthAttribute x2;
+ LsmSvgLengthAttribute y2;
};
struct _LsmSvgLineElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_line_element_get_type (void);
diff --git a/src/lsmsvgmaskelement.c b/src/lsmsvgmaskelement.c
index c65541d..16cd1d9 100644
--- a/src/lsmsvgmaskelement.c
+++ b/src/lsmsvgmaskelement.c
@@ -37,44 +37,23 @@ _mask_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
static void
-_mask_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgMaskElement *mask = LSM_SVG_MASK_ELEMENT (self);
- LsmSvgPatternUnits units;
- LsmSvgLength length;
-
- units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
- lsm_svg_pattern_units_attribute_parse (&mask->units, &units);
-
- units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
- lsm_svg_pattern_units_attribute_parse (&mask->content_units, &units);
-
- length.value_unit = -10.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&mask->x, &length);
-
- length.value_unit = -10.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&mask->y, &length);
-
- length.value_unit = 120.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&mask->width, &length);
-
- length.value_unit = 120.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&mask->height, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
-static void
-_mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_mask_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgMaskElement *mask = LSM_SVG_MASK_ELEMENT (self);
gboolean is_object_bounding_box;
LsmBox viewport;
const LsmBox *mask_extents;
+ LsmSvgStyle *style;
+
+ if (!mask->enable_rendering) {
+ lsm_debug ("[LsmSvgMaskElement::render] Direct rendering not allowed");
+ return;
+ } else {
+ mask->enable_rendering = FALSE;
+ }
+
+ style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
+ lsm_svg_view_push_style (view, style);
mask_extents = lsm_svg_view_get_pattern_extents (view);
@@ -86,13 +65,13 @@ _mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_push_viewbox (view, &viewbox);
}
- viewport.x = lsm_svg_view_normalize_length (view, &mask->x.length.base,
+ viewport.x = lsm_svg_view_normalize_length (view, &mask->x.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- viewport.y = lsm_svg_view_normalize_length (view, &mask->y.length.base,
+ viewport.y = lsm_svg_view_normalize_length (view, &mask->y.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- viewport.width = lsm_svg_view_normalize_length (view, &mask->width.length.base,
+ viewport.width = lsm_svg_view_normalize_length (view, &mask->width.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- viewport.height = lsm_svg_view_normalize_length (view, &mask->height.length.base,
+ viewport.height = lsm_svg_view_normalize_length (view, &mask->height.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
if (is_object_bounding_box) {
@@ -107,7 +86,7 @@ _mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
if (viewport.width <= 0.0 || viewport.height <= 0.0)
return;
- lsm_debug ("[LsmSvgMaskElement::render_paint] Create mask x = %g, y = %g, w = %g, h = %g",
+ lsm_debug ("[LsmSvgMaskElement::render] Create mask x = %g, y = %g, w = %g, h = %g",
viewport.x, viewport.y, viewport.width, viewport.height);
lsm_svg_view_create_surface_pattern (view, &viewport,
@@ -126,7 +105,7 @@ _mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_push_viewbox (view, &viewbox);
lsm_svg_view_push_matrix (view, &matrix);
- lsm_debug ("[LsmSvgMaskElement::render_paint] object_bounding_box"
+ lsm_debug ("[LsmSvgMaskElement::render] object_bounding_box"
" x_scale = %g, y_scale = %g, x_offset = %g, y_offset = %g",
mask_extents->width, mask_extents->height,
mask_extents->x, mask_extents->y);
@@ -138,6 +117,15 @@ _mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_pop_matrix (view);
lsm_svg_view_pop_viewbox (view);
}
+
+ lsm_svg_view_pop_style (view);
+ lsm_svg_style_free (style);
+}
+
+static void
+lsm_svg_mask_element_enable_rendering (LsmSvgElement *element)
+{
+ LSM_SVG_MASK_ELEMENT (element)->enable_rendering = TRUE;
}
/* LsmSvgMaskElement implementation */
@@ -148,22 +136,64 @@ lsm_svg_mask_element_new (void)
return g_object_new (LSM_TYPE_SVG_MASK_ELEMENT, NULL);
}
+static const LsmSvgLength x_y_default = { .value_unit = -10.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+static const LsmSvgLength width_height_default ={ .value_unit = 120.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+static const LsmSvgPatternUnits units_default = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
+static const LsmSvgPatternUnits content_units_default = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
+
static void
lsm_svg_mask_element_init (LsmSvgMaskElement *self)
{
- /* Hack - Force the creation of the attribute bags,
- making sure the properties will be inherited from the
- mask element ancestor, not the referencing one. */
-
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "transform", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "font-family", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stop-color", NULL);
+ self->enable_rendering = FALSE;
+ self->x.length = x_y_default;
+ self->y.length = x_y_default;
+ self->width.length = width_height_default;
+ self->height.length = width_height_default;
+ self->units.value = units_default;
+ self->content_units.value = content_units_default;
}
/* LsmSvgMaskElement class */
+static const LsmAttributeInfos lsm_svg_mask_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgMaskElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x_y_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgMaskElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x_y_default
+ },
+ {
+ .name = "width",
+ .attribute_offset = offsetof (LsmSvgMaskElement, width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &width_height_default
+ },
+ {
+ .name = "height",
+ .attribute_offset = offsetof (LsmSvgMaskElement, height),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &width_height_default
+ },
+ {
+ .name = "maskUnits",
+ .attribute_offset = offsetof (LsmSvgMaskElement, units),
+ .trait_class = &lsm_svg_pattern_units_trait_class,
+ .trait_default = &units_default
+ },
+ {
+ .name = "maskContentUnits",
+ .attribute_offset = offsetof (LsmSvgMaskElement, content_units),
+ .trait_class = &lsm_svg_pattern_units_trait_class,
+ .trait_default = &content_units_default
+ }
+};
+
static void
lsm_svg_mask_element_class_init (LsmSvgMaskElementClass *klass)
{
@@ -174,24 +204,13 @@ lsm_svg_mask_element_class_init (LsmSvgMaskElementClass *klass)
d_node_class->get_node_name = _mask_element_get_node_name;
- s_element_class->update = _mask_element_update;
- s_element_class->render_paint = _mask_element_render_paint;
- s_element_class->render = NULL;
-
- 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 (LsmSvgMaskElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgMaskElement, y));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgMaskElement, width));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgMaskElement, height));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "maskUnits",
- offsetof (LsmSvgMaskElement, units));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "maskContentUnits",
- offsetof (LsmSvgMaskElement, content_units));
+ s_element_class->render = lsm_svg_mask_element_render;
+ s_element_class->enable_rendering = lsm_svg_mask_element_enable_rendering;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_mask_element_attribute_infos),
+ lsm_svg_mask_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgMaskElement, lsm_svg_mask_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgMaskElement, lsm_svg_mask_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgmaskelement.h b/src/lsmsvgmaskelement.h
index c51338a..fe6a81e 100644
--- a/src/lsmsvgmaskelement.h
+++ b/src/lsmsvgmaskelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_MASK_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,18 +37,20 @@ G_BEGIN_DECLS
typedef struct _LsmSvgMaskElementClass LsmSvgMaskElementClass;
struct _LsmSvgMaskElement {
- LsmSvgGraphic graphic;
-
- LsmSvgAnimatedLengthAttribute x;
- LsmSvgAnimatedLengthAttribute y;
- LsmSvgAnimatedLengthAttribute width;
- LsmSvgAnimatedLengthAttribute height;
- LsmDomEnumAttribute units;
- LsmDomEnumAttribute content_units;
+ LsmSvgElement element;
+
+ LsmSvgLengthAttribute x;
+ LsmSvgLengthAttribute y;
+ LsmSvgLengthAttribute width;
+ LsmSvgLengthAttribute height;
+ LsmSvgPatternUnitsAttribute units;
+ LsmSvgPatternUnitsAttribute content_units;
+
+ gboolean enable_rendering;
};
struct _LsmSvgMaskElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_mask_element_get_type (void);
diff --git a/src/lsmsvgmatrix.c b/src/lsmsvgmatrix.c
index 99edea5..214544e 100644
--- a/src/lsmsvgmatrix.c
+++ b/src/lsmsvgmatrix.c
@@ -22,6 +22,12 @@
#include <lsmsvgmatrix.h>
#include <math.h>
+gboolean
+lsm_svg_matrix_is_identity (const LsmSvgMatrix *matrix)
+{
+ return ((matrix->flags & LSM_SVG_MATRIX_FLAGS_IDENTITY) != 0);
+}
+
void
lsm_svg_matrix_init (LsmSvgMatrix *matrix, double a, double b, double c, double d, double e, double f)
{
@@ -31,12 +37,14 @@ lsm_svg_matrix_init (LsmSvgMatrix *matrix, double a, double b, double c, double
matrix->d = d;
matrix->e = e;
matrix->f = f;
+ matrix->flags = 0;
}
void
lsm_svg_matrix_init_identity (LsmSvgMatrix *matrix)
{
lsm_svg_matrix_init (matrix, 1, 0, 0, 1, 0, 0);
+ matrix->flags |= LSM_SVG_MATRIX_FLAGS_IDENTITY;
}
void
@@ -125,6 +133,15 @@ lsm_svg_matrix_multiply (LsmSvgMatrix *result, const LsmSvgMatrix *a, const LsmS
{
LsmSvgMatrix r;
+ if ((a->flags & LSM_SVG_MATRIX_FLAGS_IDENTITY) != 0) {
+ *result = *b;
+ return;
+ }
+ if ((b->flags & LSM_SVG_MATRIX_FLAGS_IDENTITY) != 0) {
+ *result = *a;
+ return;
+ }
+
r.a = a->a * b->a + a->b * b->c;
r.b = a->a * b->b + a->b * b->d;
@@ -134,6 +151,8 @@ lsm_svg_matrix_multiply (LsmSvgMatrix *result, const LsmSvgMatrix *a, const LsmS
r.e = a->e * b->a + a->f * b->c + b->e;
r.f = a->e * b->b + a->f * b->d + b->f;
+ r.flags = 0;
+
*result = r;
}
@@ -143,6 +162,9 @@ lsm_svg_matrix_transform_point (const LsmSvgMatrix *matrix, double *x, double *y
double new_x;
double new_y;
+ if ((matrix->flags & LSM_SVG_MATRIX_FLAGS_IDENTITY) != 0)
+ return;
+
new_x = (matrix->a * *x + matrix->c * *y) + matrix->e;
new_y = (matrix->b * *x + matrix->d * *y) + matrix->f;
@@ -156,6 +178,9 @@ lsm_svg_matrix_transform_bounding_box (const LsmSvgMatrix *matrix, double *x1, d
double x12, y12, x21, y21;
double x_min, y_min, x_max, y_max;
+ if ((matrix->flags & LSM_SVG_MATRIX_FLAGS_IDENTITY) != 0)
+ return;
+
x12 = *x1;
y12 = *y2;
x21 = *x2;
diff --git a/src/lsmsvgmatrix.h b/src/lsmsvgmatrix.h
index 3a4cc5a..2fad642 100644
--- a/src/lsmsvgmatrix.h
+++ b/src/lsmsvgmatrix.h
@@ -24,10 +24,17 @@
#include <lsmsvg.h>
+typedef enum {
+ LSM_SVG_MATRIX_FLAGS_IDENTITY = 1 << 0
+} LsmSvgMatrixFlags;
+
typedef struct {
double a, b, c, d, e, f;
+ LsmSvgMatrixFlags flags;
} LsmSvgMatrix;
+gboolean lsm_svg_matrix_is_identity (const LsmSvgMatrix *matrix);
+
void lsm_svg_matrix_init (LsmSvgMatrix *matrix, double a, double b,
double c, double d,
double e, double f);
diff --git a/src/lsmsvgpathelement.c b/src/lsmsvgpathelement.c
index e7e55d1..eb1d540 100644
--- a/src/lsmsvgpathelement.c
+++ b/src/lsmsvgpathelement.c
@@ -36,15 +36,15 @@ lsm_svg_path_element_get_node_name (LsmDomNode *node)
/* LsmSvgGraphic implementation */
static void
-lsm_svg_path_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_path_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgPathElement *path;
path = LSM_SVG_PATH_ELEMENT (self);
- lsm_debug ("[LsmSvgPathElement::graphic_render]");
+ lsm_debug ("[LsmSvgPathElement::render]");
- lsm_svg_view_show_path (view, lsm_dom_attribute_get_value (&path->d));
+ lsm_svg_view_show_path (view, path->d.value);
}
/* LsmSvgPathElement implementation */
@@ -63,17 +63,25 @@ lsm_svg_path_element_init (LsmSvgPathElement *self)
static void
lsm_svg_path_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgPathElement class */
+static const LsmAttributeInfos lsm_svg_path_element_attribute_infos[] = {
+ {
+ .name = "d",
+ .attribute_offset = offsetof (LsmSvgPathElement, d),
+ .trait_class = &lsm_null_trait_class
+ }
+};
+
static void
lsm_svg_path_element_class_init (LsmSvgPathElementClass *s_rect_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_rect_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
@@ -81,12 +89,12 @@ lsm_svg_path_element_class_init (LsmSvgPathElementClass *s_rect_class)
d_node_class->get_node_name = lsm_svg_path_element_get_node_name;
- s_graphic_class->graphic_render = lsm_svg_path_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_path_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "d",
- offsetof (LsmSvgPathElement, d));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_path_element_attribute_infos),
+ lsm_svg_path_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgPathElement, lsm_svg_path_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgPathElement, lsm_svg_path_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgpathelement.h b/src/lsmsvgpathelement.h
index 0e9afa0..cf34419 100644
--- a/src/lsmsvgpathelement.h
+++ b/src/lsmsvgpathelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_PATH_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,14 +37,14 @@ G_BEGIN_DECLS
typedef struct _LsmSvgPathElementClass LsmSvgPathElementClass;
struct _LsmSvgPathElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmDomAttribute d;
- LsmDomDoubleAttribute path_length;
+ LsmAttribute d;
+ LsmSvgDoubleAttribute path_length;
};
struct _LsmSvgPathElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_path_element_get_type (void);
diff --git a/src/lsmsvgpatternelement.c b/src/lsmsvgpatternelement.c
index 551da38..4999c01 100644
--- a/src/lsmsvgpatternelement.c
+++ b/src/lsmsvgpatternelement.c
@@ -37,50 +37,25 @@ _pattern_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
static void
-_pattern_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgPatternElement *pattern = LSM_SVG_PATTERN_ELEMENT (self);
- LsmSvgPatternUnits units;
- LsmSvgLength length;
-
- units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
- lsm_svg_pattern_units_attribute_parse (&pattern->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_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->x, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->y, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->width, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&pattern->height, &length);
-
- lsm_svg_viewbox_attribute_parse (&pattern->viewbox);
- lsm_svg_preserve_aspect_ratio_attribute_parse (&pattern->preserve_aspect_ratio);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
-static void
-_pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_pattern_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgPatternElement *pattern = LSM_SVG_PATTERN_ELEMENT (self);
gboolean is_object_bounding_box;
gboolean is_viewbox_defined;
LsmBox viewport;
const LsmBox *pattern_extents;
+ LsmSvgStyle *style;
+
+ if (!pattern->enable_rendering) {
+ lsm_debug ("[LsmSvgPatternElement::render] Direct rendering not allowed");
+ return;
+ } else {
+ pattern->enable_rendering = FALSE;
+ }
+
+
+ style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
+ lsm_svg_view_push_style (view, style);
pattern_extents = lsm_svg_view_get_pattern_extents (view);
@@ -92,13 +67,13 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_push_viewbox (view, &viewbox);
}
- viewport.x = lsm_svg_view_normalize_length (view, &pattern->x.length.base,
+ viewport.x = lsm_svg_view_normalize_length (view, &pattern->x.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- viewport.y = lsm_svg_view_normalize_length (view, &pattern->y.length.base,
+ viewport.y = lsm_svg_view_normalize_length (view, &pattern->y.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- viewport.width = lsm_svg_view_normalize_length (view, &pattern->width.length.base,
+ viewport.width = lsm_svg_view_normalize_length (view, &pattern->width.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- viewport.height = lsm_svg_view_normalize_length (view, &pattern->height.length.base,
+ viewport.height = lsm_svg_view_normalize_length (view, &pattern->height.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
if (is_object_bounding_box) {
@@ -113,7 +88,7 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
if (viewport.width <= 0.0 || viewport.height <= 0.0)
return;
- lsm_debug ("[LsmSvgPatternElement::render_paint] Create pattern x = %g, y = %g, w = %g, h = %g",
+ lsm_debug ("[LsmSvgPatternElement::render] Create pattern x = %g, y = %g, w = %g, h = %g",
viewport.x, viewport.y, viewport.width, viewport.height);
lsm_svg_view_create_surface_pattern (view, &viewport,
@@ -133,13 +108,13 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_push_viewbox (view, &viewbox);
lsm_svg_view_push_matrix (view, &matrix);
- lsm_debug ("[LsmSvgPatternElement::render_paint] object_bounding_box"
+ lsm_debug ("[LsmSvgPatternElement::render] object_bounding_box"
" x_scale = %g, y_scale = %g, x_offset = %g, y_offset = %g",
pattern_extents->width, pattern_extents->height,
pattern_extents->x, pattern_extents->y);
}
- is_viewbox_defined = lsm_dom_attribute_is_defined ((LsmDomAttribute *) &pattern->viewbox);
+ is_viewbox_defined = lsm_attribute_is_defined (&pattern->viewbox.base);
if (!(is_viewbox_defined) ||
(is_viewbox_defined && pattern->viewbox.value.width > 0.0 && pattern->viewbox.value.height > 0.0)) {
@@ -156,6 +131,15 @@ _pattern_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
lsm_svg_view_pop_matrix (view);
lsm_svg_view_pop_viewbox (view);
}
+
+ lsm_svg_view_pop_style (view);
+ lsm_svg_style_free (style);
+}
+
+static void
+lsm_svg_pattern_element_enable_rendering (LsmSvgElement *element)
+{
+ LSM_SVG_PATTERN_ELEMENT (element)->enable_rendering = TRUE;
}
/* LsmSvgPatternElement implementation */
@@ -166,22 +150,95 @@ lsm_svg_pattern_element_new (void)
return g_object_new (LSM_TYPE_SVG_PATTERN_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+static const LsmSvgMatrix matrix_default = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0, LSM_SVG_MATRIX_FLAGS_IDENTITY};
+static const LsmBox viewbox_default = {0.0, 0.0, 0.0, 0.0};
+static const LsmSvgPatternUnits units_default = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
+static const LsmSvgPatternUnits content_units_default = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
+static const LsmSvgPreserveAspectRatio preserve_aspect_ratio_default = {
+ .defer = FALSE,
+ .align = LSM_SVG_ALIGN_X_MID_Y_MID,
+ .meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET
+};
+
static void
lsm_svg_pattern_element_init (LsmSvgPatternElement *self)
{
- /* Hack - Force the creation of the attribute bags,
- making sure the properties will be inherited from the
- pattern element ancestor, not the referencing one. */
-
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "transform", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "font-family", NULL);
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stop-color", NULL);
+ self->enable_rendering = FALSE;
+ self->x.length = length_default;
+ self->y.length = length_default;
+ self->width.length = length_default;
+ self->height.length = length_default;
+ self->transform.matrix = matrix_default;
+ self->units.value = units_default;
+ self->content_units.value = content_units_default;
+ self->preserve_aspect_ratio.value = preserve_aspect_ratio_default;
}
/* LsmSvgPatternElement class */
+static const LsmAttributeInfos lsm_svg_pattern_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgPatternElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgPatternElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "width",
+ .attribute_offset = offsetof (LsmSvgPatternElement, width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "height",
+ .attribute_offset = offsetof (LsmSvgPatternElement, height),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "patternUnits",
+ .attribute_offset = offsetof (LsmSvgPatternElement, units),
+ .trait_class = &lsm_svg_pattern_units_trait_class,
+ .trait_default = &units_default
+ },
+ {
+ .name = "patternContentUnits",
+ .attribute_offset = offsetof (LsmSvgPatternElement, content_units),
+ .trait_class = &lsm_svg_pattern_units_trait_class,
+ .trait_default = &content_units_default
+ },
+ {
+ .name = "patternTransform",
+ .attribute_offset = offsetof (LsmSvgPatternElement, transform),
+ .trait_class = &lsm_svg_matrix_trait_class,
+ .trait_default = &matrix_default
+ },
+ {
+ .name = "xlink:href",
+ .attribute_offset = offsetof (LsmSvgPatternElement, href),
+ .trait_class = &lsm_null_trait_class
+ },
+ {
+ .name = "viewBox",
+ .attribute_offset = offsetof (LsmSvgPatternElement, viewbox),
+ .trait_class = &lsm_box_trait_class,
+ .trait_default = &viewbox_default
+ },
+ {
+ .name = "preserveAspectRatio",
+ .attribute_offset = offsetof (LsmSvgPatternElement, preserve_aspect_ratio),
+ .trait_class = &lsm_svg_preserve_aspect_ratio_trait_class,
+ .trait_default = &preserve_aspect_ratio_default
+ }
+};
+
static void
lsm_svg_pattern_element_class_init (LsmSvgPatternElementClass *klass)
{
@@ -192,32 +249,13 @@ lsm_svg_pattern_element_class_init (LsmSvgPatternElementClass *klass)
d_node_class->get_node_name = _pattern_element_get_node_name;
- s_element_class->update = _pattern_element_update;
- s_element_class->render_paint = _pattern_element_render_paint;
- s_element_class->render = NULL;
-
- 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 (LsmSvgPatternElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgPatternElement, y));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgPatternElement, width));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgPatternElement, height));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "patternUnits",
- offsetof (LsmSvgPatternElement, units));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "patternContentUnits",
- offsetof (LsmSvgPatternElement, content_units));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "patternTransform",
- offsetof (LsmSvgPatternElement, transform));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "xlink:href",
- offsetof (LsmSvgPatternElement, href));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "viewBox",
- offsetof (LsmSvgPatternElement, viewbox));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "preserveAspectRatio",
- offsetof (LsmSvgPatternElement, preserve_aspect_ratio));
+ s_element_class->render = lsm_svg_pattern_element_render;
+ s_element_class->enable_rendering = lsm_svg_pattern_element_enable_rendering;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_pattern_element_attribute_infos),
+ lsm_svg_pattern_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgPatternElement, lsm_svg_pattern_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgPatternElement, lsm_svg_pattern_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgpatternelement.h b/src/lsmsvgpatternelement.h
index b2c17bd..6c717a4 100644
--- a/src/lsmsvgpatternelement.h
+++ b/src/lsmsvgpatternelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_PATTERN_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,23 +37,25 @@ G_BEGIN_DECLS
typedef struct _LsmSvgPatternElementClass LsmSvgPatternElementClass;
struct _LsmSvgPatternElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute x;
- LsmSvgAnimatedLengthAttribute y;
- LsmSvgAnimatedLengthAttribute width;
- LsmSvgAnimatedLengthAttribute height;
+ LsmSvgLengthAttribute x;
+ LsmSvgLengthAttribute y;
+ LsmSvgLengthAttribute width;
+ LsmSvgLengthAttribute height;
LsmSvgTransformAttribute transform;
- LsmDomEnumAttribute units;
- LsmDomEnumAttribute content_units;
- LsmDomAttribute href;
+ LsmSvgPatternUnitsAttribute units;
+ LsmSvgPatternUnitsAttribute content_units;
+ LsmAttribute href;
LsmSvgViewboxAttribute viewbox;
LsmSvgPreserveAspectRatioAttribute preserve_aspect_ratio;
+
+ gboolean enable_rendering;
};
struct _LsmSvgPatternElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_pattern_element_get_type (void);
diff --git a/src/lsmsvgpolygonelement.c b/src/lsmsvgpolygonelement.c
index a560e6f..fde87d0 100644
--- a/src/lsmsvgpolygonelement.c
+++ b/src/lsmsvgpolygonelement.c
@@ -37,7 +37,7 @@ lsm_svg_polygon_element_get_node_name (LsmDomNode *node)
/* LsmSvgGraphic implementation */
static void
-lsm_svg_polygon_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_polygon_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgPolygonElement *polygon = LSM_SVG_POLYGON_ELEMENT (self);
@@ -59,23 +59,30 @@ lsm_svg_polygon_element_init (LsmSvgPolygonElement *self)
/* LsmSvgPolygonElement class */
+static const LsmAttributeInfos lsm_svg_polygon_element_attribute_infos[] = {
+ {
+ .name = "points",
+ .attribute_offset = offsetof (LsmSvgPolygonElement, points),
+ .trait_class = &lsm_null_trait_class
+ }
+};
+
static void
lsm_svg_polygon_element_class_init (LsmSvgPolygonElementClass *s_rect_class)
{
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
d_node_class->get_node_name = lsm_svg_polygon_element_get_node_name;
- s_graphic_class->graphic_render = lsm_svg_polygon_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_polygon_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "points",
- offsetof (LsmSvgPolygonElement, points));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_polygon_element_attribute_infos),
+ lsm_svg_polygon_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgPolygonElement, lsm_svg_polygon_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgPolygonElement, lsm_svg_polygon_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgpolygonelement.h b/src/lsmsvgpolygonelement.h
index e9bb558..90db664 100644
--- a/src/lsmsvgpolygonelement.h
+++ b/src/lsmsvgpolygonelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_POLYGON_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,13 +37,13 @@ G_BEGIN_DECLS
typedef struct _LsmSvgPolygonElementClass LsmSvgPolygonElementClass;
struct _LsmSvgPolygonElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmDomAttribute points;
+ LsmAttribute points;
};
struct _LsmSvgPolygonElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_polygon_element_get_type (void);
diff --git a/src/lsmsvgpolylineelement.c b/src/lsmsvgpolylineelement.c
index 0facb9a..821e7b0 100644
--- a/src/lsmsvgpolylineelement.c
+++ b/src/lsmsvgpolylineelement.c
@@ -37,7 +37,7 @@ lsm_svg_polyline_element_get_node_name (LsmDomNode *node)
/* LsmSvgGraphic implementation */
static void
-lsm_svg_polyline_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_polyline_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgPolylineElement *polyline = LSM_SVG_POLYLINE_ELEMENT (self);
@@ -59,23 +59,30 @@ lsm_svg_polyline_element_init (LsmSvgPolylineElement *self)
/* LsmSvgPolylineElement class */
+static const LsmAttributeInfos lsm_svg_polyline_element_attribute_infos[] = {
+ {
+ .name = "points",
+ .attribute_offset = offsetof (LsmSvgPolylineElement, points),
+ .trait_class = &lsm_null_trait_class
+ }
+};
+
static void
lsm_svg_polyline_element_class_init (LsmSvgPolylineElementClass *s_rect_class)
{
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
d_node_class->get_node_name = lsm_svg_polyline_element_get_node_name;
- s_graphic_class->graphic_render = lsm_svg_polyline_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_polyline_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "points",
- offsetof (LsmSvgPolylineElement, points));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_polyline_element_attribute_infos),
+ lsm_svg_polyline_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgPolylineElement, lsm_svg_polyline_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgPolylineElement, lsm_svg_polyline_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgpolylineelement.h b/src/lsmsvgpolylineelement.h
index c4c15f2..a96fc6a 100644
--- a/src/lsmsvgpolylineelement.h
+++ b/src/lsmsvgpolylineelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_POLYLINE_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,13 +37,13 @@ G_BEGIN_DECLS
typedef struct _LsmSvgPolylineElementClass LsmSvgPolylineElementClass;
struct _LsmSvgPolylineElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmDomAttribute points;
+ LsmAttribute points;
};
struct _LsmSvgPolylineElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_polyline_element_get_type (void);
diff --git a/src/lsmsvgradialgradientelement.c b/src/lsmsvgradialgradientelement.c
index a219369..daa569c 100644
--- a/src/lsmsvgradialgradientelement.c
+++ b/src/lsmsvgradialgradientelement.c
@@ -35,37 +35,10 @@ lsm_svg_radial_gradient_element_get_node_name (LsmDomNode *node)
return "radialGradient";
}
-/* GRadialGradientElement implementation */
-
-static void
-_radial_gradient_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgRadialGradientElement *radial = LSM_SVG_RADIAL_GRADIENT_ELEMENT (self);
- LsmSvgLength length;
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-
- length.value_unit = 50.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&radial->cx, &length);
-
- length.value_unit = 50.0;
- length.type = LSM_SVG_LENGTH_TYPE_PERCENTAGE;
- lsm_svg_animated_length_attribute_parse (&radial->cy, &length);
-
- length.value_unit = 50.0;
- 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);
-
- length = radial->cy.length.base;
- lsm_svg_animated_length_attribute_parse (&radial->fy, &length);
-}
+/* LsmSvgRadialGradientElement implementation */
static void
-_radial_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_radial_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgRadialGradientElement *radial = LSM_SVG_RADIAL_GRADIENT_ELEMENT (self);
gboolean is_object_bounding_box;
@@ -81,11 +54,19 @@ _radial_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
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);
+ cx = lsm_svg_view_normalize_length (view, &radial->cx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ cy = lsm_svg_view_normalize_length (view, &radial->cy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ r = lsm_svg_view_normalize_length (view, &radial->r.length, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+
+ if (lsm_attribute_is_defined (&radial->fx.base))
+ fx = lsm_svg_view_normalize_length (view, &radial->fx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ else
+ fx = cx;
+
+ if (lsm_attribute_is_defined (&radial->fy.base))
+ fy = lsm_svg_view_normalize_length (view, &radial->fy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ else
+ fy = cy;
gradient_radius = sqrt ((fx - cx) * (fx - cx) + (fy - cy) * (fy - cy));
if (gradient_radius > r) {
@@ -105,8 +86,6 @@ _radial_gradient_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
cx, cy, r, fx, fy);
lsm_svg_view_create_radial_gradient (view, cx, cy, r, fx, fy);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->render_paint (self, view);
}
/* LsmSvgRadialGradientElement implementation */
@@ -117,25 +96,67 @@ lsm_svg_radial_gradient_element_new (void)
return g_object_new (LSM_TYPE_SVG_RADIAL_GRADIENT_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = {.value_unit = 50.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+static const LsmSvgLength unset_default = {.value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_UNKNOWN};
+
static void
lsm_svg_radial_gradient_element_init (LsmSvgRadialGradientElement *self)
{
-
+ self->cx.length = length_default;
+ self->cy.length = length_default;
+ self->r.length = length_default;
+ self->fx.length = unset_default;
+ self->fy.length = unset_default;
}
static void
lsm_svg_radial_gradient_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgRadialGradientElement class */
+static const LsmAttributeInfos lsm_svg_radial_gradient_element_attribute_infos[] = {
+ {
+ .name = "cx",
+ .attribute_offset = offsetof (LsmSvgRadialGradientElement, cx),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "cy",
+ .attribute_offset = offsetof (LsmSvgRadialGradientElement, cy),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "r",
+ .attribute_offset = offsetof (LsmSvgRadialGradientElement, r),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "fx",
+ .attribute_offset = offsetof (LsmSvgRadialGradientElement, fx),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &unset_default
+ },
+ {
+ .name = "fy",
+ .attribute_offset = offsetof (LsmSvgRadialGradientElement, fy),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &unset_default
+ }
+};
+
static void
lsm_svg_radial_gradient_element_class_init (LsmSvgRadialGradientElementClass *s_svg_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_svg_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_svg_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_svg_class);
+ LsmSvgGradientElementClass *s_gradient_class = LSM_SVG_GRADIENT_ELEMENT_CLASS (s_svg_class);
parent_class = g_type_class_peek_parent (s_svg_class);
@@ -143,21 +164,13 @@ lsm_svg_radial_gradient_element_class_init (LsmSvgRadialGradientElementClass *s_
d_node_class->get_node_name = lsm_svg_radial_gradient_element_get_node_name;
- s_element_class->update = _radial_gradient_element_update;
- s_element_class->render_paint = _radial_gradient_element_render_paint;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
-
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "cx",
- offsetof (LsmSvgRadialGradientElement, cx));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "cy",
- offsetof (LsmSvgRadialGradientElement, cy));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "r",
- offsetof (LsmSvgRadialGradientElement, r));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "fx",
- offsetof (LsmSvgRadialGradientElement, fx));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "fy",
- offsetof (LsmSvgRadialGradientElement, fy));
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_radial_gradient_element_attribute_infos),
+ lsm_svg_radial_gradient_element_attribute_infos);
+
+ s_gradient_class->create_gradient = lsm_svg_radial_gradient_element_create_gradient;
}
G_DEFINE_TYPE (LsmSvgRadialGradientElement, lsm_svg_radial_gradient_element, LSM_TYPE_SVG_GRADIENT_ELEMENT)
diff --git a/src/lsmsvgradialgradientelement.h b/src/lsmsvgradialgradientelement.h
index 6be6a7c..47ae183 100644
--- a/src/lsmsvgradialgradientelement.h
+++ b/src/lsmsvgradialgradientelement.h
@@ -39,11 +39,11 @@ typedef struct _LsmSvgRadialGradientElementClass LsmSvgRadialGradientElementClas
struct _LsmSvgRadialGradientElement {
LsmSvgGradientElement gradient;
- LsmSvgAnimatedLengthAttribute cx;
- LsmSvgAnimatedLengthAttribute cy;
- LsmSvgAnimatedLengthAttribute r;
- LsmSvgAnimatedLengthAttribute fx;
- LsmSvgAnimatedLengthAttribute fy;
+ LsmSvgLengthAttribute cx;
+ LsmSvgLengthAttribute cy;
+ LsmSvgLengthAttribute r;
+ LsmSvgLengthAttribute fx;
+ LsmSvgLengthAttribute fy;
};
struct _LsmSvgRadialGradientElementClass {
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index b039e9c..c743fb1 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -34,79 +34,46 @@ lsm_svg_rect_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
-static void
-lsm_svg_rect_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgRectElement *rect = LSM_SVG_RECT_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->x, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->y, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->width, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->height, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->rx, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&rect->ry, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
static void
-lsm_svg_rect_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_rect_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgRectElement *rect = LSM_SVG_RECT_ELEMENT (self);
double x, y;
double rx, ry;
double w, h;
- 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);
+ x = lsm_svg_view_normalize_length (view, &rect->x.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &rect->y.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ rx = lsm_svg_view_normalize_length (view, &rect->rx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ ry = lsm_svg_view_normalize_length (view, &rect->ry.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ w = lsm_svg_view_normalize_length (view, &rect->width.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ h = lsm_svg_view_normalize_length (view, &rect->height.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
/* SVG specification is so weird sometimes ... */
if (w == 0.0 || h == 0.0)
return;
- if (!lsm_dom_attribute_is_defined (&rect->rx.attr))
+ if (!lsm_attribute_is_defined (&rect->rx.base))
rx = ry;
- else if (!lsm_dom_attribute_is_defined (&rect->ry.attr))
+ else if (!lsm_attribute_is_defined (&rect->ry.base))
ry = rx;
lsm_svg_view_show_rectangle (view, x, y, w, h, rx, ry);
}
static void
-lsm_svg_rect_element_graphic_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExtents *extents)
+lsm_svg_rect_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExtents *extents)
{
LsmSvgRectElement *rect = LSM_SVG_RECT_ELEMENT (self);
double x, y;
double w, h;
- 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);
- 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);
+ x = lsm_svg_view_normalize_length (view, &rect->x.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &rect->y.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ w = lsm_svg_view_normalize_length (view, &rect->width.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ h = lsm_svg_view_normalize_length (view, &rect->height.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
extents->x1 = x;
extents->y1 = y;
@@ -122,25 +89,73 @@ lsm_svg_rect_element_new (void)
return g_object_new (LSM_TYPE_SVG_RECT_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+static const LsmSvgLength unset_length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_UNKNOWN};
+
static void
lsm_svg_rect_element_init (LsmSvgRectElement *self)
{
+ self->x.length = length_default;
+ self->y.length = length_default;
+ self->width.length = length_default;
+ self->height.length = length_default;
+ self->rx.length = unset_length_default;
+ self->ry.length = unset_length_default;
}
static void
lsm_svg_rect_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgRectElement class */
+static const LsmAttributeInfos lsm_svg_rect_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgRectElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgRectElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "width",
+ .attribute_offset = offsetof (LsmSvgRectElement, width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "height",
+ .attribute_offset = offsetof (LsmSvgRectElement, height),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "rx",
+ .attribute_offset = offsetof (LsmSvgRectElement, rx),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &unset_length_default
+ },
+ {
+ .name = "ry",
+ .attribute_offset = offsetof (LsmSvgRectElement, ry),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &unset_length_default
+ }
+};
+
static void
lsm_svg_rect_element_class_init (LsmSvgRectElementClass *s_rect_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_rect_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
parent_class = g_type_class_peek_parent (s_rect_class);
@@ -148,25 +163,13 @@ lsm_svg_rect_element_class_init (LsmSvgRectElementClass *s_rect_class)
d_node_class->get_node_name = lsm_svg_rect_element_get_node_name;
- s_element_class->update = lsm_svg_rect_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_rect_element_graphic_render;
- s_graphic_class->graphic_get_extents = lsm_svg_rect_element_graphic_get_extents;
-
- 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 (LsmSvgRectElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgRectElement, y));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgRectElement, width));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgRectElement, height));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "rx",
- offsetof (LsmSvgRectElement, rx));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "ry",
- offsetof (LsmSvgRectElement, ry));
+ s_element_class->render = lsm_svg_rect_element_render;
+ s_element_class->get_extents = lsm_svg_rect_element_get_extents;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_rect_element_attribute_infos),
+ lsm_svg_rect_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgRectElement, lsm_svg_rect_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgRectElement, lsm_svg_rect_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgrectelement.h b/src/lsmsvgrectelement.h
index 9bf874a..0ec6552 100644
--- a/src/lsmsvgrectelement.h
+++ b/src/lsmsvgrectelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_RECT_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,18 +37,18 @@ G_BEGIN_DECLS
typedef struct _LsmSvgRectElementClass LsmSvgRectElementClass;
struct _LsmSvgRectElement {
- LsmSvgGraphic graphic;
-
- LsmSvgAnimatedLengthAttribute x;
- LsmSvgAnimatedLengthAttribute y;
- LsmSvgAnimatedLengthAttribute width;
- LsmSvgAnimatedLengthAttribute height;
- LsmSvgAnimatedLengthAttribute rx;
- LsmSvgAnimatedLengthAttribute ry;
+ LsmSvgElement element;
+
+ LsmSvgLengthAttribute x;
+ LsmSvgLengthAttribute y;
+ LsmSvgLengthAttribute width;
+ LsmSvgLengthAttribute height;
+ LsmSvgLengthAttribute rx;
+ LsmSvgLengthAttribute ry;
};
struct _LsmSvgRectElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_rect_element_get_type (void);
diff --git a/src/lsmsvgstopelement.c b/src/lsmsvgstopelement.c
index efdd129..e50b7f3 100644
--- a/src/lsmsvgstopelement.c
+++ b/src/lsmsvgstopelement.c
@@ -38,51 +38,22 @@ lsm_svg_stop_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
static void
-_stop_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
+lsm_svg_stop_element_render (LsmSvgElement *element, LsmSvgView *view)
{
- LsmSvgStopElement *stop = LSM_SVG_STOP_ELEMENT (self);
- LsmSvgLength length;
+ LsmSvgStopElement *stop = LSM_SVG_STOP_ELEMENT (element);
+ double offset;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&stop->offset, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
-/* LsmSvgStopElement implementation */
-
-double
-lsm_svg_stop_element_get_offset (LsmSvgStopElement *self)
-{
- g_return_val_if_fail (LSM_IS_SVG_STOP_ELEMENT (self), 0.0);
-
- if (self->offset.length.type == LSM_SVG_LENGTH_TYPE_PERCENTAGE)
- return self->offset.length.value_unit / 100.0;
+ if (stop->offset.length.type == LSM_SVG_LENGTH_TYPE_PERCENTAGE)
+ offset = stop->offset.length.value_unit / 100.0;
else
- return self->offset.length.value_unit;
-}
+ offset = stop->offset.length.value_unit;
-const LsmSvgColor *
-lsm_svg_stop_element_get_color (LsmSvgStopElement *self)
-{
- g_return_val_if_fail (LSM_IS_SVG_STOP_ELEMENT (self), &lsm_svg_color_null);
+ lsm_debug ("[LsmSvgStopElement::render] Add stop at %g", offset);
- if (LSM_SVG_GRAPHIC(self)->stop != NULL)
- return &(LSM_SVG_GRAPHIC (self)->stop->color.value);
- else
- return &lsm_svg_color_null;
+ lsm_svg_view_add_gradient_color_stop (view, offset);
}
-double
-lsm_svg_stop_element_get_opacity (LsmSvgStopElement *self)
-{
- g_return_val_if_fail (LSM_IS_SVG_STOP_ELEMENT (self), 1.0);
-
- if (LSM_SVG_GRAPHIC(self)->stop != NULL)
- return LSM_SVG_GRAPHIC (self)->stop->opacity.value;
- else
- return 1.0;
-}
+/* LsmSvgStopElement implementation */
LsmDomNode *
lsm_svg_stop_element_new (void)
@@ -90,13 +61,25 @@ lsm_svg_stop_element_new (void)
return g_object_new (LSM_TYPE_SVG_STOP_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_NUMBER};
+
static void
lsm_svg_stop_element_init (LsmSvgStopElement *self)
{
+ self->offset.length = length_default;
}
/* LsmSvgStopElement class */
+static const LsmAttributeInfos lsm_svg_stop_element_attribute_infos[] = {
+ {
+ .name = "offset",
+ .attribute_offset = offsetof (LsmSvgStopElement, offset),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ }
+};
+
static void
lsm_svg_stop_element_class_init (LsmSvgStopElementClass *klass)
{
@@ -107,12 +90,13 @@ lsm_svg_stop_element_class_init (LsmSvgStopElementClass *klass)
d_node_class->get_node_name = lsm_svg_stop_element_get_node_name;
- s_element_class->update = _stop_element_update;
+ s_element_class->render = lsm_svg_stop_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_stop_element_attribute_infos),
+ lsm_svg_stop_element_attribute_infos);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "offset",
- offsetof (LsmSvgStopElement, offset));
}
-G_DEFINE_TYPE (LsmSvgStopElement, lsm_svg_stop_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgStopElement, lsm_svg_stop_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgstopelement.h b/src/lsmsvgstopelement.h
index 0187c9c..7b17be4 100644
--- a/src/lsmsvgstopelement.h
+++ b/src/lsmsvgstopelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_STOP_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,23 +37,19 @@ G_BEGIN_DECLS
typedef struct _LsmSvgStopElementClass LsmSvgStopElementClass;
struct _LsmSvgStopElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
LsmSvgLengthAttribute offset;
};
struct _LsmSvgStopElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
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 LsmSvgColor * lsm_svg_stop_element_get_color (LsmSvgStopElement *self);
-double lsm_svg_stop_element_get_opacity (LsmSvgStopElement *self);
-
G_END_DECLS
#endif
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index 8e98709..438aa26 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -20,7 +20,442 @@
*/
#include <lsmsvgstyle.h>
+#include <lsmsvgcolors.h>
+#include <lsmsvgtraits.h>
+#include <lsmstr.h>
#include <string.h>
+#include <math.h>
+
+static const LsmPropertyInfos lsm_svg_property_infos[] = {
+ {
+ .name = "alignment-baseline",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, alignment_baseline),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto" /* FIXME specification says "see property description" */
+ },
+ {
+ .name = "baseline-shift",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, baseline_shift),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "baseline"
+ },
+ {
+ .name = "clip",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, clip),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "clip-path",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, clip_path),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "dominant-baseline",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, dominant_baseline),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "enable-background",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, enable_background),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "accumulate"
+ },
+ {
+ .name = "filter",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, filter),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "flood-color",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, flood_color),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "black"
+ },
+ {
+ .name = "flood-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, flood_opacity),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "1"
+ },
+ {
+ .name = "lighting-color",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, lighting_color),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "white"
+ },
+ {
+ .name = "mask",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, mask),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, opacity),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = "1"
+ },
+ {
+ .name = "overflow",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, overflow),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = ""
+ },
+ {
+ .name = "stop-color",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stop_color),
+ .trait_class = &lsm_svg_color_trait_class,
+ .trait_default = "black"
+ },
+ {
+ .name = "stop-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stop_opacity),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = "1"
+ },
+ {
+ .name = "text-decoration",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, text_decoration),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "unicode-bidi",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, unicode_bidi),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ /* Inherited properties */
+ {
+ .name = "clip-rule",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, clip_rule),
+ .trait_class = &lsm_svg_fill_rule_trait_class,
+ .trait_default = "nonzero"
+ },
+ {
+ .name = "color",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, color),
+ .trait_class = &lsm_svg_color_trait_class,
+ .trait_default = "black" /* Depends on user agent */
+ },
+ {
+ .name = "color-interpolation",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, color_interpolation),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "sRGB"
+ },
+ {
+ .name = "color-interpolation-filters",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, color_interpolation_filters),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "linearRGB"
+ },
+ {
+ .name = "color-profile",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, color_profile),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "color-rendering",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, color_rendering),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "cursor",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, cursor),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "direction",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, direction),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "ltr"
+ },
+ {
+ .name = "display",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, display),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "inline"
+ },
+ {
+ .name = "fill",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, fill),
+ .trait_class = &lsm_svg_paint_trait_class,
+ .trait_default = "black"
+ },
+ {
+ .name = "fill-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, fill_opacity),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = "1"
+ },
+ {
+ .name = "fill-rule",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, fill_rule),
+ .trait_class = &lsm_svg_fill_rule_trait_class,
+ .trait_default = "nonzero"
+ },
+ {
+ .name = "font",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = NULL /* specification says "See individual properties" */
+ },
+ {
+ .name = "font-family",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_family),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "Sans" /* Depends on user agent */
+ },
+ {
+ .name = "font-size",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_size),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = "10pt" /* FIXME Specification says "medium" */
+ },
+ {
+ .name = "font-size-adjust",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_size_adjust),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "font-stretch",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_stretch),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ {
+ .name = "font-style",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_style),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ {
+ .name = "font-variant",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_variant),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ {
+ .name = "font-weight",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, font_weight),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ {
+ .name = "glyph-orientation-horizontal",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, glyph_orientation_horizontal),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "0deg"
+ },
+ {
+ .name = "glyph-orientation-vertical",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, glyph_orientation_vertical),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "image-rendering",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, image_rendering),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "kerning",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, kerning),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "letter-spacing",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, letter_spacing),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ {
+ .name = "marker",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, marker),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "marker-end",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, marker_end),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "marker-mid",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, marker_mid),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "marker-start",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, marker_start),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "pointer-events",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, pointer_events),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "visiblePainted"
+ },
+ {
+ .name = "shape-rendering",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, shape_rendering),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "stroke",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke),
+ .trait_class = &lsm_svg_paint_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "stroke-dasharray",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_dash_array),
+ .trait_class = &lsm_svg_dash_array_trait_class,
+ .trait_default = "none"
+ },
+ {
+ .name = "stroke-dashoffset",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_dash_offset),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = "0"
+ },
+ {
+ .name = "stroke-linecap",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_line_cap),
+ .trait_class = &lsm_svg_line_cap_trait_class,
+ .trait_default = "butt"
+ },
+ {
+ .name = "stroke-linejoin",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_line_join),
+ .trait_class = &lsm_svg_line_join_trait_class,
+ .trait_default = "miter"
+ },
+ {
+ .name = "stroke-miterlimit",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_miter_limit),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = "4"
+ },
+ {
+ .name = "stroke-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_opacity),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = "1"
+ },
+ {
+ .name = "stroke-width",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, stroke_width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = "1"
+ },
+ {
+ .name = "text-anchor",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, text_anchor),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "start"
+ },
+ {
+ .name = "text-rendering",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, text_rendering),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "auto"
+ },
+ {
+ .name = "visibility",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, visibility),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "visible"
+ },
+ {
+ .name = "word-spacing",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, word_spacing),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "normal"
+ },
+ {
+ .name = "writing-mode",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, writing_mode),
+ .trait_class = &lsm_null_trait_class,
+ .trait_default = "lr-tb"
+ }
+};
+
+static LsmPropertyManager *
+lsm_svg_get_property_manager (void)
+{
+ static LsmPropertyManager *manager = NULL;
+
+ if (G_LIKELY (manager != NULL))
+ return manager;
+
+ manager = lsm_property_manager_new (G_N_ELEMENTS (lsm_svg_property_infos), lsm_svg_property_infos);
+
+ return manager;
+}
+
+void
+lsm_svg_property_bag_set_property (LsmPropertyBag *property_bag, const char *name, const char *value)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ lsm_property_manager_set_property (property_manager, property_bag, name, value);
+}
+
+const char *
+lsm_svg_property_bag_get_property (LsmPropertyBag *property_bag, const char *name)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ return lsm_property_manager_get_property (property_manager, property_bag, name);
+}
+
+void
+lsm_svg_property_bag_clean (LsmPropertyBag *property_bag)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ lsm_property_manager_clean_properties (property_manager, property_bag);
+}
+
+char *
+lsm_svg_property_bag_serialize (LsmPropertyBag *property_bag)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ return lsm_property_manager_serialize (property_manager, property_bag);
+}
+
+static const LsmSvgStyle *
+lsm_svg_get_default_style (void)
+{
+ static LsmSvgStyle *style = NULL;
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ if (style != NULL)
+ return style;
+
+ style = g_new (LsmSvgStyle, 1);
+
+ lsm_property_manager_init_default_style (property_manager, style);
+
+ return style;
+}
LsmSvgStyle *
lsm_svg_style_new (void)
@@ -28,9 +463,6 @@ lsm_svg_style_new (void)
LsmSvgStyle *style;
style = g_new0 (LsmSvgStyle, 1);
- g_return_val_if_fail (style != NULL, NULL);
-
- style->text.font_family = g_strdup ("sans");
return style;
}
@@ -40,26 +472,31 @@ lsm_svg_style_free (LsmSvgStyle *style)
{
g_return_if_fail (style != NULL);
- lsm_svg_dash_array_free (style->stroke.dash_array);
-
- g_free (style->text.font_family);
g_free (style);
}
LsmSvgStyle *
-lsm_svg_style_duplicate (const LsmSvgStyle *from)
+lsm_svg_style_new_inherited (const LsmSvgStyle *parent_style, LsmPropertyBag *property_bag)
{
LsmSvgStyle *style;
+ const LsmSvgStyle *default_style;
- g_return_val_if_fail (from != NULL, NULL);
+ default_style = lsm_svg_get_default_style ();
- style = lsm_svg_style_new ();
- g_return_val_if_fail (style != NULL, NULL);
+ style = g_new (LsmSvgStyle, 1);
- memcpy (style, from, sizeof (LsmSvgStyle));
+ if (parent_style != NULL) {
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
- style->stroke.dash_array = lsm_svg_dash_array_duplicate (from->stroke.dash_array);
- style->text.font_family = g_strdup (from->text.font_family);
+ memcpy (style, default_style, offsetof (LsmSvgStyle, clip_rule));
+ memcpy (&style->clip_rule, &parent_style->clip_rule,
+ sizeof (LsmSvgStyle) - offsetof (LsmSvgStyle, clip_rule));
+
+ lsm_property_manager_apply_property_bag (property_manager, property_bag, style, parent_style);
+ } else {
+ memcpy (style, default_style, sizeof (LsmSvgStyle));
+ }
return style;
}
+
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index ccd0c37..cbb1cc7 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -22,50 +22,136 @@
#ifndef LSM_SVG_STYLE_H
#define LSM_SVG_STYLE_H
-#include <lsmsvg.h>
-#include <lsmsvgattributebags.h>
+#include <lsmsvgtraits.h>
+#include <lsmproperties.h>
G_BEGIN_DECLS
+typedef struct {
+ LsmProperty base;
+ double value;
+} LsmSvgDoubleProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgLength length;
+} LsmSvgLengthProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgPaint paint;
+} LsmSvgPaintProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgColor value;
+} LsmSvgColorProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgMatrix matrix;
+} LsmSvgTransformProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgFillRule value;
+} LsmSvgFillRuleProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgLineJoin value;
+} LsmSvgLineJoinProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgLineCap value;
+} LsmSvgLineCapProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgDashArray value;
+} LsmSvgDashArrayProperty;
+
struct _LsmSvgStyle {
- LsmBox viewport;
- LsmSvgColor color;
-
- struct {
- LsmSvgPaint paint;
- LsmSvgFillRule rule;
- double opacity;
- } fill;
-
- struct {
- LsmSvgPaint paint;
- LsmSvgLength width;
- LsmSvgLineJoin line_join;
- LsmSvgLineCap line_cap;
- double opacity;
- double miter_limit;
- LsmSvgDashArray *dash_array;
- LsmSvgLength dash_offset;
- } stroke;
-
- struct {
- LsmSvgFillRule rule;
- } clip;
-
- struct {
- char *font_family;
- LsmSvgLength font_size;
- } text;
-
- struct {
- LsmSvgColor color;
- double opacity;
- } stop;
+ /* Not inherited */
+
+ LsmProperty * alignment_baseline;
+ LsmProperty * baseline_shift;
+ LsmProperty * clip;
+ LsmProperty * clip_path;
+ LsmProperty * dominant_baseline;
+ LsmProperty * enable_background;
+ LsmProperty * filter;
+ LsmProperty * flood_color;
+ LsmProperty * flood_opacity;
+ LsmProperty * lighting_color;
+ LsmProperty * mask;
+ LsmSvgDoubleProperty * opacity;
+ LsmProperty * overflow;
+ LsmSvgColorProperty * stop_color;
+ LsmSvgDoubleProperty * stop_opacity;
+ LsmProperty * text_decoration;
+ LsmProperty * unicode_bidi;
+
+ /* Inherited */
+
+ LsmSvgFillRuleProperty * clip_rule;
+ LsmSvgColorProperty * color;
+ LsmProperty * color_interpolation;
+ LsmProperty * color_interpolation_filters;
+ LsmProperty * color_profile;
+ LsmProperty * color_rendering;
+ LsmProperty * cursor;
+ LsmProperty * direction;
+ LsmProperty * display;
+ LsmSvgPaintProperty * fill;
+ LsmSvgDoubleProperty * fill_opacity;
+ LsmSvgFillRuleProperty * fill_rule;
+ LsmProperty * font;
+ LsmProperty * font_family;
+ LsmSvgLengthProperty * font_size;
+ LsmProperty * font_size_adjust;
+ LsmProperty * font_stretch;
+ LsmProperty * font_style;
+ LsmProperty * font_variant;
+ LsmProperty * font_weight;
+ LsmProperty * glyph_orientation_horizontal;
+ LsmProperty * glyph_orientation_vertical;
+ LsmProperty * image_rendering;
+ LsmProperty * kerning;
+ LsmProperty * letter_spacing;
+ LsmProperty * marker;
+ LsmProperty * marker_end;
+ LsmProperty * marker_mid;
+ LsmProperty * marker_start;
+ LsmProperty * pointer_events;
+ LsmProperty * shape_rendering;
+ LsmSvgPaintProperty * stroke;
+ LsmSvgDashArrayProperty * stroke_dash_array;
+ LsmSvgLengthProperty * stroke_dash_offset;
+ LsmSvgLineCapProperty * stroke_line_cap;
+ LsmSvgLineJoinProperty * stroke_line_join;
+ LsmSvgDoubleProperty * stroke_miter_limit;
+ LsmSvgDoubleProperty * stroke_opacity;
+ LsmSvgLengthProperty * stroke_width;
+ LsmProperty * text_anchor;
+ LsmProperty * text_rendering;
+ LsmProperty * visibility;
+ LsmProperty * word_spacing;
+ LsmProperty * writing_mode;
};
-LsmSvgStyle * lsm_svg_style_new (void);
-void lsm_svg_style_free (LsmSvgStyle *style);
-LsmSvgStyle * lsm_svg_style_duplicate (const LsmSvgStyle *style);
+void lsm_svg_property_bag_set_property (LsmPropertyBag *property_bag,
+ const char *name, const char *value);
+const char * lsm_svg_property_bag_get_property (LsmPropertyBag *property_bag,
+ const char *name);
+void lsm_svg_property_bag_clean (LsmPropertyBag *property_bag);
+char * lsm_svg_property_bag_serialize (LsmPropertyBag *property_bag);
+
+LsmSvgStyle * lsm_svg_style_new (void);
+void lsm_svg_style_free (LsmSvgStyle *style);
+LsmSvgStyle * lsm_svg_style_new_inherited (const LsmSvgStyle *parent_style,
+ LsmPropertyBag *property_bag);
G_END_DECLS
diff --git a/src/lsmsvgsvgelement.c b/src/lsmsvgsvgelement.c
index be01e75..9537697 100644
--- a/src/lsmsvgsvgelement.c
+++ b/src/lsmsvgsvgelement.c
@@ -39,42 +39,6 @@ lsm_svg_svg_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
-static void
-_svg_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->x, &length);
-
- length.value_unit = 0;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->y, &length);
-
- length.value_unit = parent_style->viewport.width;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->width, &length);
-
- length.value_unit = parent_style->viewport.height;
- length.type = LSM_SVG_LENGTH_TYPE_NUMBER;
- lsm_svg_length_attribute_parse (&svg->height, &length);
-
- lsm_svg_viewbox_attribute_parse (&svg->viewbox);
- lsm_svg_preserve_aspect_ratio_attribute_parse (&svg->preserve_aspect_ratio);
-
- lsm_debug ("[LsmSvgSvgElement::update] view_bbox = %g, %g, %g, %g\n",
- 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)
{
@@ -99,14 +63,29 @@ lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *heig
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 (lsm_attribute_is_defined (&self->x.base))
+ svg_x = lsm_svg_length_normalize (&self->x.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ else
+ svg_x = viewport.x;
+
+ if (lsm_attribute_is_defined (&self->y.base))
+ svg_y = lsm_svg_length_normalize (&self->y.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ else
+ svg_y = viewport.y;
+
+ if (lsm_attribute_is_defined (&self->width.base))
+ svg_width = lsm_svg_length_normalize (&self->width.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ else
+ svg_width = viewport.width;
+
+ if (lsm_attribute_is_defined (&self->height.base))
+ svg_height = lsm_svg_length_normalize (&self->height.length, svg_viewbox,
+ font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+ else
+ svg_height = viewport.height;
if (width != NULL)
*width = svg_width * 72.0 / resolution_ppi;
@@ -127,7 +106,7 @@ lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *heig
/* LsmSvgGraphic implementation */
static void
-lsm_svg_svg_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+_svg_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
gboolean is_viewbox_defined;
@@ -138,51 +117,25 @@ lsm_svg_svg_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
viewport.width = lsm_svg_view_normalize_length (view, &svg->width.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
viewport.height = lsm_svg_view_normalize_length (view, &svg->height.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
- is_viewbox_defined = lsm_dom_attribute_is_defined ((LsmDomAttribute *) &svg->viewbox);
+ is_viewbox_defined = lsm_attribute_is_defined ((LsmAttribute *) &svg->viewbox);
if (is_viewbox_defined && (svg->viewbox.value.width <= 0.0 ||
svg->viewbox.value.height <= 0.0))
return;
- lsm_debug ("[LsmSvgSvgElement::graphic_render] viewport %g, %g, %g, %g",
+ lsm_debug ("[LsmSvgSvgElement::render] viewport %g, %g, %g, %g",
viewport.x, viewport.y, viewport.width, viewport.height);
lsm_svg_view_push_viewport (view, &viewport, is_viewbox_defined ? &svg->viewbox.value : NULL,
&svg->preserve_aspect_ratio.value);
- LSM_SVG_GRAPHIC_CLASS (parent_class)->graphic_render (self, view);
+ LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);
lsm_svg_view_pop_viewport (view);
}
/* LsmSvgSvgElement implementation */
-LsmSvgStyle *
-lsm_svg_svg_element_get_default_style (LsmSvgSvgElement *svg_element)
-{
- g_return_val_if_fail (LSM_IS_SVG_SVG_ELEMENT (svg_element), NULL);
-
- return svg_element->default_style;
-}
-
-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->viewport = lsm_dom_document_get_viewport_px (document);
-
- lsm_svg_element_update (LSM_SVG_ELEMENT (svg_element), style);
-}
-
void
lsm_svg_svg_element_render (LsmSvgSvgElement *svg, LsmSvgView *view)
{
@@ -197,49 +150,79 @@ lsm_svg_svg_element_new (void)
return g_object_new (LSM_TYPE_SVG_SVG_ELEMENT, NULL);
}
+static const LsmSvgLength x_y_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+static const LsmSvgLength width_height_default = { .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
+static const LsmBox viewbox_default = {0.0, 0.0, 0.0, 0.0};
+static const LsmSvgPreserveAspectRatio preserve_aspect_ratio_default = {
+ .defer = FALSE,
+ .align = LSM_SVG_ALIGN_X_MID_Y_MID,
+ .meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET
+};
+
static void
lsm_svg_svg_element_init (LsmSvgSvgElement *self)
{
- LsmSvgStyle *style;
-
- style = lsm_svg_style_new ();
- self->default_style = style;
- g_return_if_fail (style != NULL);
-
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "opacity", "1.0");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill", "black");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill-opacity", "1");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill-rule", "nonzero");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke", "none");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke-width", "1px");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke-opacity", "1");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke-linejoin", "miter");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke-linecap", "butt");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke-miterlimit", "4");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "font-family", "sans");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "font-size", "10pt");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stop-color", "black");
- lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stop-opacity", "1");
-
+ self->x.length = x_y_default;
+ self->y.length = x_y_default;
+ self->width.length = width_height_default;
+ self->height.length = width_height_default;
+ self->viewbox.value = viewbox_default;
+ self->preserve_aspect_ratio.value = preserve_aspect_ratio_default;
}
static void
lsm_svg_svg_element_finalize (GObject *object)
{
- LsmSvgSvgElement *svg_element = LSM_SVG_SVG_ELEMENT (object);
-
- lsm_svg_style_free (svg_element->default_style);
+ parent_class->finalize (object);
}
/* LsmSvgSvgElement class */
+static const LsmAttributeInfos lsm_svg_svg_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgSvgElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x_y_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgSvgElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &x_y_default
+ },
+ {
+ .name = "width",
+ .attribute_offset = offsetof (LsmSvgSvgElement, width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &width_height_default
+ },
+ {
+ .name = "height",
+ .attribute_offset = offsetof (LsmSvgSvgElement, height),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &width_height_default
+ },
+ {
+ .name = "viewBox",
+ .attribute_offset = offsetof (LsmSvgSvgElement, viewbox),
+ .trait_class = &lsm_box_trait_class,
+ .trait_default = &viewbox_default
+ },
+ {
+ .name = "preserveAspectRatio",
+ .attribute_offset = offsetof (LsmSvgSvgElement, preserve_aspect_ratio),
+ .trait_class = &lsm_svg_preserve_aspect_ratio_trait_class,
+ .trait_default = &preserve_aspect_ratio_default
+ }
+};
+
static void
lsm_svg_svg_element_class_init (LsmSvgSvgElementClass *s_svg_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (s_svg_class);
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_svg_class);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_svg_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_svg_class);
parent_class = g_type_class_peek_parent (s_svg_class);
@@ -247,24 +230,12 @@ lsm_svg_svg_element_class_init (LsmSvgSvgElementClass *s_svg_class)
d_node_class->get_node_name = lsm_svg_svg_element_get_node_name;
- s_element_class->update = _svg_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_svg_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = _svg_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x",
- offsetof (LsmSvgSvgElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgSvgElement, y));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgSvgElement, width));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgSvgElement, height));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "viewBox",
- offsetof (LsmSvgSvgElement, viewbox));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "preserveAspectRatio",
- offsetof (LsmSvgSvgElement, preserve_aspect_ratio));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_svg_element_attribute_infos),
+ lsm_svg_svg_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgSvgElement, lsm_svg_svg_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgSvgElement, lsm_svg_svg_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgsvgelement.h b/src/lsmsvgsvgelement.h
index bfb9f75..fca6269 100644
--- a/src/lsmsvgsvgelement.h
+++ b/src/lsmsvgsvgelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_SVG_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,9 +37,9 @@ G_BEGIN_DECLS
typedef struct _LsmSvgSvgElementClass LsmSvgSvgElementClass;
struct _LsmSvgSvgElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgStyle *default_style;
+// LsmSvgStyle *default_style;
LsmSvgLengthAttribute x;
LsmSvgLengthAttribute y;
@@ -53,15 +53,13 @@ struct _LsmSvgSvgElement {
};
struct _LsmSvgSvgElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_svg_element_get_type (void);
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);
diff --git a/src/lsmsvgsymbolelement.c b/src/lsmsvgsymbolelement.c
index 410a8ad..1f8b641 100644
--- a/src/lsmsvgsymbolelement.c
+++ b/src/lsmsvgsymbolelement.c
@@ -37,12 +37,6 @@ lsm_svg_symbol_element_get_node_name (LsmDomNode *node)
/* LsmSvgElement implementation */
-static void
-lsm_svg_symbol_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
/* LsmSvgSymbolElement implementation */
@@ -64,15 +58,10 @@ static void
lsm_svg_symbol_element_class_init (LsmSvgSymbolElementClass *klass)
{
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
- LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
d_node_class->get_node_name = lsm_svg_symbol_element_get_node_name;
-
- s_element_class->update = lsm_svg_symbol_element_update;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
}
-G_DEFINE_TYPE (LsmSvgSymbolElement, lsm_svg_symbol_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgSymbolElement, lsm_svg_symbol_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgsymbolelement.h b/src/lsmsvgsymbolelement.h
index c3ea1b1..40ea9e3 100644
--- a/src/lsmsvgsymbolelement.h
+++ b/src/lsmsvgsymbolelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_SYMBOL_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,11 +37,11 @@ G_BEGIN_DECLS
typedef struct _LsmSvgSymbolElementClass LsmSvgSymbolElementClass;
struct _LsmSvgSymbolElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
};
struct _LsmSvgSymbolElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_symbol_element_get_type (void);
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index f89c44e..c891343 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -41,27 +41,10 @@ lsm_svg_text_element_can_append_child (LsmDomNode *self, LsmDomNode *child)
/* LsmSvgElement implementation */
-static void
-lsm_svg_text_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgTextElement *text = LSM_SVG_TEXT_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&text->x, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&text->y, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
static void
-lsm_svg_text_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_text_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgTextElement *text = LSM_SVG_TEXT_ELEMENT (self);
LsmDomNode *node = LSM_DOM_NODE (self);
@@ -78,8 +61,8 @@ lsm_svg_text_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
}
}
- 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);
+ x = lsm_svg_view_normalize_length (view, &text->x.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+ y = lsm_svg_view_normalize_length (view, &text->y.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
lsm_svg_view_show_text (view, g_strstrip (string->str), x, y);
@@ -94,43 +77,58 @@ lsm_svg_text_element_new (void)
return g_object_new (LSM_TYPE_SVG_TEXT_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+
static void
lsm_svg_text_element_init (LsmSvgTextElement *self)
{
+ self->x.length = length_default;
+ self->y.length = length_default;
}
static void
lsm_svg_text_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgTextElement class */
+static const LsmAttributeInfos lsm_svg_text_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgTextElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgTextElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ }
+};
+
static void
-lsm_svg_text_element_class_init (LsmSvgTextElementClass *s_rect_class)
+lsm_svg_text_element_class_init (LsmSvgTextElementClass *s_text_class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (s_rect_class);
- LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
- LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (s_rect_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (s_text_class);
+ LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_text_class);
+ LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_text_class);
- parent_class = g_type_class_peek_parent (s_rect_class);
+ parent_class = g_type_class_peek_parent (s_text_class);
object_class->finalize = lsm_svg_text_element_finalize;
d_node_class->get_node_name = lsm_svg_text_element_get_node_name;
d_node_class->can_append_child = lsm_svg_text_element_can_append_child;
- s_element_class->update = lsm_svg_text_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_text_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_text_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x",
- offsetof (LsmSvgTextElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgTextElement, y));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_text_element_attribute_infos),
+ lsm_svg_text_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgTextElement, lsm_svg_text_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgTextElement, lsm_svg_text_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgtextelement.h b/src/lsmsvgtextelement.h
index c3017ed..8e0a28f 100644
--- a/src/lsmsvgtextelement.h
+++ b/src/lsmsvgtextelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_TEXT_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,14 +37,14 @@ G_BEGIN_DECLS
typedef struct _LsmSvgTextElementClass LsmSvgTextElementClass;
struct _LsmSvgTextElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute x;
- LsmSvgAnimatedLengthAttribute y;
+ LsmSvgLengthAttribute x;
+ LsmSvgLengthAttribute y;
};
struct _LsmSvgTextElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_text_element_get_type (void);
diff --git a/src/lsmsvgtraits.c b/src/lsmsvgtraits.c
new file mode 100644
index 0000000..8eb4c49
--- /dev/null
+++ b/src/lsmsvgtraits.c
@@ -0,0 +1,666 @@
+/* lsmdom.h
+ *
+ * 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 <lsmsvgtraits.h>
+#include <lsmstr.h>
+#include <lsmsvgcolors.h>
+#include <math.h>
+#include <string.h>
+
+const LsmSvgColor lsm_svg_color_null = {0.0, 0.0, 0.0};
+const LsmSvgDashArray lsm_svg_dash_array_null = {0, NULL};
+
+static void
+lsm_svg_length_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgLength *svg_length = (LsmSvgLength *) abstract_trait;
+ char *length_type_str;
+
+ svg_length->value_unit = g_strtod (string, &length_type_str);
+ svg_length->type = lsm_svg_length_type_from_string (length_type_str);
+}
+
+static char *
+lsm_svg_length_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgLength *svg_length = (LsmSvgLength *) abstract_trait;
+
+ return g_strdup_printf ("%g%s",
+ svg_length->value_unit,
+ lsm_svg_length_type_to_string (svg_length->type));
+}
+
+const LsmTraitClass lsm_svg_length_trait_class = {
+ .size = sizeof (LsmSvgLength),
+ .from_string = lsm_svg_length_trait_from_string,
+ .to_string = lsm_svg_length_trait_to_string
+};
+
+static void
+_init_matrix (LsmSvgMatrix *matrix, LsmSvgTransformType transform, unsigned int n_values, double values[])
+{
+ switch (transform) {
+ case LSM_SVG_TRANSFORM_TYPE_SCALE:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_scale (matrix, values[0], values[0]);
+ return;
+ } else if (n_values == 2) {
+ lsm_svg_matrix_init_scale (matrix, values[0], values[1]);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_TRANSLATE:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_translate (matrix, values[0], values[0]);
+ return;
+ } else if (n_values == 2) {
+ lsm_svg_matrix_init_translate (matrix, values[0], values[1]);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_MATRIX:
+ if (n_values == 6) {
+ lsm_svg_matrix_init (matrix,
+ values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_ROTATE:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_rotate (matrix, values[0] * M_PI / 180.0);
+ return;
+ } else if (n_values == 3) {
+ LsmSvgMatrix matrix_b;
+
+ lsm_svg_matrix_init_translate (matrix, values[1], values[2]);
+ lsm_svg_matrix_init_rotate (&matrix_b, values[0] * M_PI / 180.0);
+ lsm_svg_matrix_multiply (matrix, &matrix_b, matrix);
+ lsm_svg_matrix_init_translate (&matrix_b, -values[1], -values[2]);
+ lsm_svg_matrix_multiply (matrix, &matrix_b, matrix);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_SKEW_X:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_skew_x (matrix, values[0] * M_PI / 180.0);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_SKEW_Y:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_skew_y (matrix, values[0] * M_PI / 180.0);
+ return;
+ }
+ default:
+ break;
+ }
+
+ lsm_svg_matrix_init_identity (matrix);
+}
+
+static void
+lsm_svg_matrix_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgMatrix *matrix = (LsmSvgMatrix *) abstract_trait;
+
+ lsm_svg_matrix_init_identity (matrix);
+
+ while (*string != '\0') {
+ LsmSvgTransformType transform;
+ double values[6];
+
+ lsm_str_skip_spaces (&string);
+
+ if (strncmp (string, "translate", 9) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_TRANSLATE;
+ string += 9;
+ } else if (strncmp (string, "scale", 5) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_SCALE;
+ string += 5;
+ } else if (strncmp (string, "rotate", 6) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_ROTATE;
+ string += 6;
+ } else if (strncmp (string, "matrix", 6) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_MATRIX;
+ string += 6;
+ } else if (strncmp (string, "skewX", 5) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_SKEW_X;
+ string += 5;
+ } else if (strncmp (string, "skewY", 5) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_SKEW_Y;
+ string += 5;
+ } else
+ break;
+
+ lsm_str_skip_spaces (&string);
+
+ if (*string == '(') {
+ unsigned int n_values = 0;
+
+ string++;
+
+ while (*string != ')' && *string != '\0' && n_values < 6) {
+ lsm_str_skip_comma_and_spaces (&string);
+
+ if (!lsm_str_parse_double (&string, &values[n_values]))
+ break;
+
+ n_values++;
+ }
+
+ lsm_str_skip_comma_and_spaces (&string);
+
+ if (*string == ')') {
+ LsmSvgMatrix new_matrix;
+
+ string++;
+
+ _init_matrix (&new_matrix, transform, n_values, values);
+
+ lsm_svg_matrix_multiply (matrix, &new_matrix, matrix);
+ }
+ }
+ }
+}
+
+static char *
+lsm_svg_matrix_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgMatrix *matrix = (LsmSvgMatrix *) abstract_trait;
+
+ /* TODO smarter serialization, checking for zeros */
+ return g_strdup_printf ("matrix(%g,%g,%g,%g,%g,%g)",
+ matrix->a,
+ matrix->b,
+ matrix->c,
+ matrix->d,
+ matrix->e,
+ matrix->f);
+}
+
+const LsmTraitClass lsm_svg_matrix_trait_class = {
+ .size = sizeof (LsmSvgMatrix),
+ .from_string = lsm_svg_matrix_trait_from_string,
+ .to_string = lsm_svg_matrix_trait_to_string
+};
+
+static char *
+_parse_color (char *string,
+ LsmSvgColor *svg_color,
+ LsmSvgPaintType *paint_type)
+{
+ unsigned int color = 0;
+
+ lsm_str_skip_spaces (&string);
+
+ if (g_strcmp0 (string, "currentColor") == 0) {
+ svg_color->red = -1.0;
+ svg_color->green = -1.0;
+ svg_color->blue = -1.0;
+
+ *paint_type = LSM_SVG_PAINT_TYPE_CURRENT_COLOR;
+
+ string += 12; /* strlen ("current_color") */
+
+ return string;
+ }
+
+ if (*string == '#') {
+ int value, i;
+ string++;
+
+ for (i = 0; i < 6; i++) {
+ if (*string >= '0' && *string <= '9')
+ value = *string - '0';
+ else if (*string >= 'A' && *string <= 'F')
+ value = *string - 'A' + 10;
+ else if (*string >= 'a' && *string <= 'f')
+ value = *string - 'a' + 10;
+ else
+ break;
+
+ color = (color << 4) + value;
+ string++;
+ }
+
+ if (i == 3) {
+ color = ((color & 0xf00) << 8) | ((color & 0x0f0) << 4) | (color & 0x00f);
+ color |= color << 4;
+ } else if (i != 6)
+ color = 0;
+
+ *paint_type = LSM_SVG_PAINT_TYPE_RGB_COLOR;
+ } else if (strncmp (string, "rgb(", 4) == 0) {
+ int i;
+ double value;
+
+
+ string += 4; /* strlen ("rgb(") */
+
+ for (i = 0; i < 3; i++) {
+ if (!lsm_str_parse_double (&string, &value))
+ break;
+
+ if (*string == '%') {
+ value = value * 255.0 / 100.0;
+ string++;
+ }
+
+ if (i < 2)
+ lsm_str_skip_comma_and_spaces (&string);
+
+ color = (color << 8) + (int) (0.5 + CLAMP (value, 0.0, 255.0));
+ }
+
+ lsm_str_skip_spaces (&string);
+
+ if (*string != ')' || i != 3)
+ color = 0;
+
+ *paint_type = LSM_SVG_PAINT_TYPE_RGB_COLOR;
+ } else if (g_strcmp0 (string, "none") != 0) {
+ color = lsm_svg_color_from_string (string);
+
+ *paint_type = LSM_SVG_PAINT_TYPE_RGB_COLOR;
+ } else {
+ *paint_type = LSM_SVG_PAINT_TYPE_NONE;
+ }
+
+ svg_color->red = (double) ((color & 0xff0000) >> 16) / 255.0;
+ svg_color->green = (double) ((color & 0x00ff00) >> 8) / 255.0;
+ svg_color->blue = (double) (color & 0x0000ff) / 255.0;
+
+ return string;
+}
+
+static void
+lsm_svg_paint_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgPaint *paint = (LsmSvgPaint *) abstract_trait;
+ LsmSvgPaintType paint_type;
+
+ g_free (paint->uri);
+
+ if (strncmp (string, "url(#", 5) == 0) {
+ unsigned int length;
+
+ string += 5;
+ length = 0;
+ while (string[length] != ')')
+ length++;
+ length++;
+
+ paint->uri = g_new (char, length);
+ if (paint->uri != NULL) {
+ memcpy (paint->uri, string, length - 1);
+ paint->uri[length - 1] = '\0';
+ }
+ string += length;
+ } else {
+ paint->uri = NULL;
+ }
+
+ string = _parse_color (string, &paint->color, &paint_type);
+
+ if (paint->uri != NULL)
+ switch (paint_type) {
+ case LSM_SVG_PAINT_TYPE_RGB_COLOR:
+ paint_type = LSM_SVG_PAINT_TYPE_URI_RGB_COLOR;
+ break;
+ case LSM_SVG_PAINT_TYPE_CURRENT_COLOR:
+ paint_type = LSM_SVG_PAINT_TYPE_URI_CURRENT_COLOR;
+ break;
+ case LSM_SVG_PAINT_TYPE_NONE:
+ paint_type = LSM_SVG_PAINT_TYPE_URI;
+ break;
+ case LSM_SVG_PAINT_TYPE_RGB_COLOR_ICC_COLOR:
+ paint_type = LSM_SVG_PAINT_TYPE_URI_RGB_COLOR_ICC_COLOR;
+ break;
+ default:
+ paint_type = LSM_SVG_PAINT_TYPE_URI;
+ break;
+ }
+
+ paint->type = paint_type;
+}
+
+char *
+lsm_svg_paint_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgPaint *paint = (LsmSvgPaint *) abstract_trait;
+
+ if (paint->color.red < 0.0 || paint->color.green < 0.0 || paint->color.blue < 0.0)
+ return g_strdup ("currentColor");
+
+ if (paint->uri != NULL)
+ g_strdup_printf ("url(#%s)", paint->uri);
+
+ return g_strdup_printf ("rgb(%g%%,%g%%,%g%%)",
+ 100.0 * paint->color.red,
+ 100.0 * paint->color.green,
+ 100.0 * paint->color.blue);
+}
+
+const LsmTraitClass lsm_svg_paint_trait_class = {
+ .size = sizeof (LsmSvgPaint),
+ .from_string = lsm_svg_paint_trait_from_string,
+ .to_string = lsm_svg_paint_trait_to_string
+};
+
+static void
+lsm_svg_fill_rule_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgFillRule *trait = (LsmSvgFillRule *) abstract_trait;
+
+ *trait = lsm_svg_fill_rule_from_string (string);
+}
+
+char *
+lsm_svg_fill_rule_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgFillRule *trait = (LsmSvgFillRule *) abstract_trait;
+
+ return g_strdup (lsm_svg_fill_rule_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_fill_rule_trait_class = {
+ .size = sizeof (LsmSvgFillRule),
+ .from_string = lsm_svg_fill_rule_trait_from_string,
+ .to_string = lsm_svg_fill_rule_trait_to_string
+};
+
+static void
+lsm_svg_line_join_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgLineJoin *trait = (LsmSvgLineJoin *) abstract_trait;
+
+ *trait = lsm_svg_line_join_from_string (string);
+}
+
+char *
+lsm_svg_line_join_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgLineJoin *trait = (LsmSvgLineJoin *) abstract_trait;
+
+ return g_strdup (lsm_svg_line_join_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_line_join_trait_class = {
+ .size = sizeof (LsmSvgLineJoin),
+ .from_string = lsm_svg_line_join_trait_from_string,
+ .to_string = lsm_svg_line_join_trait_to_string
+};
+
+static void
+lsm_svg_line_cap_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgLineCap *trait = (LsmSvgLineCap *) abstract_trait;
+
+ *trait = lsm_svg_line_cap_from_string (string);
+}
+
+static char *
+lsm_svg_line_cap_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgLineCap *trait = (LsmSvgLineCap *) abstract_trait;
+
+ return g_strdup (lsm_svg_line_cap_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_line_cap_trait_class = {
+ .size = sizeof (LsmSvgLineCap),
+ .from_string = lsm_svg_line_cap_trait_from_string,
+ .to_string = lsm_svg_line_cap_trait_to_string
+};
+
+LsmSvgDashArray *
+lsm_svg_dash_array_new (unsigned int n_dashes)
+{
+ LsmSvgDashArray *array;
+
+ g_return_val_if_fail (n_dashes > 0, (LsmSvgDashArray *) &lsm_svg_dash_array_null);
+
+ array = g_new (LsmSvgDashArray, 1);
+ if (array != NULL) {
+ array->n_dashes = n_dashes;
+ array->dashes = g_new (LsmSvgLength, n_dashes);
+ if (array->dashes != NULL)
+ return array;
+ g_free (array);
+ }
+
+ return (LsmSvgDashArray *) &lsm_svg_dash_array_null;
+}
+
+void
+lsm_svg_dash_array_free (LsmSvgDashArray *array)
+{
+ if (array == NULL || array == &lsm_svg_dash_array_null)
+ return;
+
+ g_free (array->dashes);
+ g_free (array);
+}
+
+LsmSvgDashArray *
+lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin)
+{
+ LsmSvgDashArray *duplicate;
+
+ if (origin == NULL || origin == &lsm_svg_dash_array_null)
+ return (LsmSvgDashArray *) &lsm_svg_dash_array_null;
+
+ duplicate = lsm_svg_dash_array_new (origin->n_dashes);
+
+ if (duplicate != &lsm_svg_dash_array_null)
+ memcpy (duplicate->dashes, origin->dashes, sizeof (LsmSvgLength) * origin->n_dashes);
+
+ return duplicate;
+}
+
+static void
+lsm_svg_dash_array_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgDashArray *dash_array = (LsmSvgDashArray *) abstract_trait;
+ unsigned int n_dashes = 1;
+
+ g_free (dash_array->dashes);
+ dash_array->n_dashes = 0;
+ dash_array->dashes = NULL;
+
+ if (strcmp (string, "none") != 0) {
+ char *iter = (char *) string;
+ unsigned int i;
+
+ while (*iter != '\0') {
+ if (*iter == ',')
+ n_dashes++;
+ iter++;
+ }
+
+ if (n_dashes > 0) {
+ LsmSvgLength length;
+
+ dash_array->n_dashes = n_dashes;
+ dash_array->dashes = g_new (LsmSvgLength, n_dashes);
+
+ iter = (char *)string;
+ lsm_str_skip_spaces (&iter);
+
+ for (i = 0; i < n_dashes; i++) {
+ if (lsm_str_parse_double (&iter, &length.value_unit)) {
+ length.type = lsm_svg_length_type_from_string (iter);
+ dash_array->dashes[i] = length;
+ while (*iter != '\0' && *iter != ' ' && *iter != ',')
+ iter ++;
+ } else {
+ dash_array->dashes[i].value_unit = 0.0;
+ dash_array->dashes[i].value_unit = LSM_SVG_LENGTH_TYPE_NUMBER;
+ }
+ lsm_str_skip_comma_and_spaces (&iter);
+ }
+ }
+ }
+}
+
+static char *
+lsm_svg_dash_array_trait_to_string (LsmTrait *abstract_trait)
+{
+ g_assert_not_reached ();
+}
+
+static void
+lsm_svg_dash_array_trait_finalize (LsmTrait *abstract_trait)
+{
+ LsmSvgDashArray *dash_array = (LsmSvgDashArray *) abstract_trait;
+
+ g_free (dash_array->dashes);
+ dash_array->n_dashes = 0;
+ dash_array->dashes = NULL;
+}
+
+const LsmTraitClass lsm_svg_dash_array_trait_class = {
+ .size = sizeof (LsmSvgDashArray),
+ .from_string = lsm_svg_dash_array_trait_from_string,
+ .to_string = lsm_svg_dash_array_trait_to_string,
+ .finalize = lsm_svg_dash_array_trait_finalize
+};
+
+static void
+lsm_svg_color_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgColor *color = (LsmSvgColor *) abstract_trait;
+ LsmSvgPaintType paint_type;
+
+ _parse_color (string, color, &paint_type);
+}
+
+static char *
+lsm_svg_color_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgColor *color = (LsmSvgColor *) abstract_trait;
+
+ if (color->red < 0.0 || color->green < 0.0 || color->blue < 0.0)
+ return g_strdup ("currentColor");
+
+ return g_strdup_printf ("rgb(%g%%,%g%%,%g%%)",
+ 100.0 * color->red,
+ 100.0 * color->green,
+ 100.0 * color->blue);
+}
+
+const LsmTraitClass lsm_svg_color_trait_class = {
+ .size = sizeof (LsmSvgColor),
+ .from_string = lsm_svg_color_trait_from_string,
+ .to_string = lsm_svg_color_trait_to_string
+};
+
+static void
+lsm_svg_pattern_units_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgPatternUnits *trait = (LsmSvgPatternUnits *) abstract_trait;
+
+ *trait = lsm_svg_pattern_units_from_string (string);
+}
+
+char *
+lsm_svg_pattern_units_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgPatternUnits *trait = (LsmSvgPatternUnits *) abstract_trait;
+
+ return g_strdup (lsm_svg_pattern_units_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_pattern_units_trait_class = {
+ .size = sizeof (LsmSvgPatternUnits),
+ .from_string = lsm_svg_pattern_units_trait_from_string,
+ .to_string = lsm_svg_pattern_units_trait_to_string
+};
+
+static void
+lsm_svg_preserve_aspect_ratio_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgPreserveAspectRatio *trait = (LsmSvgPreserveAspectRatio *) abstract_trait;
+
+ char **tokens;
+ unsigned int i = 0;
+
+ tokens = g_strsplit (string, " ", -1);
+
+ if (tokens[i] != NULL && strcmp (tokens[i], "defer") == 0) {
+ trait->defer = TRUE;
+ i++;
+ } else
+ trait->defer = FALSE;
+
+ if (tokens[i] != NULL) {
+ trait->align = lsm_svg_align_from_string (tokens[i]);
+ i++;
+ if (tokens[i] != NULL)
+ trait->meet_or_slice = lsm_svg_meet_or_slice_from_string (tokens[i]);
+ else
+ trait->meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET;
+ } else trait->align = LSM_SVG_ALIGN_X_MID_Y_MID;
+
+ g_strfreev (tokens);
+}
+
+char *
+lsm_svg_preserve_aspect_ratio_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgPreserveAspectRatio *trait = (LsmSvgPreserveAspectRatio *) abstract_trait;
+
+ return g_strdup_printf ("%s%s %s", trait->defer ? "defer " : "",
+ lsm_svg_align_to_string (trait->align),
+ lsm_svg_meet_or_slice_to_string (trait->meet_or_slice));
+}
+
+const LsmTraitClass lsm_svg_preserve_aspect_ratio_trait_class = {
+ .size = sizeof (LsmSvgPreserveAspectRatio),
+ .from_string = lsm_svg_preserve_aspect_ratio_trait_from_string,
+ .to_string = lsm_svg_preserve_aspect_ratio_trait_to_string
+};
+
+static void
+lsm_svg_spread_method_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgSpreadMethod *trait = (LsmSvgSpreadMethod *) abstract_trait;
+
+ *trait = lsm_svg_spread_method_from_string (string);
+}
+
+static char *
+lsm_svg_spread_method_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgSpreadMethod *trait = (LsmSvgSpreadMethod *) abstract_trait;
+
+ return g_strdup (lsm_svg_spread_method_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_spread_method_trait_class = {
+ .size = sizeof (LsmSvgSpreadMethod),
+ .from_string = lsm_svg_spread_method_trait_from_string,
+ .to_string = lsm_svg_spread_method_trait_to_string
+};
+
diff --git a/src/lsmsvgtraits.h b/src/lsmsvgtraits.h
new file mode 100644
index 0000000..e33c474
--- /dev/null
+++ b/src/lsmsvgtraits.h
@@ -0,0 +1,77 @@
+/*
+ * 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_TRAITS_H
+#define LSM_SVG_TRAITS_H
+
+#include <lsmtraits.h>
+#include <lsmsvglength.h>
+#include <lsmsvgmatrix.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ double red;
+ double green;
+ double blue;
+} LsmSvgColor;
+
+extern const LsmSvgColor lsm_svg_color_null;
+
+typedef struct {
+ unsigned int n_dashes;
+ LsmSvgLength *dashes;
+} LsmSvgDashArray;
+
+extern const LsmSvgDashArray lsm_svg_dash_array_null;
+
+LsmSvgDashArray * lsm_svg_dash_array_new (unsigned int n_dashes);
+void lsm_svg_dash_array_free (LsmSvgDashArray *array);
+LsmSvgDashArray * lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin);
+void lsm_svg_dash_array_copy (LsmSvgDashArray *to, const LsmSvgDashArray *from);
+
+typedef struct {
+ LsmSvgPaintType type;
+ char *uri;
+ LsmSvgColor color;
+} LsmSvgPaint;
+
+typedef struct {
+ gboolean defer;
+ LsmSvgAlign align;
+ LsmSvgMeetOrSlice meet_or_slice;
+} LsmSvgPreserveAspectRatio;
+
+extern const LsmTraitClass lsm_svg_length_trait_class;
+extern const LsmTraitClass lsm_svg_matrix_trait_class;
+extern const LsmTraitClass lsm_svg_paint_trait_class;
+extern const LsmTraitClass lsm_svg_fill_rule_trait_class;
+extern const LsmTraitClass lsm_svg_line_join_trait_class;
+extern const LsmTraitClass lsm_svg_line_cap_trait_class;
+extern const LsmTraitClass lsm_svg_dash_array_trait_class;
+extern const LsmTraitClass lsm_svg_color_trait_class;
+extern const LsmTraitClass lsm_svg_pattern_units_trait_class;
+extern const LsmTraitClass lsm_svg_preserve_aspect_ratio_trait_class;
+extern const LsmTraitClass lsm_svg_spread_method_trait_class;
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvguseelement.c b/src/lsmsvguseelement.c
index 819ecea..5fcb2ee 100644
--- a/src/lsmsvguseelement.c
+++ b/src/lsmsvguseelement.c
@@ -43,35 +43,10 @@ lsm_svg_use_can_append_child (LsmDomNode *node, LsmDomNode *child)
/* LsmSvgElement implementation */
-static void
-lsm_svg_use_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
-{
- LsmSvgUseElement *use_element = LSM_SVG_USE_ELEMENT (self);
- LsmSvgLength length;
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->x, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->y, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->width, &length);
-
- length.value_unit = 0.0;
- length.type = LSM_SVG_LENGTH_TYPE_PX;
- lsm_svg_animated_length_attribute_parse (&use_element->height, &length);
-
- LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
-}
-
/* LsmSvgGraphic implementation */
static void
-lsm_svg_use_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_use_element_render (LsmSvgElement *self, LsmSvgView *view)
{
LsmSvgUseElement *use_element;
LsmDomDocument *document;
@@ -82,7 +57,7 @@ lsm_svg_use_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
document = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
if (document == NULL) {
- lsm_debug ("[LsmSvgUseElement::graphic_render] Owner document not found");
+ lsm_debug ("[LsmSvgUseElement::render] Owner document not found");
return;
}
@@ -98,22 +73,20 @@ lsm_svg_use_element_graphic_render (LsmSvgElement *self, LsmSvgView *view)
element = lsm_dom_document_get_element_by_id (document, id);
if (!LSM_IS_SVG_ELEMENT (element)) {
- lsm_debug ("[LsmSvgUseElement::graphic_render] Target '%s' not found", id);
+ lsm_debug ("[LsmSvgUseElement::render] Target '%s' not found", id);
return;
}
- width = lsm_svg_view_normalize_length (view, &use_element->width.length.base,
+ width = lsm_svg_view_normalize_length (view, &use_element->width.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- height = lsm_svg_view_normalize_length (view, &use_element->height.length.base,
+ height = lsm_svg_view_normalize_length (view, &use_element->height.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
-/* if (width <= 0.0 || height <= 0.0)*/
-/* return;*/
- lsm_debug ("[LsmSvgUseElement::graphic_render] Use '%s'", id);
+ lsm_debug ("[LsmSvgUseElement::render] Use '%s'", id);
- x = lsm_svg_view_normalize_length (view, &use_element->x.length.base,
+ x = lsm_svg_view_normalize_length (view, &use_element->x.length,
LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
- y = lsm_svg_view_normalize_length (view, &use_element->y.length.base,
+ y = lsm_svg_view_normalize_length (view, &use_element->y.length,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
lsm_svg_matrix_init_translate (&matrix, x, y);
@@ -132,41 +105,68 @@ lsm_svg_use_element_new (void)
return g_object_new (LSM_TYPE_SVG_USE_ELEMENT, NULL);
}
+static const LsmSvgLength length_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
+
static void
lsm_svg_use_element_init (LsmSvgUseElement *self)
{
+ self->x.length = length_default;
+ self->y.length = length_default;
+ self->width.length = length_default;
+ self->height.length = length_default;
}
/* LsmSvgUseElement class */
+static const LsmAttributeInfos lsm_svg_use_element_attribute_infos[] = {
+ {
+ .name = "x",
+ .attribute_offset = offsetof (LsmSvgUseElement, x),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "y",
+ .attribute_offset = offsetof (LsmSvgUseElement, y),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "width",
+ .attribute_offset = offsetof (LsmSvgUseElement, width),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "height",
+ .attribute_offset = offsetof (LsmSvgUseElement, height),
+ .trait_class = &lsm_svg_length_trait_class,
+ .trait_default = &length_default
+ },
+ {
+ .name = "xlink:href",
+ .attribute_offset = offsetof (LsmSvgUseElement, href),
+ .trait_class = &lsm_null_trait_class
+ }
+};
+
static void
lsm_svg_use_element_class_init (LsmSvgUseElementClass *klass)
{
LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
- LsmSvgGraphicClass *s_graphic_class = LSM_SVG_GRAPHIC_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
d_node_class->get_node_name = lsm_svg_use_element_get_node_name;
d_node_class->can_append_child = lsm_svg_use_can_append_child;
- s_element_class->update = lsm_svg_use_element_update;
-
- s_graphic_class->graphic_render = lsm_svg_use_element_graphic_render;
-
- s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+ s_element_class->render = lsm_svg_use_element_render;
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x",
- offsetof (LsmSvgUseElement, x));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
- offsetof (LsmSvgUseElement, y));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
- offsetof (LsmSvgUseElement, width));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
- offsetof (LsmSvgUseElement, height));
- lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "xlink:href",
- offsetof (LsmSvgUseElement, href));
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_use_element_attribute_infos),
+ lsm_svg_use_element_attribute_infos);
}
-G_DEFINE_TYPE (LsmSvgUseElement, lsm_svg_use_element, LSM_TYPE_SVG_GRAPHIC)
+G_DEFINE_TYPE (LsmSvgUseElement, lsm_svg_use_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvguseelement.h b/src/lsmsvguseelement.h
index 285d7e8..3645d90 100644
--- a/src/lsmsvguseelement.h
+++ b/src/lsmsvguseelement.h
@@ -23,7 +23,7 @@
#define LSM_SVG_USE_ELEMENT_H
#include <lsmsvg.h>
-#include <lsmsvggraphic.h>
+#include <lsmsvgelement.h>
G_BEGIN_DECLS
@@ -37,18 +37,18 @@ G_BEGIN_DECLS
typedef struct _LsmSvgUseElementClass LsmSvgUseElementClass;
struct _LsmSvgUseElement {
- LsmSvgGraphic graphic;
+ LsmSvgElement element;
- LsmSvgAnimatedLengthAttribute x;
- LsmSvgAnimatedLengthAttribute y;
- LsmSvgAnimatedLengthAttribute width;
- LsmSvgAnimatedLengthAttribute height;
+ LsmSvgLengthAttribute x;
+ LsmSvgLengthAttribute y;
+ LsmSvgLengthAttribute width;
+ LsmSvgLengthAttribute height;
- LsmDomAttribute href;
+ LsmAttribute href;
};
struct _LsmSvgUseElementClass {
- LsmSvgGraphicClass parent_class;
+ LsmSvgElementClass element_class;
};
GType lsm_svg_use_element_get_type (void);
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 0aaed98..58845fc 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -28,7 +28,7 @@
#include <lsmsvgpatternelement.h>
#include <lsmsvgclippathelement.h>
#include <lsmsvgmaskelement.h>
-#include <lsmsvgutils.h>
+#include <lsmstr.h>
#include <gdk/gdk.h>
#include <glib/gprintf.h>
@@ -58,11 +58,8 @@ lsm_svg_view_normalize_length (LsmSvgView *view, const LsmSvgLength *length, Lsm
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,
+ if (view->viewbox_stack != NULL && view->style != NULL) {
+ font_size = lsm_svg_length_normalize (&view->style->font_size->length, view->viewbox_stack->data,
0.0, LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
} else
font_size = 0.0;
@@ -120,6 +117,7 @@ _set_pattern (LsmSvgView *view, cairo_pattern_t *pattern)
g_return_if_fail (view->pattern_data->pattern == NULL);
view->pattern_data->pattern = pattern;
+ view->last_stop_offset = 0.0;
}
void
@@ -144,15 +142,37 @@ lsm_svg_view_create_linear_gradient (LsmSvgView *view,
}
void
-lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset, const LsmSvgColor *color, double opacity)
+lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset)
{
+ const LsmSvgStyle *style;
+ const LsmSvgColor *color;
+
g_return_if_fail (LSM_IS_SVG_VIEW (view));
g_return_if_fail (view->pattern_data != NULL);
g_return_if_fail (view->pattern_data->pattern != NULL);
- g_return_if_fail (color != NULL);
+
+ if (offset > 1.0)
+ offset = 1.0;
+
+ if (offset < view->last_stop_offset)
+ offset = view->last_stop_offset;
+ else
+ view->last_stop_offset = offset;
+
+ style = view->style;
+
+ lsm_debug ("[LsmSvgView::add_gradient_color_stop] opacity = %g", style->stop_opacity->value);
+
+ color = &style->stop_color->value;
+
+ if (color->red < 0.0 || color->blue < 0.0 || color->green < 0.0)
+ color = &style->color->value;
cairo_pattern_add_color_stop_rgba (view->pattern_data->pattern, offset,
- color->red, color->green, color->blue, opacity);
+ color->red,
+ color->green,
+ color->blue,
+ style->stop_opacity->value);
}
void
@@ -199,13 +219,6 @@ lsm_svg_view_create_surface_pattern (LsmSvgView *view,
width = viewport->width;
height = viewport->height;
-/* if (units == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX) {*/
-/* x *= view->pattern_data->extents.width;*/
-/* y *= view->pattern_data->extents.height;*/
-/* width *= view->pattern_data->extents.width;*/
-/* height *= view->pattern_data->extents.height;*/
-/* }*/
-
lsm_debug ("[LsmSvgView::create_pattern] pattern size = %g ,%g at %g, %g",
width, height, x, y);
@@ -474,7 +487,7 @@ static void
_emit_function_1 (LsmSvgPathContext *ctxt,
void (*cairo_func) (cairo_t *, double))
{
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 1, ctxt->values))
+ while (lsm_str_parse_double_list (&ctxt->ptr, 1, ctxt->values))
cairo_func (ctxt->cr, ctxt->values[0]);
}
@@ -484,12 +497,12 @@ _emit_function_2 (LsmSvgPathContext *ctxt,
void (*cairo_func_b) (cairo_t *, double, double))
{
- if (lsm_svg_str_parse_double_list (&ctxt->ptr, 2, ctxt->values)) {
+ if (lsm_str_parse_double_list (&ctxt->ptr, 2, ctxt->values)) {
cairo_func_a (ctxt->cr, ctxt->values[0], ctxt->values[1]);
/* Why oh why does the specification say Line is implied here ? */
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 2, ctxt->values))
+ while (lsm_str_parse_double_list (&ctxt->ptr, 2, ctxt->values))
cairo_func_b (ctxt->cr, ctxt->values[0], ctxt->values[1]);
}
}
@@ -498,7 +511,7 @@ static void
_emit_function_4 (LsmSvgPathContext *ctxt,
void (*cairo_func) (cairo_t *, double, double, double, double))
{
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 4, ctxt->values))
+ while (lsm_str_parse_double_list (&ctxt->ptr, 4, ctxt->values))
cairo_func (ctxt->cr, ctxt->values[0], ctxt->values[1], ctxt->values[2], ctxt->values[3]);
}
@@ -530,7 +543,7 @@ _emit_smooth_curve (LsmSvgPathContext *ctxt, gboolean relative)
default: x = x0; y = y0; break;
}
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 4, ctxt->values)) {
+ while (lsm_str_parse_double_list (&ctxt->ptr, 4, ctxt->values)) {
if (relative) {
cairo_get_current_point (ctxt->cr, &x0, &y0);
cairo_curve_to (ctxt->cr,
@@ -571,7 +584,7 @@ _emit_smooth_quadratic_curve (LsmSvgPathContext *ctxt, gboolean relative)
default: ctxt->last_cp_x = x0; ctxt->last_cp_y = y0; break;
}
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 2, ctxt->values)) {
+ while (lsm_str_parse_double_list (&ctxt->ptr, 2, ctxt->values)) {
x = 2 * x0 - ctxt->last_cp_x;
y = 2 * y0 - ctxt->last_cp_y;
if (relative) {
@@ -590,7 +603,7 @@ static void
_emit_function_6 (LsmSvgPathContext *ctxt,
void (*cairo_func) (cairo_t *, double, double, double ,double, double, double))
{
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 6, ctxt->values))
+ while (lsm_str_parse_double_list (&ctxt->ptr, 6, ctxt->values))
cairo_func (ctxt->cr, ctxt->values[0], ctxt->values[1], ctxt->values[2],
ctxt->values[3], ctxt->values[4], ctxt->values[5]);
}
@@ -599,7 +612,7 @@ static void
_emit_function_7 (LsmSvgPathContext *ctxt,
void (*cairo_func) (cairo_t *, double, double, double ,gboolean, gboolean, double, double))
{
- while (lsm_svg_str_parse_double_list (&ctxt->ptr, 7, ctxt->values))
+ while (lsm_str_parse_double_list (&ctxt->ptr, 7, ctxt->values))
cairo_func (ctxt->cr, ctxt->values[0], ctxt->values[1], ctxt->values[2],
ctxt->values[3], ctxt->values[4], ctxt->values[5],
ctxt->values[6]);
@@ -624,14 +637,14 @@ _emit_svg_path (cairo_t *cr, char const *path)
ctxt.values[2] = ctxt.values[4] = ctxt.values[0];
ctxt.values[3] = ctxt.values[5] = ctxt.values[1];
- lsm_svg_str_skip_spaces (&ctxt.ptr);
+ lsm_str_skip_spaces (&ctxt.ptr);
while (*ctxt.ptr != '\0') {
char command;
command = *ctxt.ptr;
ctxt.ptr++;
- lsm_svg_str_skip_spaces (&ctxt.ptr);
+ lsm_str_skip_spaces (&ctxt.ptr);
if (!cairo_has_current_point (cr)) {
cairo_move_to (cr, 0, 0);
@@ -694,7 +707,7 @@ _paint_uri (LsmSvgView *view, LsmSvgViewPaintOperation operation, const char *ur
_start_pattern (view, &extents);
- lsm_svg_element_render_paint (LSM_SVG_ELEMENT (element), view);
+ lsm_svg_element_force_render (LSM_SVG_ELEMENT (element), view);
cairo = view->pattern_data->old_cairo;
@@ -765,6 +778,13 @@ _set_color (LsmSvgView *view, LsmSvgViewPaintOperation operation,
paint->color.blue,
opacity);
break;
+ case LSM_SVG_PAINT_TYPE_CURRENT_COLOR:
+ cairo_set_source_rgba (cairo,
+ view->style->color->value.red,
+ view->style->color->value.green,
+ view->style->color->value.blue,
+ opacity);
+ break;
case LSM_SVG_PAINT_TYPE_URI:
case LSM_SVG_PAINT_TYPE_URI_RGB_COLOR:
case LSM_SVG_PAINT_TYPE_URI_CURRENT_COLOR:
@@ -781,33 +801,24 @@ _set_color (LsmSvgView *view, LsmSvgViewPaintOperation operation,
static void
paint (LsmSvgView *view)
{
- LsmSvgFillAttributeBag *fill;
- LsmSvgStrokeAttributeBag *stroke;
- LsmSvgGraphic *graphic;
+ LsmSvgElement *element;
+ const LsmSvgStyle *style;
cairo_t *cairo;
gboolean use_group;
double group_opacity;
- g_return_if_fail (view->fill_stack != NULL);
- g_return_if_fail (view->stroke_stack != NULL);
- g_return_if_fail (view->element_stack != NULL);
-
- graphic = view->element_stack->data;
+ element = view->element_stack->data;
- g_return_if_fail (LSM_IS_SVG_GRAPHIC (graphic));
+ g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
cairo = view->dom_view.cairo;
- fill = view->fill_stack->data;
- stroke = view->stroke_stack->data;
-
- if (view->mask_stack != NULL && view->mask_stack->data == graphic->mask) {
- LsmSvgMaskAttributeBag *mask;
+ style = view->style;
- mask = view->mask_stack->data;
- group_opacity = mask->opacity.value;
+ if (style->opacity != NULL) {
+ group_opacity = style->opacity->value;
- use_group = fill->paint.paint.type != LSM_SVG_PAINT_TYPE_NONE &&
- stroke->paint.paint.type != LSM_SVG_PAINT_TYPE_NONE &&
+ use_group = style->fill->paint.type != LSM_SVG_PAINT_TYPE_NONE &&
+ style->stroke->paint.type != LSM_SVG_PAINT_TYPE_NONE &&
group_opacity < 1.0;
} else {
use_group = FALSE;
@@ -818,18 +829,22 @@ paint (LsmSvgView *view)
if (use_group)
cairo_push_group (cairo);
- if (_set_color (view, LSM_SVG_VIEW_PAINT_OPERATION_FILL,
- &fill->paint.paint, fill->opacity.value * (use_group ? 1.0 : group_opacity))) {
- cairo_set_fill_rule (cairo, fill->rule.value == LSM_SVG_FILL_RULE_EVEN_ODD ?
+ if (_set_color (view,
+ LSM_SVG_VIEW_PAINT_OPERATION_FILL,
+ &style->fill->paint,
+ style->fill_opacity->value * (use_group ? 1.0 : group_opacity))) {
+ cairo_set_fill_rule (cairo, style->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, LSM_SVG_VIEW_PAINT_OPERATION_STROKE,
- &stroke->paint.paint, stroke->opacity.value * (use_group ? 1.0 : group_opacity))) {
+ if (_set_color (view,
+ LSM_SVG_VIEW_PAINT_OPERATION_STROKE,
+ &style->stroke->paint,
+ style->stroke_opacity->value * (use_group ? 1.0 : group_opacity))) {
double line_width;
- switch (stroke->line_join.value) {
+ switch (style->stroke_line_join->value) {
case LSM_SVG_LINE_JOIN_MITER:
cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
break;
@@ -840,7 +855,7 @@ paint (LsmSvgView *view)
cairo_set_line_join (cairo,CAIRO_LINE_JOIN_BEVEL);
}
- switch (stroke->line_cap.value) {
+ switch (style->stroke_line_cap->value) {
case LSM_SVG_LINE_CAP_BUTT:
cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT);
break;
@@ -851,31 +866,26 @@ paint (LsmSvgView *view)
cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE);
}
- line_width = lsm_svg_view_normalize_length (view, &stroke->width.length,
+ line_width = lsm_svg_view_normalize_length (view, &style->stroke_width->length,
LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- cairo_set_miter_limit (cairo, stroke->miter_limit.value);
+ cairo_set_miter_limit (cairo, style->stroke_miter_limit->value);
cairo_set_line_width (cairo, line_width);
- if (stroke->dash_array.value != NULL &&
- stroke->dash_array.value->n_dashes > 0) {
+ if (style->stroke_dash_array->value.n_dashes > 0) {
double dash_offset;
double *dashes;
unsigned int i;
- dash_offset = lsm_svg_view_normalize_length (view, &stroke->dash_offset.length,
+ dash_offset = lsm_svg_view_normalize_length (view, &style->stroke_dash_offset->length,
LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- dashes = g_new(double, stroke->dash_array.value->n_dashes);
- for (i = 0; i < stroke->dash_array.value->n_dashes; i++)
+ dashes = g_new (double, style->stroke_dash_array->value.n_dashes);
+ for (i = 0; i < style->stroke_dash_array->value.n_dashes; i++)
dashes[i] = lsm_svg_view_normalize_length (view,
- &stroke->dash_array.value->dashes[i],
+ &style->stroke_dash_array->value.dashes[i],
LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- cairo_set_dash (cairo,
- dashes,
- stroke->dash_array.value->n_dashes,
- dash_offset);
-
+ cairo_set_dash (cairo, dashes, style->stroke_dash_array->value.n_dashes, dash_offset);
g_free (dashes);
} else
cairo_set_dash (cairo, NULL, 0, 0.0);
@@ -894,11 +904,10 @@ paint (LsmSvgView *view)
static void
process_path (LsmSvgView *view)
{
- if (view->is_clipping) {
- LsmSvgMaskAttributeBag *mask;
+ g_return_if_fail (view->style != NULL);
- mask = view->mask_stack->data;
- cairo_set_fill_rule (view->dom_view.cairo, mask->clip_rule.value);
+ if (view->is_clipping) {
+ cairo_set_fill_rule (view->dom_view.cairo, view->style->clip_rule->value);
} else
paint (view);
}
@@ -1018,9 +1027,9 @@ lsm_svg_view_show_polyline (LsmSvgView *view, const char *points)
str = (char *) points;
- if (lsm_svg_str_parse_double_list (&str, 2, values)) {
+ if (lsm_str_parse_double_list (&str, 2, values)) {
cairo_move_to (view->dom_view.cairo, values[0], values[1]);
- while (lsm_svg_str_parse_double_list (&str, 2, values))
+ while (lsm_str_parse_double_list (&str, 2, values))
cairo_line_to (view->dom_view.cairo, values[0], values[1]);
}
@@ -1037,9 +1046,9 @@ lsm_svg_view_show_polygon (LsmSvgView *view, const char *points)
str = (char *) points;
- if (lsm_svg_str_parse_double_list (&str, 2, values)) {
+ if (lsm_str_parse_double_list (&str, 2, values)) {
cairo_move_to (view->dom_view.cairo, values[0], values[1]);
- while (lsm_svg_str_parse_double_list (&str, 2, values))
+ while (lsm_str_parse_double_list (&str, 2, values))
cairo_line_to (view->dom_view.cairo, values[0], values[1]);
}
@@ -1051,11 +1060,11 @@ lsm_svg_view_show_polygon (LsmSvgView *view, const char *points)
void
lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y)
{
+ const LsmSvgStyle *style;
PangoLayout *pango_layout;
PangoFontDescription *font_description;
PangoLayoutIter *iter;
PangoRectangle ink_rect;
- LsmSvgTextAttributeBag *text;
double font_size;
int baseline;
@@ -1064,15 +1073,15 @@ lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- text = view->text_stack->data;
- g_return_if_fail (text != NULL);
+ style = view->style;
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);
+ font_size = lsm_svg_view_normalize_length (view, &style->font_size->length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
- pango_font_description_set_family (font_description, text->font_family.value);
+ pango_font_description_set_family (font_description, style->font_family->value);
pango_font_description_set_size (font_description, font_size * PANGO_SCALE);
pango_layout_set_text (pango_layout, string, -1);
@@ -1227,7 +1236,7 @@ lsm_svg_view_pop_viewport (LsmSvgView *view)
}
void
-lsm_svg_view_push_matrix (LsmSvgView *view, LsmSvgMatrix *matrix)
+lsm_svg_view_push_matrix (LsmSvgView *view, const LsmSvgMatrix *matrix)
{
cairo_matrix_t cr_matrix;
cairo_matrix_t *ctm;
@@ -1273,25 +1282,29 @@ lsm_svg_view_pop_matrix (LsmSvgView *view)
}
void
-lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
+lsm_svg_view_push_group_opacity (LsmSvgView *view)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
+ g_return_if_fail (view->style != NULL);
- view->element_stack = g_slist_prepend (view->element_stack, (void *) element);
+ if (view->style->opacity->value < 1.0)
+ cairo_push_group (view->dom_view.cairo);
}
void
-lsm_svg_view_pop_element (LsmSvgView *view)
+lsm_svg_view_pop_group_opacity (LsmSvgView *view)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->element_stack != NULL);
+ g_return_if_fail (view->style != NULL);
- view->element_stack = g_slist_delete_link (view->element_stack, view->element_stack);
+ if (view->style->opacity->value < 1.0) {
+ cairo_pop_group_to_source (view->dom_view.cairo);
+ cairo_paint_with_alpha (view->dom_view.cairo, view->style->opacity->value);
+ }
}
static void
-lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_rule)
+lsm_svg_view_push_clip (LsmSvgView *view)
{
LsmDomElement *element;
LsmExtents extents;
@@ -1302,9 +1315,9 @@ lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_r
lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
- uri = clip_path;
+ uri = view->style->clip_path->value;
- lsm_debug ("[LsmSvgView::push_clip] Using '%s'", clip_path);
+ lsm_debug ("[LsmSvgView::push_clip] Using '%s'", uri);
cairo_save (view->dom_view.cairo);
@@ -1326,7 +1339,7 @@ lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_r
if (element != NULL && LSM_IS_SVG_CLIP_PATH_ELEMENT (element)) {
view->is_clipping = TRUE;
- lsm_svg_element_render_clip (LSM_SVG_ELEMENT (element), view);
+ lsm_svg_element_force_render (LSM_SVG_ELEMENT (element), view);
cairo_clip (view->dom_view.cairo);
view->is_clipping = FALSE;
}
@@ -1341,194 +1354,152 @@ lsm_svg_view_pop_clip (LsmSvgView *view)
cairo_restore (view->dom_view.cairo);
}
-void
-lsm_svg_view_push_group_opacity (LsmSvgView *view)
+static void
+lsm_svg_view_push_mask (LsmSvgView *view)
{
- LsmSvgMaskAttributeBag *mask;
-
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->mask_stack != NULL);
-
- mask = view->mask_stack->data;
- if (mask->opacity.value < 1.0)
- cairo_push_group (view->dom_view.cairo);
+ cairo_push_group (view->dom_view.cairo);
}
-void
-lsm_svg_view_pop_group_opacity (LsmSvgView *view)
+static void
+lsm_svg_view_pop_mask (LsmSvgView *view)
{
- LsmSvgMaskAttributeBag *mask;
-
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->mask_stack != NULL);
- mask = view->mask_stack->data;
+ if (strncmp (view->style->mask->value, "url(#", 5) == 0) {
+ LsmDomElement *mask_element;
+ char *end;
+ char *uri;
- if (mask->opacity.value < 1.0) {
- cairo_pop_group_to_source (view->dom_view.cairo);
- cairo_paint_with_alpha (view->dom_view.cairo, mask->opacity.value);
- }
-}
+ uri = g_strdup (view->style->mask->value + 5);
+ for (end = uri; *end != '\0' && *end != ')'; end++);
+ *end = '\0';
-void
-lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (mask != NULL);
+ mask_element = lsm_dom_document_get_element_by_id (view->dom_view.document, uri);
- view->mask_stack = g_slist_prepend (view->mask_stack, (void *) mask);
+ if (LSM_IS_SVG_MASK_ELEMENT (mask_element)) {
+ LsmExtents extents;
+ LsmBox mask_extents;
+ cairo_t *cairo;
- if (mask->clip_path.value != NULL)
- lsm_svg_view_push_clip (view, mask->clip_path.value, mask->clip_rule.value);
+ lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
- if (mask->mask.value != NULL)
- cairo_push_group (view->dom_view.cairo);
-}
+ mask_extents.x = extents.x1;
+ mask_extents.y = extents.y1;
+ mask_extents.width = extents.x2 - extents.x1;
+ mask_extents.height = extents.y2 - extents.y1;
-void
-lsm_svg_view_pop_mask_attributes (LsmSvgView *view)
-{
- LsmSvgMaskAttributeBag *mask;
+ cairo = view->dom_view.cairo;
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->mask_stack != NULL);
+ _start_pattern (view, &mask_extents);
- mask = view->mask_stack->data;
+ lsm_svg_element_force_render (LSM_SVG_ELEMENT (mask_element), view);
- if (mask->clip_path.value != NULL)
- lsm_svg_view_pop_clip (view);
+ cairo_pop_group_to_source (cairo);
+ if (view->pattern_data->pattern != NULL) {
+ cairo_surface_t *surface;
+ int width, height, row, i, stride;
+ unsigned char *pixels;
+
+ cairo_pattern_get_surface (view->pattern_data->pattern, &surface);
+ pixels = cairo_image_surface_get_data (surface);
+ height = cairo_image_surface_get_height (surface);
+ width = cairo_image_surface_get_width (surface);
+ stride = cairo_image_surface_get_stride (surface);
- if (mask->mask.value != NULL) {
- if (strncmp (mask->mask.value, "url(#", 5) == 0) {
- LsmDomElement *mask_element;
- char *end;
- char *uri;
-
- uri = g_strdup (mask->mask.value + 5);
- for (end = uri; *end != '\0' && *end != ')'; end++);
- *end = '\0';
-
- mask_element = lsm_dom_document_get_element_by_id (view->dom_view.document, uri);
-
- if (LSM_IS_SVG_MASK_ELEMENT (mask_element)) {
- LsmExtents extents;
- LsmBox mask_extents;
- cairo_t *cairo;
-
- lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
-
- mask_extents.x = extents.x1;
- mask_extents.y = extents.y1;
- mask_extents.width = extents.x2 - extents.x1;
- mask_extents.height = extents.y2 - extents.y1;
-
- cairo = view->dom_view.cairo;
-
- _start_pattern (view, &mask_extents);
-
- lsm_svg_element_render_paint (LSM_SVG_ELEMENT (mask_element), view);
-
- cairo_pop_group_to_source (cairo);
- if (view->pattern_data->pattern != NULL) {
- cairo_surface_t *surface;
- int width, height, row, i, stride;
- unsigned char *pixels;
-
- cairo_pattern_get_surface (view->pattern_data->pattern, &surface);
- pixels = cairo_image_surface_get_data (surface);
- height = cairo_image_surface_get_height (surface);
- width = cairo_image_surface_get_width (surface);
- stride = cairo_image_surface_get_stride (surface);
-
- for (row = 0; row < height; row++) {
- guint8 *row_data = (pixels + (row * stride));
- for (i = 0; i < width; i++) {
- guint32 *pixel = (guint32 *) row_data + i;
- *pixel = ((((*pixel & 0x00ff0000) >> 16) * 13817 +
- ((*pixel & 0x0000ff00) >> 8) * 46518 +
- ((*pixel & 0x000000ff)) * 4688) * 0xff
- /* * opacity */);
- }
+ for (row = 0; row < height; row++) {
+ guint8 *row_data = (pixels + (row * stride));
+ for (i = 0; i < width; i++) {
+ guint32 *pixel = (guint32 *) row_data + i;
+ *pixel = ((((*pixel & 0x00ff0000) >> 16) * 13817 +
+ ((*pixel & 0x0000ff00) >> 8) * 46518 +
+ ((*pixel & 0x000000ff)) * 4688) * 0xff
+ /* * opacity */);
}
+ }
- cairo_pattern_set_matrix (view->pattern_data->pattern,
- &view->pattern_data->matrix);
- cairo_pattern_set_extend (view->pattern_data->pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_matrix (view->pattern_data->pattern,
+ &view->pattern_data->matrix);
+ cairo_pattern_set_extend (view->pattern_data->pattern, CAIRO_EXTEND_NONE);
#if 0
- cairo_surface_write_to_png (surface, "mask.png");
+ cairo_surface_write_to_png (surface, "mask.png");
#endif
- cairo_mask (cairo, view->pattern_data->pattern);
- } else {
- cairo_paint (cairo);
- }
-
- _end_pattern (view);
+ cairo_mask (cairo, view->pattern_data->pattern);
} else {
- cairo_pop_group_to_source (view->dom_view.cairo);
- cairo_paint (view->dom_view.cairo);
+ cairo_paint (cairo);
}
+
+ _end_pattern (view);
} else {
cairo_pop_group_to_source (view->dom_view.cairo);
cairo_paint (view->dom_view.cairo);
}
+ } else {
+ cairo_pop_group_to_source (view->dom_view.cairo);
+ cairo_paint (view->dom_view.cairo);
}
-
- view->mask_stack = g_slist_delete_link (view->mask_stack, view->mask_stack);
}
void
-lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill)
+lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (fill != NULL);
+ g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
- view->fill_stack = g_slist_prepend (view->fill_stack, (void *) fill);
+ view->element_stack = g_slist_prepend (view->element_stack, (void *) element);
}
void
-lsm_svg_view_pop_fill_attributes (LsmSvgView *view)
+lsm_svg_view_pop_element (LsmSvgView *view)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->fill_stack != NULL);
+ g_return_if_fail (view->element_stack != NULL);
- view->fill_stack = g_slist_delete_link (view->fill_stack, view->fill_stack);
+ view->element_stack = g_slist_delete_link (view->element_stack, view->element_stack);
}
void
-lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke)
+lsm_svg_view_push_style (LsmSvgView *view, const LsmSvgStyle *style)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (stroke != NULL);
+ g_return_if_fail (style != NULL);
- view->stroke_stack = g_slist_prepend (view->stroke_stack, (void *) stroke);
-}
+ view->style_stack = g_slist_prepend (view->style_stack, (void *) style);
+ view->style = style;
-void
-lsm_svg_view_pop_stroke_attributes (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->stroke_stack != NULL);
+ if (g_strcmp0 (style->clip_path->value, "none") != 0) {
+ lsm_debug ("[LsmSvgView::push_style] Start clip '%s'", style->clip_path->value);
+ lsm_svg_view_push_clip (view);
+ }
- view->stroke_stack = g_slist_delete_link (view->stroke_stack, view->stroke_stack);
+ if (g_strcmp0 (style->mask->value, "none") != 0) {
+ lsm_debug ("[LsmSvgView::push_style] Start mask '%s'", style->mask->value);
+ lsm_svg_view_push_mask (view);
+ }
}
-void
-lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text)
+void lsm_svg_view_pop_style (LsmSvgView *view)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (text != NULL);
+ g_return_if_fail (view->style_stack != NULL);
+
+ if (g_strcmp0 (view->style->mask->value, "none") != 0)
+ lsm_svg_view_pop_mask (view);
- view->text_stack = g_slist_prepend (view->text_stack, (void *) text);
+ if (g_strcmp0 (view->style->clip_path->value, "none") != 0)
+ lsm_svg_view_pop_clip (view);
+
+ view->style_stack = g_slist_delete_link (view->style_stack, view->style_stack);
+ view->style = view->style_stack != NULL ? view->style_stack->data : NULL;
}
-void
-lsm_svg_view_pop_text_attributes (LsmSvgView *view)
+const LsmSvgStyle *
+lsm_svg_view_get_current_style (LsmSvgView *view)
{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->text_stack != NULL);
+ g_return_val_if_fail (LSM_IS_SVG_VIEW (view), NULL);
- view->text_stack = g_slist_delete_link (view->text_stack, view->text_stack);
+ return view->style;
}
const LsmBox *
@@ -1562,8 +1533,6 @@ lsm_svg_view_measure (LsmDomView *view, double *width, double *height)
if (svg_element == NULL)
return;
- lsm_svg_svg_element_update (svg_element);
-
lsm_svg_svg_element_measure (svg_element, width, height);
}
@@ -1579,14 +1548,9 @@ lsm_svg_view_render (LsmDomView *view)
if (svg_element == NULL)
return;
- lsm_svg_svg_element_update (svg_element);
-
+ svg_view->style_stack = NULL;
svg_view->element_stack = NULL;
svg_view->viewbox_stack = NULL;
- svg_view->mask_stack = NULL;
- svg_view->fill_stack = NULL;
- svg_view->stroke_stack = NULL;
- svg_view->text_stack = NULL;
svg_view->matrix_stack = NULL;
svg_view->is_clipping = FALSE;
@@ -1608,31 +1572,16 @@ lsm_svg_view_render (LsmDomView *view)
g_slist_free (svg_view->viewbox_stack);
svg_view->viewbox_stack = NULL;
}
- if (svg_view->fill_stack != NULL) {
- g_warning ("[LsmSvgView::render] Dangling fill attributes in stack");
- g_slist_free (svg_view->fill_stack);
- svg_view->fill_stack = NULL;
- }
- if (svg_view->stroke_stack != NULL) {
- g_warning ("[LsmSvgView::render] Dangling stroke attributes in stack");
- g_slist_free (svg_view->stroke_stack);
- svg_view->stroke_stack = NULL;
- }
- if (svg_view->mask_stack != NULL) {
- g_warning ("[LsmSvgView::render] Dangling mask attributes in stack");
- g_slist_free (svg_view->mask_stack);
- svg_view->mask_stack = NULL;
- }
- if (svg_view->text_stack != NULL) {
- g_warning ("[LsmSvgView::render] Dangling text attribute in stack");
- g_slist_free (svg_view->text_stack);
- svg_view->text_stack = NULL;
- }
if (svg_view->element_stack != NULL) {
g_warning ("[LsmSvgView::render] Dangling element in stack");
g_slist_free (svg_view->element_stack);
svg_view->element_stack = NULL;
}
+ if (svg_view->style_stack != NULL) {
+ g_warning ("[LsmSvgView::render] Dangling style in stack");
+ g_slist_free (svg_view->style_stack);
+ svg_view->style_stack = NULL;
+ }
}
LsmSvgView *
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index d295ffe..b960b05 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -51,12 +51,11 @@ struct _LsmSvgView {
double resolution_ppi;
+ const LsmSvgStyle *style;
+
+ GSList *style_stack;
GSList *element_stack;
GSList *viewbox_stack;
- GSList *mask_stack;
- GSList *fill_stack;
- GSList *stroke_stack;
- GSList *text_stack;
GSList *matrix_stack;
LsmSvgViewPatternData *pattern_data;
@@ -65,6 +64,8 @@ struct _LsmSvgView {
gboolean is_clipping;
LsmBox clip_extents;
+
+ double last_stop_offset;
};
struct _LsmSvgViewClass {
@@ -85,8 +86,7 @@ void lsm_svg_view_create_radial_gradient (LsmSvgView *view, double cx, double
double r, double fx, double fy);
void lsm_svg_view_create_linear_gradient (LsmSvgView *view, double x1, double y1,
double x2, double y2);
-void lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset,
- const LsmSvgColor *color, double opacity);
+void lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset);
void lsm_svg_view_set_gradient_properties (LsmSvgView *view,
LsmSvgSpreadMethod method,
LsmSvgPatternUnits units,
@@ -116,7 +116,7 @@ void lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport,
const LsmBox *viewbox,
const LsmSvgPreserveAspectRatio *aspect_ratio);
void lsm_svg_view_pop_viewport (LsmSvgView *view);
-void lsm_svg_view_push_matrix (LsmSvgView *view, LsmSvgMatrix *matrix);
+void lsm_svg_view_push_matrix (LsmSvgView *view, const LsmSvgMatrix *matrix);
void lsm_svg_view_pop_matrix (LsmSvgView *view);
void lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element);
@@ -125,14 +125,10 @@ void lsm_svg_view_pop_element (LsmSvgView *view);
void lsm_svg_view_push_group_opacity (LsmSvgView *view);
void lsm_svg_view_pop_group_opacity (LsmSvgView *view);
-void lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask);
-void lsm_svg_view_pop_mask_attributes (LsmSvgView *view);
-void lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill);
-void lsm_svg_view_pop_fill_attributes (LsmSvgView *view);
-void lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke);
-void lsm_svg_view_pop_stroke_attributes (LsmSvgView *view);
-void lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text);
-void lsm_svg_view_pop_text_attributes (LsmSvgView *view);
+void lsm_svg_view_push_style (LsmSvgView *view, const LsmSvgStyle *style);
+void lsm_svg_view_pop_style (LsmSvgView *view);
+
+const LsmSvgStyle * lsm_svg_view_get_current_style (LsmSvgView *view);
G_END_DECLS
diff --git a/test/.gitignore b/test/.gitignore
index d109f53..b4dc037 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -1,3 +1,2 @@
-lasemtest.xml
log
*-out.png
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]