[lasem] svg_text: lame text extents support.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg_text: lame text extents support.
- Date: Mon, 22 Oct 2012 21:46:23 +0000 (UTC)
commit 06d821a7c2c145fbe08fd6bdfb4639fa3e5c6348
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Mon Oct 22 23:45:58 2012 +0200
svg_text: lame text extents support.
src/lsmsvgpathelement.c | 4 +-
src/lsmsvgtextelement.c | 15 +++-
src/lsmsvgview.c | 161 +++++++++++++++++++++++++++++++----------------
src/lsmsvgview.h | 5 +-
4 files changed, 120 insertions(+), 65 deletions(-)
---
diff --git a/src/lsmsvgpathelement.c b/src/lsmsvgpathelement.c
index 4643507..3f59a88 100644
--- a/src/lsmsvgpathelement.c
+++ b/src/lsmsvgpathelement.c
@@ -52,9 +52,7 @@ lsm_svg_path_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExte
{
LsmSvgPathElement *path = LSM_SVG_PATH_ELEMENT (self);
- lsm_svg_view_calculate_path_extents (view, path->d.value,
- &extents->x1, &extents->y1,
- &extents->x2, &extents->y2);
+ lsm_svg_view_path_extents (view, path->d.value, extents);
}
/* LsmSvgPathElement implementation */
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index 1ec0efc..bb647ce 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -80,15 +80,22 @@ static void
lsm_svg_text_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExtents *extents)
{
LsmSvgTextElement *text = LSM_SVG_TEXT_ELEMENT (self);
+ LsmDomNode *iter;
+ GString *string = g_string_new ("");
double x, y;
+ for (iter = LSM_DOM_NODE (self)->first_child; iter != NULL; iter = iter->next_sibling) {
+ if (LSM_IS_DOM_TEXT (iter)) {
+ g_string_append (string, lsm_dom_node_get_node_value (iter));
+ }
+ }
+
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);
- extents->x1 = x;
- extents->y1 = y;
- extents->x2 = x;
- extents->y2 = y;
+ lsm_svg_view_text_extents (view, g_strstrip (string->str), x, y, extents);
+
+ g_string_free (string, TRUE);
}
/* LsmSvgTextElement implementation */
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 623dbba..0cbb475 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -873,28 +873,24 @@ lsm_svg_view_show_path (LsmSvgView *view,
}
void
-lsm_svg_view_calculate_path_extents (LsmSvgView *view,
- const char *path,
- double *x1, double *y1,
- double *x2, double *y2)
+lsm_svg_view_path_extents (LsmSvgView *view,
+ const char *path,
+ LsmExtents *extents)
{
- double xx1, yy1, xx2, yy2;
+ double x1, y1, x2, y2;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (extents != NULL);
cairo_new_path (view->dom_view.cairo);
lsm_cairo_emit_svg_path (view->dom_view.cairo, path);
- cairo_path_extents (view->dom_view.cairo, &xx1, &yy1, &xx2, &yy2);
+ cairo_path_extents (view->dom_view.cairo, &x1, &y1, &x2, &y2);
cairo_new_path (view->dom_view.cairo);
- if (x1 != NULL)
- *x1 = xx1;
- if (y1 != NULL)
- *y1 = yy1;
- if (x2 != NULL)
- *x2 = xx2;
- if (y2 != NULL)
- *y2 = yy2;
+ extents->x1 = x1;
+ extents->x2 = x2;
+ extents->y1 = y1;
+ extents->y2 = y2;
}
void
@@ -958,10 +954,9 @@ lsm_svg_view_show_polygon (LsmSvgView *view, const char *points)
_show_points (view, points, TRUE);
}
-void
-lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y)
+static void
+_update_pango_layout (LsmSvgView *view, char const *string, double x, double y, LsmSvgViewPathInfos *path_infos)
{
- LsmSvgViewPathInfos path_infos = default_path_infos;
const LsmSvgStyle *style;
PangoLayout *pango_layout;
PangoFontDescription *font_description;
@@ -972,28 +967,8 @@ lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y
int baseline;
double x1, y1;
- if (string == NULL || string[0] == '\0')
- return;
-
- g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
style = view->style;
- lsm_debug_render ("[LsmSvgView::show_text] Show '%s' at %g,%g (%g px)", string, x, y, style->font_size_px);
-
- /* A text may be painted with a text based pattern. In this case,
- * we take care to create a new pango layout if the current one is in use. */
- if (view->is_pango_layout_in_use) {
- PangoContext *pango_context;
-
- pango_context = pango_layout_get_context (view->pango_layout);
- view->pango_layout_stack = g_slist_prepend (view->pango_layout_stack, view->pango_layout);
- view->pango_layout = pango_layout_new (pango_context);
-
- lsm_debug_render ("[LsmSvgView::show_text] Create a new pango layout");
- } else
- view->is_pango_layout_in_use = TRUE;
-
pango_layout = view->pango_layout;
font_description = view->dom_view.font_description;
@@ -1070,30 +1045,42 @@ lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y
break;
}
- path_infos.is_text_path = TRUE;
- path_infos.is_extents_defined = TRUE;
- path_infos.extents.x1 = x1;
- path_infos.extents.y1 = y1;
- path_infos.extents.x2 = x1 + pango_units_to_double (rectangle.width);
- path_infos.extents.y2 = y1 + pango_units_to_double (rectangle.height);
- path_infos.pango_layout = pango_layout;
+ path_infos->is_text_path = TRUE;
+ path_infos->is_extents_defined = TRUE;
+ path_infos->extents.x1 = x1;
+ path_infos->extents.y1 = y1;
+ path_infos->extents.x2 = x1 + pango_units_to_double (rectangle.width);
+ path_infos->extents.y2 = y1 + pango_units_to_double (rectangle.height);
+ path_infos->pango_layout = pango_layout;
+}
- if (style->writing_mode->value == LSM_SVG_WRITING_MODE_TB ||
- style->writing_mode->value == LSM_SVG_WRITING_MODE_TB_RL) {
+static gboolean
+_lock_pango_layout (LsmSvgView *view)
+{
+ /* A text may be painted with a text based pattern. In this case,
+ * we take care to create a new pango layout if the current one is in use. */
+ if (view->is_pango_layout_in_use) {
+ PangoContext *pango_context;
- cairo_save (view->dom_view.cairo);
- cairo_rotate (view->dom_view.cairo, M_PI / 2.0);
- cairo_move_to (view->dom_view.cairo, x1, y1);
+ pango_context = pango_layout_get_context (view->pango_layout);
+ view->pango_layout_stack = g_slist_prepend (view->pango_layout_stack, view->pango_layout);
+ view->pango_layout = pango_layout_new (pango_context);
- process_path (view, &path_infos);
+ lsm_debug_render ("[LsmSvgView::show_text] Create a new pango layout");
- cairo_restore (view->dom_view.cairo);
- } else {
- cairo_move_to (view->dom_view.cairo, x1, y1);
- process_path (view, &path_infos);
+ return TRUE;
}
- if (pango_layout != view->pango_layout) {
+ view->is_pango_layout_in_use = TRUE;
+
+ return FALSE;
+}
+
+static void
+_unlock_pango_layout (LsmSvgView *view, gboolean need_pop)
+{
+
+ if (need_pop) {
lsm_debug_render ("[LsmSvgView::show_text] Free the child pango layout");
if (view->pango_layout != NULL) {
@@ -1110,6 +1097,70 @@ lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y
}
void
+lsm_svg_view_show_text (LsmSvgView *view, char const *string, double x, double y)
+{
+ LsmSvgViewPathInfos path_infos = default_path_infos;
+ const LsmSvgStyle *style;
+ gboolean need_pop;
+
+ if (string == NULL || string[0] == '\0')
+ return;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+ style = view->style;
+
+ lsm_debug_render ("[LsmSvgView::show_text] Show '%s' at %g,%g (%g px)", string, x, y, style->font_size_px);
+
+ need_pop = _lock_pango_layout (view);
+
+ _update_pango_layout (view, string, x, y, &path_infos);
+
+ if (style->writing_mode->value == LSM_SVG_WRITING_MODE_TB ||
+ style->writing_mode->value == LSM_SVG_WRITING_MODE_TB_RL) {
+
+ cairo_save (view->dom_view.cairo);
+ cairo_rotate (view->dom_view.cairo, M_PI / 2.0);
+ cairo_move_to (view->dom_view.cairo, path_infos.extents.x1, path_infos.extents.y1);
+
+ process_path (view, &path_infos);
+
+ cairo_restore (view->dom_view.cairo);
+ } else {
+ cairo_move_to (view->dom_view.cairo, path_infos.extents.x1, path_infos.extents.y1);
+ process_path (view, &path_infos);
+ }
+
+ _unlock_pango_layout (view, need_pop);
+}
+
+void
+lsm_svg_view_text_extents (LsmSvgView *view, char const *string, double x, double y, LsmExtents *extents)
+{
+ LsmSvgViewPathInfos path_infos = default_path_infos;
+ gboolean need_pop;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+ g_return_if_fail (extents != NULL);
+
+ if (string == NULL ||
+ string[0] == '\0') {
+ extents->x1 = 0;
+ extents->y1 = 0;
+ extents->y1 = 0;
+ extents->y2 = 0;
+ }
+
+ need_pop = _lock_pango_layout (view);
+
+ _update_pango_layout (view, string, x, y, &path_infos);
+
+ _unlock_pango_layout (view, need_pop);
+
+ *extents = path_infos.extents;
+}
+
+void
lsm_svg_view_show_pixbuf (LsmSvgView *view, GdkPixbuf *pixbuf)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index c553776..a0c3e33 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -95,9 +95,7 @@ const LsmBox * lsm_svg_view_get_pattern_extents (LsmSvgView *view);
const LsmBox * lsm_svg_view_get_object_extents (LsmSvgView *view);
const LsmBox * lsm_svg_view_get_clip_extents (LsmSvgView *view);
-void lsm_svg_view_calculate_path_extents (LsmSvgView *view, const char *path,
- double *x1, double *y1,
- double *x2, double *y2);
+void lsm_svg_view_path_extents (LsmSvgView *view, const char *path, LsmExtents *extents);
void lsm_svg_view_create_radial_gradient (LsmSvgView *view, double cx, double cy,
double r, double fx, double fy);
@@ -125,6 +123,7 @@ void lsm_svg_view_show_line (LsmSvgView *view, double x1, double y1, double
void lsm_svg_view_show_polyline (LsmSvgView *view, const char *points);
void lsm_svg_view_show_polygon (LsmSvgView *view, const char *points);
void lsm_svg_view_show_text (LsmSvgView *view, char const *text, double x, double y);
+void lsm_svg_view_text_extents (LsmSvgView *view, char const *string, double x, double y, LsmExtents *extents);
void lsm_svg_view_show_pixbuf (LsmSvgView *view, GdkPixbuf *pixbuf);
void lsm_svg_view_push_viewbox (LsmSvgView *view, const LsmBox *viewbox);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]