[lasem/wip/emmanuel/extents] wip: svg ruler
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem/wip/emmanuel/extents] wip: svg ruler
- Date: Mon, 11 Jul 2016 13:38:23 +0000 (UTC)
commit b4b12bb92f6fcd0d93008fb90cd8e6274d90eb7b
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Mon Jul 11 15:38:20 2016 +0200
wip: svg ruler
src/Makefile.am | 2 +
src/lsmdebug.c | 6 +
src/lsmdebug.h | 5 +
src/lsmsvg.h | 1 +
src/lsmsvgruler.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++
src/lsmsvgruler.h | 28 ++++++
src/lsmsvgsvgelement.c | 23 +++--
src/lsmsvgview.c | 243 ++++++++++++++++++++----------------------------
src/lsmsvgview.h | 5 +-
9 files changed, 401 insertions(+), 151 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index dbc5c87..9ccdcdd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -103,6 +103,7 @@ LASEM_SVG_SRCS = \
lsmsvglength.c \
lsmsvgview.c \
lsmsvgmatrix.c \
+ lsmsvgruler.c \
lsmsvgdocument.c \
lsmsvgelement.c \
lsmsvgtransformable.c \
@@ -227,6 +228,7 @@ LASEM_SVG_HDRS = \
lsmsvglength.h \
lsmsvgview.h \
lsmsvgmatrix.h \
+ lsmsvgruler.h \
lsmsvgdocument.h \
lsmsvgelement.h \
lsmsvgtransformable.h \
diff --git a/src/lsmdebug.c b/src/lsmdebug.c
index 02adaed..7dda251 100644
--- a/src/lsmdebug.c
+++ b/src/lsmdebug.c
@@ -56,6 +56,12 @@ LsmDebugCategory lsm_debug_category_render =
.level = -1
};
+LsmDebugCategory lsm_debug_category_ruler =
+{
+ .name = (char *) "ruler",
+ .level = -1
+};
+
LsmDebugCategory lsm_debug_category_viewport =
{
.name = (char *) "viewport",
diff --git a/src/lsmdebug.h b/src/lsmdebug.h
index 85f2cfc..fbcfae1 100644
--- a/src/lsmdebug.h
+++ b/src/lsmdebug.h
@@ -42,6 +42,7 @@ extern LsmDebugCategory lsm_debug_category_dom;
extern LsmDebugCategory lsm_debug_category_measure;
extern LsmDebugCategory lsm_debug_category_update;
extern LsmDebugCategory lsm_debug_category_render;
+extern LsmDebugCategory lsm_debug_category_ruler;
extern LsmDebugCategory lsm_debug_category_viewport;
#define lsm_debug_dom(...) lsm_debug (&lsm_debug_category_dom, __VA_ARGS__)
@@ -60,6 +61,10 @@ extern LsmDebugCategory lsm_debug_category_viewport;
#define lsm_log_render(...) lsm_log (&lsm_debug_category_render, __VA_ARGS__)
#define lsm_warning_render(...) lsm_warning (&lsm_debug_category_render, __VA_ARGS__)
+#define lsm_debug_ruler(...) lsm_debug (&lsm_debug_category_ruler, __VA_ARGS__)
+#define lsm_log_ruler(...) lsm_log (&lsm_debug_category_ruler, __VA_ARGS__)
+#define lsm_warning_ruler(...) lsm_warning (&lsm_debug_category_ruler, __VA_ARGS__)
+
void lsm_warning (LsmDebugCategory *category, const char *format, ...)
G_GNUC_PRINTF(2,3);
void lsm_debug (LsmDebugCategory *category, const char *format, ...)
G_GNUC_PRINTF(2,3);
void lsm_log (LsmDebugCategory *category, const char *format, ...)
G_GNUC_PRINTF(2,3);
diff --git a/src/lsmsvg.h b/src/lsmsvg.h
index b08d328..149fc01 100644
--- a/src/lsmsvg.h
+++ b/src/lsmsvg.h
@@ -33,6 +33,7 @@
#include <lsmsvgstyle.h>
#include <lsmsvgcolors.h>
#include <lsmsvglength.h>
+#include <lsmsvgruler.h>
#include <lsmsvgview.h>
#include <lsmsvgmatrix.h>
#include <lsmsvgdocument.h>
diff --git a/src/lsmsvgruler.c b/src/lsmsvgruler.c
new file mode 100644
index 0000000..8a8ace4
--- /dev/null
+++ b/src/lsmsvgruler.c
@@ -0,0 +1,239 @@
+#include <lsmsvgruler.h>
+#include <lsmsvgmatrix.h>
+#include <lsmutils.h>
+
+struct _LsmSvgRuler {
+ double resolution_ppi;
+
+ LsmSvgStyle *style;
+ LsmSvgMatrix *matrix;
+ LsmSvgViewbox *viewbox;
+
+ GSList *style_stack;
+ GSList *matrix_stack;
+ GSList *viewbox_stack;
+
+ volatile gint ref_count;
+};
+
+LsmSvgRuler *
+lsm_svg_ruler_new (double resolution_ppi)
+{
+ LsmSvgRuler *ruler;
+
+ ruler = g_slice_new0 (LsmSvgRuler);
+ ruler->ref_count = 1;
+ ruler->resolution_ppi = resolution_ppi;
+ ruler->style = NULL;
+ ruler->matrix = g_slice_new (LsmSvgMatrix);
+ lsm_svg_matrix_init_identity (ruler->matrix);
+
+ return ruler;
+}
+
+LsmSvgRuler *
+lsm_svg_ruler_ref (LsmSvgRuler *ruler)
+{
+ g_return_val_if_fail (ruler != NULL, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&ruler->ref_count) > 0, ruler);
+ g_atomic_int_inc (&ruler->ref_count);
+
+ return ruler;
+}
+
+static void
+_free_style (gpointer data, gpointer user_data)
+{
+ if (data != NULL)
+ lsm_svg_style_unref (data);
+}
+
+static void
+_free_matrix (gpointer data, gpointer user_data)
+{
+ if (data != NULL)
+ g_slice_free (LsmSvgMatrix, data);
+}
+
+static void
+_free_viewbox (gpointer data, gpointer user_data)
+{
+ if (data != NULL)
+ lsm_svg_viewbox_free (data);
+}
+
+void
+lsm_svg_ruler_unref (LsmSvgRuler *ruler)
+{
+ g_return_if_fail (g_atomic_int_get (&ruler->ref_count) > 0);
+ if (g_atomic_int_dec_and_test (&ruler->ref_count)) {
+ if (ruler->style_stack != NULL) {
+ g_warning ("Dangling style in ruler stack");
+ g_slist_foreach (ruler->style_stack, _free_style, NULL);
+ g_clear_pointer (&ruler->style_stack, g_slist_free);
+ }
+ if (ruler->matrix_stack != NULL) {
+ g_warning ("Dangling matrix in ruler stack");
+ g_slist_foreach (ruler->matrix_stack, _free_matrix, NULL);
+ g_clear_pointer (&ruler->matrix_stack, g_slist_free);
+ }
+ if (ruler->viewbox_stack != NULL) {
+ g_warning ("Dangling viewbow in ruler stack");
+ g_slist_foreach (ruler->viewbox_stack, _free_viewbox, NULL);
+ g_clear_pointer (&ruler->viewbox_stack, g_slist_free);
+ }
+ _free_style (ruler->style, NULL);
+ _free_matrix (ruler->matrix, NULL);
+ _free_viewbox (ruler->viewbox, NULL);
+ g_slice_free (LsmSvgRuler, ruler);
+ }
+}
+
+void
+lsm_svg_ruler_push_style (LsmSvgRuler *ruler, LsmSvgStyle *style)
+{
+ g_return_if_fail (ruler != NULL);
+ g_return_if_fail (style != NULL);
+
+ lsm_log_ruler ("Push style");
+
+ /* FIXME Don't store current font_size_pixel in style */
+ if (ruler->style == NULL || (style->font_size != ruler->style->font_size)) {
+ LsmSvgViewbox font_viewbox;
+ LsmSvgViewbox *viewbox;
+ double current_font_size_px;
+
+ if (ruler->style != NULL)
+ current_font_size_px = ruler->style->font_size_px;
+ else
+ current_font_size_px = 0.0;
+
+ viewbox = ruler->viewbox;
+ font_viewbox.resolution_ppi = viewbox->resolution_ppi;
+ font_viewbox.viewbox.x = 0;
+ font_viewbox.viewbox.y = 0;
+ font_viewbox.viewbox.width = current_font_size_px;
+ font_viewbox.viewbox.height = current_font_size_px;
+
+ style->font_size_px = lsm_svg_length_normalize (&style->font_size->length, &font_viewbox,
+ current_font_size_px,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+ if (style->font_size_px < 0.0)
+ style->font_size_px = 0.0;
+ lsm_log_ruler ("Font size = %g pixels", style->font_size_px);
+ } else
+ style->font_size_px = ruler->style->font_size_px;
+
+ ruler->style_stack = g_slist_prepend (ruler->style_stack, ruler->style);
+ ruler->style = lsm_svg_style_ref (style);
+}
+
+void
+lsm_svg_ruler_pop_style (LsmSvgRuler *ruler)
+{
+ g_return_if_fail (ruler != NULL);
+ g_return_if_fail (ruler->style_stack != NULL);
+
+ lsm_log_ruler ("Pop style");
+
+ lsm_svg_style_unref (ruler->style);
+ ruler->style = ruler->style_stack->data;
+ ruler->style_stack = g_slist_delete_link (ruler->style_stack, ruler->style_stack);
+}
+
+LsmSvgStyle *
+lsm_svg_ruler_get_style (LsmSvgRuler *ruler)
+{
+ g_return_val_if_fail (ruler != NULL, NULL);
+
+ return ruler->style;
+}
+
+gboolean
+lsm_svg_ruler_push_matrix (LsmSvgRuler *ruler, const LsmSvgMatrix *matrix)
+{
+ gboolean is_invertible;
+
+ g_return_val_if_fail (ruler != NULL, FALSE);
+ g_return_val_if_fail (matrix != NULL, FALSE);
+
+ ruler->matrix_stack = g_slist_prepend (ruler->matrix_stack, ruler->matrix);
+ ruler->matrix = g_slice_new (LsmSvgMatrix);
+
+ is_invertible = lsm_svg_matrix_is_invertible (matrix);
+ if (is_invertible)
+ lsm_svg_matrix_multiply (ruler->matrix, ruler->matrix, matrix);
+ else
+ lsm_svg_matrix_init (ruler->matrix, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+ return is_invertible;
+}
+
+void
+lsm_svg_ruler_pop_matrix (LsmSvgRuler *ruler)
+{
+ g_return_if_fail (ruler != NULL);
+ g_return_if_fail (ruler->matrix_stack != NULL);
+
+ g_slice_free (LsmSvgMatrix, ruler->matrix);
+ ruler->matrix = ruler->matrix_stack->data;
+ ruler->matrix_stack = g_slist_delete_link (ruler->matrix_stack, ruler->matrix_stack);
+}
+
+void
+lsm_svg_ruler_push_viewbox (LsmSvgRuler *ruler, const LsmBox *viewbox)
+{
+ g_return_if_fail (ruler != NULL);
+ g_return_if_fail (viewbox != NULL);
+
+ lsm_debug_ruler ("Push viewbox = %g, %g, %g, %g",
+ viewbox->x, viewbox->y, viewbox->width, viewbox->height);
+
+ ruler->viewbox_stack = g_slist_prepend (ruler->viewbox_stack, ruler->viewbox);
+ ruler->viewbox = lsm_svg_viewbox_new (ruler->resolution_ppi, viewbox);
+}
+
+void
+lsm_svg_ruler_pop_viewbox (LsmSvgRuler *ruler)
+{
+ g_return_if_fail (ruler != NULL);
+ g_return_if_fail (ruler->viewbox_stack != NULL);
+
+ lsm_debug_ruler ("Pop viewbox");
+
+ lsm_svg_viewbox_free (ruler->viewbox);
+ ruler->viewbox = ruler->viewbox_stack->data;
+ ruler->viewbox_stack = g_slist_delete_link (ruler->viewbox_stack, ruler->viewbox_stack);
+}
+
+double
+lsm_svg_ruler_normalize_length (LsmSvgRuler *ruler, const LsmSvgLength *length, LsmSvgLengthDirection
direction)
+{
+ g_return_val_if_fail (ruler != NULL, 0.0);
+
+ return lsm_svg_length_normalize (length, ruler->viewbox, ruler->style->font_size_px, direction);
+}
+
+double *
+lsm_svg_ruler_normalize_length_list (LsmSvgRuler *ruler, const LsmSvgLengthList *list,
+ LsmSvgLengthDirection direction, unsigned int *n_data)
+{
+ double *data;
+ unsigned int i;
+
+ g_return_val_if_fail (n_data != NULL, NULL);
+ *n_data = 0;
+ g_return_val_if_fail (ruler != NULL, NULL);
+ g_return_val_if_fail (list != NULL, NULL);
+
+ if (list->n_lengths == 0)
+ return NULL;
+
+ *n_data = list->n_lengths;
+ data = g_new (double, list->n_lengths);
+ for (i = 0; i < list->n_lengths; i++)
+ data[i] = lsm_svg_ruler_normalize_length (ruler, &list->lengths[i], direction);
+
+ return data;
+}
+
diff --git a/src/lsmsvgruler.h b/src/lsmsvgruler.h
new file mode 100644
index 0000000..7229c13
--- /dev/null
+++ b/src/lsmsvgruler.h
@@ -0,0 +1,28 @@
+#include <lsmsvgstyle.h>
+
+#ifndef LSM_SVG_RULER
+#define LSM_SVG_RULER
+
+typedef struct _LsmSvgRuler LsmSvgRuler;
+
+LsmSvgRuler * lsm_svg_ruler_new (double resolution_ppi);
+double lsm_svg_ruler_get_resolution_ppi (LsmSvgRuler *ruler);
+
+LsmSvgRuler * lsm_svg_ruler_ref (LsmSvgRuler *ruler);
+void lsm_svg_ruler_unref (LsmSvgRuler *ruler);
+void lsm_svg_ruler_push_style (LsmSvgRuler *ruler, LsmSvgStyle *style);
+void lsm_svg_ruler_pop_style (LsmSvgRuler *ruler);
+LsmSvgStyle * lsm_svg_ruler_get_style (LsmSvgRuler *ruler);
+gboolean lsm_svg_ruler_push_matrix (LsmSvgRuler *ruler, const LsmSvgMatrix
*matrix);
+void lsm_svg_ruler_pop_matrix (LsmSvgRuler *ruler);
+const LsmSvgMatrix * lsm_svg_ruler_get_matrix (LsmSvgRuler *ruler);
+void lsm_svg_ruler_push_viewbox (LsmSvgRuler *ruler, const LsmBox *viewbox);
+void lsm_svg_ruler_pop_viewbox (LsmSvgRuler *ruler);
+const LsmSvgViewbox * lsm_svg_ruler_get_viewbox (LsmSvgRuler *ruler);
+
+double lsm_svg_ruler_normalize_length (LsmSvgRuler *ruler, const
LsmSvgLength *length,
+ LsmSvgLengthDirection direction);
+double * lsm_svg_ruler_normalize_length_list (LsmSvgRuler *ruler, const LsmSvgLengthList
*list,
+ LsmSvgLengthDirection direction, unsigned
int *n_data);
+
+#endif
diff --git a/src/lsmsvgsvgelement.c b/src/lsmsvgsvgelement.c
index 29597a5..257c79d 100644
--- a/src/lsmsvgsvgelement.c
+++ b/src/lsmsvgsvgelement.c
@@ -47,6 +47,7 @@ lsm_svg_svg_element_measure (LsmSvgSvgElement *self, LsmSvgView *view, LsmDomVie
{
LsmSvgViewbox *svg_viewbox;
LsmBox viewport;
+ LsmExtents extents = {0.0, 0.0, 0.0, 0.0};
gboolean is_outermost_svg;
double resolution_ppi;
double svg_x;
@@ -99,14 +100,22 @@ lsm_svg_svg_element_measure (LsmSvgSvgElement *self, LsmSvgView *view, LsmDomVie
self->svg_box.width = svg_width;
self->svg_box.height = svg_height;
- lsm_debug_measure ("[LsmSvgSvgElement::measure] Size = %g, %g, %g, %g",
- svg_x, svg_y, svg_width, svg_height);
- lsm_svg_viewbox_free (svg_viewbox);
+ switch (measurement) {
+ case LSM_DOM_VIEW_MEASUREMENT_VIEWPORT:
+ lsm_debug_measure ("[LsmSvgSvgElement::measure] Size = %g, %g, %g, %g",
+ svg_x, svg_y, svg_width, svg_height);
+
+ if (x != NULL)
+ *x = 0.0;
+ if (y != NULL)
+ *y = 0.0;
+ break;
+ case LSM_DOM_VIEW_MEASUREMENT_EXTENTS:
+ lsm_svg_element_get_extents (LSM_SVG_ELEMENT (self), view, &extents);
+ break;
+ }
- if (x != NULL)
- *x = 0.0;
- if (y != NULL)
- *y = 0.0;
+ lsm_svg_viewbox_free (svg_viewbox);
}
/* LsmSvgGraphic implementation */
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index ab6d22e..4777310 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -117,29 +117,16 @@ double
lsm_svg_view_normalize_length (LsmSvgView *view, const LsmSvgLength *length, LsmSvgLengthDirection direction)
{
g_return_val_if_fail (LSM_IS_SVG_VIEW (view), 0.0);
-
- return lsm_svg_length_normalize (length, view->viewbox_stack->data, view->style->font_size_px,
direction);
+
+ return lsm_svg_ruler_normalize_length (view->ruler, length, direction);
}
double *
lsm_svg_view_normalize_length_list (LsmSvgView *view, const LsmSvgLengthList *list, LsmSvgLengthDirection
direction, unsigned int *n_data)
{
- double *data;
- unsigned int i;
-
- g_return_val_if_fail (n_data != NULL, NULL);
- *n_data = 0;
g_return_val_if_fail (LSM_IS_SVG_VIEW (view), NULL);
- if (list->n_lengths == 0)
- return NULL;
-
- *n_data = list->n_lengths;
- data = g_new (double, list->n_lengths);
- for (i = 0; i < list->n_lengths; i++)
- data[i] = lsm_svg_view_normalize_length (view, &list->lengths[i], direction);
-
- return data;
+ return lsm_svg_ruler_normalize_length_list (view->ruler, list, direction, n_data);
}
static void
@@ -231,7 +218,7 @@ lsm_svg_view_add_gradient_color_stop (LsmSvgView *view, double offset)
else
view->last_stop_offset = offset;
- style = view->style;
+ style = lsm_svg_ruler_get_style (view->ruler);
lsm_debug_render ("[LsmSvgView::add_gradient_color_stop] opacity = %g", style->stop_opacity->value);
@@ -499,6 +486,7 @@ _set_color (LsmSvgView *view,
const LsmSvgPaint *paint, double opacity)
{
cairo_t *cairo = view->dom_view.cairo;
+ LsmSvgStyle *style;
switch (paint->type) {
case LSM_SVG_PAINT_TYPE_NONE:
@@ -511,10 +499,11 @@ _set_color (LsmSvgView *view,
opacity);
break;
case LSM_SVG_PAINT_TYPE_CURRENT_COLOR:
+ style = lsm_svg_ruler_get_style (view->ruler);
cairo_set_source_rgba (cairo,
- view->style->color->value.red,
- view->style->color->value.green,
- view->style->color->value.blue,
+ style->color->value.red,
+ style->color->value.green,
+ style->color->value.blue,
opacity);
break;
case LSM_SVG_PAINT_TYPE_URI:
@@ -552,7 +541,7 @@ paint_markers (LsmSvgView *view)
double angle;
int i;
- style = view->style;
+ style = lsm_svg_ruler_get_style (view->ruler);
if ((style->marker->value == NULL || strcmp (style->marker->value, "none") == 0) &&
(style->marker_mid->value == NULL || strcmp (style->marker_mid->value, "none") == 0) &&
@@ -570,8 +559,8 @@ paint_markers (LsmSvgView *view)
style->marker_mid->value);
marker_end = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
style->marker_end->value);
- stroke_width = lsm_svg_view_normalize_length (view, &view->style->stroke_width->length,
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ stroke_width = lsm_svg_ruler_normalize_length (view->ruler, &style->stroke_width->length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
if (marker != NULL && lsm_svg_view_circular_reference_check (view, marker))
return;
@@ -728,7 +717,7 @@ paint (LsmSvgView *view, LsmSvgViewPathInfos *path_infos)
g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
cairo = view->dom_view.cairo;
- style = view->style;
+ style = lsm_svg_ruler_get_style (view->ruler);
if ((style->opacity != NULL ||
style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER ) &&
@@ -802,8 +791,8 @@ paint (LsmSvgView *view, LsmSvgViewPathInfos *path_infos)
cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE);
}
- line_width = lsm_svg_view_normalize_length (view, &style->stroke_width->length,
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ line_width = lsm_svg_ruler_normalize_length (view->ruler, &style->stroke_width->length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
cairo_set_miter_limit (cairo, style->stroke_miter_limit->value);
cairo_set_line_width (cairo, line_width);
@@ -813,13 +802,13 @@ paint (LsmSvgView *view, LsmSvgViewPathInfos *path_infos)
double *dashes;
unsigned int i;
- dash_offset = lsm_svg_view_normalize_length (view, &style->stroke_dash_offset->length,
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ dash_offset = lsm_svg_ruler_normalize_length (view->ruler,
&style->stroke_dash_offset->length,
+ LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
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,
-
&style->stroke_dash_array->value.dashes[i],
- LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+ dashes[i] = lsm_svg_ruler_normalize_length (view->ruler,
+
&style->stroke_dash_array->value.dashes[i],
+
LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
cairo_set_dash (cairo, dashes, style->stroke_dash_array->value.n_dashes, dash_offset);
g_free (dashes);
@@ -840,19 +829,23 @@ paint (LsmSvgView *view, LsmSvgViewPathInfos *path_infos)
cairo_paint_with_alpha (cairo, group_opacity);
}
- if (view->style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER)
+ if (style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER)
lsm_cairo_set_comp_op (cairo, LSM_SVG_COMP_OP_SRC_OVER);
}
static void
process_path (LsmSvgView *view, LsmSvgViewPathInfos *path_infos)
{
- g_return_if_fail (view->style != NULL);
+ LsmSvgStyle *style;
+
+ style = lsm_svg_ruler_get_style (view->ruler);
+
+ g_return_if_fail (style != NULL);
if (view->is_clipping) {
if (path_infos->is_text_path)
pango_cairo_layout_path (view->dom_view.cairo, path_infos->pango_layout);
- cairo_set_fill_rule (view->dom_view.cairo, view->style->clip_rule->value);
+ cairo_set_fill_rule (view->dom_view.cairo, style->clip_rule->value);
} else
paint (view, path_infos);
}
@@ -861,11 +854,14 @@ void
lsm_svg_view_show_viewport (LsmSvgView*view, const LsmBox *viewport)
{
LsmSvgPaint *paint;
+ LsmSvgStyle *style;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
g_return_if_fail (viewport != NULL);
+
+ style = lsm_svg_ruler_get_style (view->ruler);
- paint = &view->style->viewport_fill->paint;
+ paint = &style->viewport_fill->paint;
switch (paint->type) {
case LSM_SVG_PAINT_TYPE_RGB_COLOR:
@@ -873,14 +869,14 @@ lsm_svg_view_show_viewport (LsmSvgView*view, const LsmBox *viewport)
paint->color.red,
paint->color.green,
paint->color.blue,
- view->style->viewport_fill_opacity->value);
+ style->viewport_fill_opacity->value);
break;
case LSM_SVG_PAINT_TYPE_CURRENT_COLOR:
cairo_set_source_rgba (view->dom_view.cairo,
- view->style->color->value.red,
- view->style->color->value.green,
- view->style->color->value.blue,
- view->style->viewport_fill_opacity->value);
+ style->color->value.red,
+ style->color->value.green,
+ style->color->value.blue,
+ style->viewport_fill_opacity->value);
default:
return;
}
@@ -1089,7 +1085,7 @@ _update_pango_layout (LsmSvgView *view, unsigned int n, char const *string, doub
int i;
double x1, y1;
- style = view->style;
+ style = lsm_svg_ruler_get_style (view->ruler);
pango_layout = view->pango_layout;
font_description = view->dom_view.font_description;
@@ -1267,7 +1263,7 @@ _show_text (LsmSvgView *view,
cairo = view->dom_view.cairo;
- style = view->style;
+ style = lsm_svg_ruler_get_style (view->ruler);
lsm_debug_render ("[LsmSvgView::show_text] Show '%s' at %g,%g (%g px)", string,
x != NULL ? *x : 0, y != NULL ? *y : 0, style->font_size_px);
@@ -1448,28 +1444,17 @@ lsm_svg_view_show_pixbuf (LsmSvgView *view, GdkPixbuf *pixbuf)
void
lsm_svg_view_push_viewbox (LsmSvgView *view, const LsmBox *viewbox)
{
- LsmSvgViewbox *svg_viewbox;
-
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- lsm_debug_render ("[LsmSvgView::push_viewbox] viewbox = %g, %g, %g, %g",
- viewbox->x, viewbox->y, viewbox->width, viewbox->height);
-
- svg_viewbox = lsm_svg_viewbox_new (view->resolution_ppi, viewbox);
-
- view->viewbox_stack = g_slist_prepend (view->viewbox_stack, svg_viewbox);
+ lsm_svg_ruler_push_viewbox (view->ruler, viewbox);
}
void
lsm_svg_view_pop_viewbox (LsmSvgView *view)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->viewbox_stack != NULL);
-
- lsm_debug_render ("[LsmSvgView::pop_viewbox]");
- lsm_svg_viewbox_free (view->viewbox_stack->data);
- view->viewbox_stack = g_slist_delete_link (view->viewbox_stack, view->viewbox_stack);
+ lsm_svg_ruler_pop_viewbox (view->ruler);
}
static const LsmBox *
@@ -1662,6 +1647,8 @@ lsm_svg_view_push_matrix (LsmSvgView *view, const LsmSvgMatrix *matrix)
current_ctm.x0, current_ctm.y0);
}
+ lsm_svg_ruler_push_matrix (view->ruler, matrix);
+
return TRUE;
}
@@ -1670,6 +1657,8 @@ lsm_svg_view_pop_matrix (LsmSvgView *view)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ lsm_svg_ruler_pop_matrix (view->ruler);
+
if (view->matrix_stack != NULL) {
cairo_matrix_t *ctm;
@@ -1691,6 +1680,7 @@ lsm_svg_view_push_clip (LsmSvgView *view)
{
LsmSvgElement *element;
LsmExtents extents;
+ LsmSvgStyle *style;
char *url;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
@@ -1698,7 +1688,8 @@ lsm_svg_view_push_clip (LsmSvgView *view)
lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
- url = view->style->clip_path->value;
+ style = lsm_svg_ruler_get_style (view->ruler);
+ url = style->clip_path->value;
lsm_debug_render ("[LsmSvgView::push_clip] Using '%s'", url);
@@ -1723,7 +1714,7 @@ lsm_svg_view_push_clip (LsmSvgView *view)
cairo_clip (view->dom_view.cairo);
view->is_clipping = FALSE;
} else
- lsm_warning_render ("[LsmSvgView::push_clip] Clip path not found: %s",
view->style->clip_path->value);
+ lsm_warning_render ("[LsmSvgView::push_clip] Clip path not found: %s",
style->clip_path->value);
}
static void
@@ -1746,11 +1737,13 @@ static void
lsm_svg_view_pop_mask (LsmSvgView *view)
{
LsmSvgElement *mask_element;
+ LsmSvgStyle *style;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ style = lsm_svg_ruler_get_style (view->ruler);
mask_element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
- view->style->mask->value);
+ style->mask->value);
if (LSM_IS_SVG_MASK_ELEMENT (mask_element) &&
!lsm_svg_view_circular_reference_check (view, mask_element)) {
@@ -1801,7 +1794,7 @@ lsm_svg_view_pop_mask (LsmSvgView *view)
if (view->debug_mask && view->dom_view.cairo != NULL) {
char *filename;
- filename = g_strdup_printf ("mask-%s.png", view->style->mask->value);
+ filename = g_strdup_printf ("mask-%s.png", style->mask->value);
cairo_surface_write_to_png (cairo_get_target (view->dom_view.cairo),
filename);
g_free (filename);
}
@@ -1813,7 +1806,7 @@ lsm_svg_view_pop_mask (LsmSvgView *view)
_end_pattern (view);
} else {
- lsm_warning_render ("[LsmSvgView::pop_mask] Mask url nout found: %s",
view->style->mask->value);
+ lsm_warning_render ("[LsmSvgView::pop_mask] Mask url nout found: %s", style->mask->value);
cairo_pop_group_to_source (view->dom_view.cairo);
cairo_paint (view->dom_view.cairo);
@@ -1827,11 +1820,13 @@ lsm_svg_view_push_filter (LsmSvgView *view)
LsmBox object_extents;
LsmBox effect_viewport;
LsmSvgElement *filter_element;
+ LsmSvgStyle *style;
gboolean success;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
g_return_if_fail (view->element_stack != NULL);
+ style = lsm_svg_ruler_get_style (view->ruler);
lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
object_extents.x = extents.x1;
@@ -1840,21 +1835,21 @@ lsm_svg_view_push_filter (LsmSvgView *view)
object_extents.height = extents.y2 - extents.y1;
filter_element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
- view->style->filter->value);
+ style->filter->value);
if (LSM_IS_SVG_FILTER_ELEMENT (filter_element)) {
effect_viewport = lsm_svg_filter_element_get_effect_viewport (LSM_SVG_FILTER_ELEMENT
(filter_element),
&object_extents, view);
_start_pattern (view, &effect_viewport, &object_extents,
- view->style->opacity != NULL ? view->style->opacity->value : 1.0);
+ style->opacity != NULL ? style->opacity->value : 1.0);
success = lsm_svg_view_create_surface_pattern (view,
&effect_viewport,
NULL,
LSM_SVG_VIEW_SURFACE_TYPE_IMAGE);
} else {
- lsm_warning_render ("LsmSvgView::push_filter] Filter not found: %s",
view->style->filter->value);
+ lsm_warning_render ("LsmSvgView::push_filter] Filter not found: %s", style->filter->value);
_start_pattern (view, &object_extents, &object_extents, 0.0);
@@ -1873,13 +1868,15 @@ lsm_svg_view_pop_filter (LsmSvgView *view)
{
LsmSvgElement *filter_element;
LsmSvgFilterSurface *filter_surface;
+ LsmSvgStyle *style;
cairo_surface_t *surface;
GSList *iter;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ style = lsm_svg_ruler_get_style (view->ruler);
filter_element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
- view->style->filter->value);
+ style->filter->value);
if (LSM_IS_SVG_FILTER_ELEMENT (filter_element) &&
view->pattern_data->pattern != NULL) {
@@ -1910,7 +1907,7 @@ lsm_svg_view_pop_filter (LsmSvgView *view)
LsmSvgFilterSurface *surface = iter->data;
filename = g_strdup_printf ("filter-%04d-%s-%s.png", count++,
- view->style->filter->value,
+ style->filter->value,
lsm_svg_filter_surface_get_name (surface));
cairo_surface_write_to_png (lsm_svg_filter_surface_get_cairo_surface
(surface), filename);
g_free (filename);
@@ -1927,7 +1924,7 @@ lsm_svg_view_pop_filter (LsmSvgView *view)
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (view->pattern_data->old_cairo, pattern);
cairo_pattern_destroy (pattern);
- cairo_paint_with_alpha (view->pattern_data->old_cairo,
view->style->opacity->value);
+ cairo_paint_with_alpha (view->pattern_data->old_cairo, style->opacity->value);
}
for (iter = view->filter_surfaces; iter != NULL; iter = iter->next)
@@ -2096,6 +2093,7 @@ lsm_svg_view_apply_flood (LsmSvgView *view, const char *output, const LsmBox *su
{
LsmSvgFilterSurface *output_surface;
LsmSvgFilterSurface *input_surface;
+ LsmSvgStyle *style;
LsmBox subregion_px;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
@@ -2109,11 +2107,12 @@ lsm_svg_view_apply_flood (LsmSvgView *view, const char *output, const LsmBox *su
subregion_px.width, subregion_px.height,
subregion_px.x, subregion_px.y);
+ style = lsm_svg_ruler_get_style (view->ruler);
lsm_svg_filter_surface_flood (output_surface,
- view->style->flood_color->value.red,
- view->style->flood_color->value.green,
- view->style->flood_color->value.blue,
- view->style->flood_opacity->value);
+ style->flood_color->value.red,
+ style->flood_color->value.green,
+ style->flood_color->value.blue,
+ style->flood_opacity->value);
}
void
@@ -2462,37 +2461,14 @@ lsm_svg_view_push_style (LsmSvgView *view, LsmSvgStyle *style)
g_return_if_fail (LSM_IS_SVG_VIEW (view));
g_return_if_fail (style != NULL);
- lsm_log_render ("[SvgView::push_style]");
-
- if (view->style == NULL || (style->font_size != view->style->font_size)) {
- LsmSvgViewbox font_viewbox;
- LsmSvgViewbox *viewbox;
- double current_font_size_px;
-
- if (view->style != NULL)
- current_font_size_px = view->style->font_size_px;
- else
- current_font_size_px = 0.0;
-
- viewbox = view->viewbox_stack->data;
- font_viewbox.resolution_ppi = viewbox->resolution_ppi;
- font_viewbox.viewbox.x = 0;
- font_viewbox.viewbox.y = 0;
- font_viewbox.viewbox.width = current_font_size_px;
- font_viewbox.viewbox.height = current_font_size_px;
-
- style->font_size_px = lsm_svg_length_normalize (&style->font_size->length, &font_viewbox,
- current_font_size_px,
LSM_SVG_LENGTH_DIRECTION_VERTICAL);
-
- if (style->font_size_px < 0.0)
- style->font_size_px = 0.0;
- lsm_log_render ("[SvgView::push_style] Font size = %g pixels", style->font_size_px);
- } else
- style->font_size_px = view->style->font_size_px;
+ lsm_svg_ruler_push_style (view->ruler, style);
+}
- view->style_stack = g_slist_prepend (view->style_stack, (void *) style);
- view->style = style;
+void lsm_svg_view_pop_style (LsmSvgView *view)
+{
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ lsm_svg_ruler_pop_style (view->ruler);
}
void
@@ -2513,12 +2489,12 @@ lsm_svg_view_push_composition (LsmSvgView *view, LsmSvgStyle *style)
do_mask = (g_strcmp0 (style->mask->value, "none") != 0);
do_filter = (g_strcmp0 (style->filter->value, "none") != 0);
- if (G_UNLIKELY((view->style->opacity->value < 1.0 ||
- view->style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW ||
- view->style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER) &&
+ if (G_UNLIKELY((style->opacity->value < 1.0 ||
+ style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW ||
+ style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER) &&
!do_filter &&
!view->is_clipping &&
- !view->style->ignore_group_opacity &&
+ !style->ignore_group_opacity &&
view->dom_view.cairo != NULL)) {
LsmSvgViewBackground *background;
@@ -2527,8 +2503,8 @@ lsm_svg_view_push_composition (LsmSvgView *view, LsmSvgStyle *style)
background = g_slice_new (LsmSvgViewBackground);
background->surface = cairo_get_group_target (view->dom_view.cairo);
- background->group_opacity = view->style->opacity->value;
- background->enable_background = view->style->enable_background->value ==
LSM_SVG_ENABLE_BACKGROUND_NEW;
+ background->group_opacity = style->opacity->value;
+ background->enable_background = style->enable_background->value ==
LSM_SVG_ENABLE_BACKGROUND_NEW;
view->background_stack = g_list_prepend (view->background_stack, background);
}
@@ -2552,32 +2528,25 @@ lsm_svg_view_push_composition (LsmSvgView *view, LsmSvgStyle *style)
}
}
-void lsm_svg_view_pop_style (LsmSvgView *view)
-{
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->style_stack != NULL);
-
- view->style_stack = g_slist_delete_link (view->style_stack, view->style_stack);
- view->style = view->style_stack != NULL ? view->style_stack->data : NULL;
-
- lsm_log_render ("[SvgView::pop_style]");
-}
-
void lsm_svg_view_pop_composition (LsmSvgView *view)
{
+ LsmSvgStyle *style;
gboolean do_filter;
gboolean do_mask;
gboolean do_clip;
cairo_t *cairo;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- g_return_if_fail (view->style != NULL);
+ g_return_if_fail (view->ruler != NULL);
+
+ style = lsm_svg_ruler_get_style (view->ruler);
+ g_return_if_fail (style != NULL);
lsm_log_render ("[SvgView::pop_composition]");
- do_clip = (g_strcmp0 (view->style->clip_path->value, "none") != 0);
- do_mask = (g_strcmp0 (view->style->mask->value, "none") != 0);
- do_filter = (g_strcmp0 (view->style->filter->value, "none") != 0);
+ do_clip = (g_strcmp0 (style->clip_path->value, "none") != 0);
+ do_mask = (g_strcmp0 (style->mask->value, "none") != 0);
+ do_filter = (g_strcmp0 (style->filter->value, "none") != 0);
/* Don't do filtering during a clipping operation, as filter will
* create a new subsurface, where clipping should occur with the path
@@ -2593,21 +2562,21 @@ void lsm_svg_view_pop_composition (LsmSvgView *view)
cairo = view->dom_view.cairo;
- if (G_UNLIKELY ((view->style->opacity->value < 1.0 ||
- view->style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW ||
- view->style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER) &&
+ if (G_UNLIKELY ((style->opacity->value < 1.0 ||
+ style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW ||
+ style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER) &&
!do_filter &&
!view->is_clipping &&
- !view->style->ignore_group_opacity &&
+ !style->ignore_group_opacity &&
cairo != NULL)) {
g_slice_free (LsmSvgViewBackground, view->background_stack->data);
view->background_stack = g_list_delete_link (view->background_stack, view->background_stack);
cairo_pop_group_to_source (view->dom_view.cairo);
- if (G_UNLIKELY (view->style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER))
- lsm_cairo_set_comp_op (cairo, view->style->comp_op->value);
- cairo_paint_with_alpha (cairo, view->style->opacity->value);
- if (G_UNLIKELY (view->style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER))
+ if (G_UNLIKELY (style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER))
+ lsm_cairo_set_comp_op (cairo, style->comp_op->value);
+ cairo_paint_with_alpha (cairo, style->opacity->value);
+ if (G_UNLIKELY (style->comp_op->value != LSM_SVG_COMP_OP_SRC_OVER))
lsm_cairo_set_comp_op (cairo, LSM_SVG_COMP_OP_SRC_OVER);
lsm_debug_render ("[LsmSvgView::pop_composition] Pop group");
}
@@ -2620,7 +2589,7 @@ lsm_svg_view_get_current_style (LsmSvgView *view)
{
g_return_val_if_fail (LSM_IS_SVG_VIEW (view), NULL);
- return (LsmSvgStyle *) view->style;
+ return lsm_svg_ruler_get_style (view->ruler);
}
const LsmBox *
@@ -2683,9 +2652,9 @@ lsm_svg_view_render (LsmDomView *view)
if (svg_element == NULL)
return;
- svg_view->style_stack = NULL;
+ svg_view->ruler = lsm_svg_ruler_new (view->resolution_ppi);
+
svg_view->element_stack = NULL;
- svg_view->viewbox_stack = NULL;
svg_view->matrix_stack = NULL;
svg_view->pango_layout_stack = NULL;
svg_view->background_stack = NULL;
@@ -2715,26 +2684,18 @@ lsm_svg_view_render (LsmDomView *view)
g_slist_free (svg_view->matrix_stack);
svg_view->matrix_stack = NULL;
}
- if (svg_view->viewbox_stack != NULL) {
- g_warning ("[LsmSvgView::render] Dangling viewport in stack");
- g_slist_free (svg_view->viewbox_stack);
- svg_view->viewbox_stack = NULL;
- }
if (svg_view->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;
- }
if (svg_view->background_stack != NULL) {
g_warning ("[LsmSvgView::render] Dangling background in stack");
g_list_free (svg_view->background_stack);
svg_view->background_stack = NULL;
}
+
+ g_clear_pointer (&svg_view->ruler, lsm_svg_ruler_unref);
}
static void
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index 92ed6c6..87fa77f 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -26,6 +26,7 @@
#include <lsmdom.h>
#include <lsmsvgtypes.h>
+#include <lsmsvgruler.h>
#include <lsmsvgelement.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -53,11 +54,9 @@ struct _LsmSvgView {
double resolution_ppi;
- const LsmSvgStyle *style;
+ LsmSvgRuler *ruler;
- GSList *style_stack;
GSList *element_stack;
- GSList *viewbox_stack;
GSList *matrix_stack;
GSList *pango_layout_stack;
GList *background_stack;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]