summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2008-08-06 08:38:47 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2008-08-06 08:38:47 +0000
commitfb5d6ad85ca10e67db70575b0604894fa8c484f5 (patch)
tree6d981e7a19a26d9e73af5940ccc2f8451940e940 /pango
parent1c37e9281dfb928291911f13e2ffb21589024725 (diff)
downloadpango-fb5d6ad85ca10e67db70575b0604894fa8c484f5.tar.gz
New public API:
2008-07-30 Behdad Esfahbod <behdad@gnome.org> * docs/pango-sections.txt: * docs/tmpl/pango-renderer.sgml: * pango/pango-renderer.c: * pango/pango-renderer.h: New public API: PangoRenderer::draw_glyph_item() pango_renderer_draw_glyph_item() Make layout and layout-line default renderers go through draw_glyph_item(), which then by default falls back to draw_glyphs(). The advantage in draw_glyph_item() is that it has access to the text and cluster information. * pango/pangocairo.h: * pango/pangocairo-render.c: New public API: pango_cairo_show_glyph_item() svn path=/trunk/; revision=2674
Diffstat (limited to 'pango')
-rw-r--r--pango/pango-renderer.c67
-rw-r--r--pango/pango-renderer.h16
-rw-r--r--pango/pango.def1
-rw-r--r--pango/pangocairo-render.c178
-rw-r--r--pango/pangocairo.def1
-rw-r--r--pango/pangocairo.h3
6 files changed, 258 insertions, 8 deletions
diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c
index a5f5368e..9febeddc 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -64,6 +64,11 @@ static void pango_renderer_default_draw_glyphs (PangoRenderer *rende
PangoGlyphString *glyphs,
int x,
int y);
+static void pango_renderer_default_draw_glyph_item (PangoRenderer *renderer,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ int x,
+ int y);
static void pango_renderer_default_draw_rectangle (PangoRenderer *renderer,
PangoRenderPart part,
int x,
@@ -107,6 +112,7 @@ pango_renderer_class_init (PangoRendererClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->draw_glyphs = pango_renderer_default_draw_glyphs;
+ klass->draw_glyph_item = pango_renderer_default_draw_glyph_item;
klass->draw_rectangle = pango_renderer_default_draw_rectangle;
klass->draw_error_underline = pango_renderer_default_draw_error_underline;
klass->prepare_run = pango_renderer_default_prepare_run;
@@ -455,6 +461,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
GSList *l;
gboolean got_overall = FALSE;
PangoRectangle overall_rect;
+ const char *text;
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
@@ -476,6 +483,8 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
state.underline = PANGO_UNDERLINE_NONE;
state.strikethrough = FALSE;
+ text = pango_layout_get_text (line->layout);
+
for (l = line->runs; l; l = l->next)
{
PangoFontMetrics *metrics;
@@ -556,9 +565,10 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
}
else
{
- pango_renderer_draw_glyphs (renderer,
- run->item->analysis.font, run->glyphs,
- x + x_off, y - rise);
+ pango_renderer_draw_glyph_item (renderer,
+ text,
+ run,
+ x + x_off, y - rise);
}
if (renderer->underline != PANGO_UNDERLINE_NONE ||
@@ -658,6 +668,57 @@ pango_renderer_default_draw_glyphs (PangoRenderer *renderer,
}
/**
+ * pango_renderer_draw_glyph_item:
+ * @renderer: a #PangoRenderer
+ * @text: the UTF-8 text that @glyph_item refers to
+ * @glyph_item: a #PangoGlyphItem
+ * @x: X position of left edge of baseline, in user space coordinates
+ * in Pango units.
+ * @y: Y position of left edge of baseline, in user space coordinates
+ * in Pango units.
+ *
+ * Draws the glyphs in @glyph_item with the specified #PangoRenderer,
+ * embedding the text associated with the glyphs in the output if the
+ * output format supports it (PDF for example).
+ *
+ * Note that @text is the start of the text for layout, which is then
+ * indexed by <literal>glyph_item->item->offset</literal>.
+ *
+ * The default implementation of this method simply falls back to
+ * pango_renderer_draw_glyphs().
+ *
+ * Since: 1.22
+ **/
+void
+pango_renderer_draw_glyph_item (PangoRenderer *renderer,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ int x,
+ int y)
+{
+ g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
+
+ pango_renderer_activate (renderer);
+
+ PANGO_RENDERER_GET_CLASS (renderer)->draw_glyph_item (renderer, text, glyph_item, x, y);
+
+ pango_renderer_deactivate (renderer);
+}
+
+static void
+pango_renderer_default_draw_glyph_item (PangoRenderer *renderer,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ int x,
+ int y)
+{
+ pango_renderer_draw_glyphs (renderer,
+ glyph_item->item->analysis.font,
+ glyph_item->glyphs,
+ x, y);
+}
+
+/**
* pango_renderer_draw_rectangle:
* @renderer: a #PangoRenderer
* @part: type of object this rectangle is part of
diff --git a/pango/pango-renderer.h b/pango/pango-renderer.h
index 89c45fac..354127b7 100644
--- a/pango/pango-renderer.h
+++ b/pango/pango-renderer.h
@@ -101,6 +101,7 @@ struct _PangoRenderer
* @begin: Do renderer-specific initialization before drawing
* @end: Do renderer-specific cleanup after drawing
* @prepare_run: updates the renderer for a new run
+ * @draw_glyph_item: draws a #PangoGlyphItem
*
* Class structure for #PangoRenderer.
*
@@ -172,10 +173,18 @@ struct _PangoRendererClass
void (*prepare_run) (PangoRenderer *renderer,
PangoLayoutRun *run);
+ /* All of the following have default implementations
+ * and take as coordinates user coordinates in Pango units
+ */
+ void (*draw_glyph_item) (PangoRenderer *renderer,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ int x,
+ int y);
+
/*< private >*/
/* Padding for future expansion */
- void (*_pango_reserved1) (void);
void (*_pango_reserved2) (void);
void (*_pango_reserved3) (void);
void (*_pango_reserved4) (void);
@@ -196,6 +205,11 @@ void pango_renderer_draw_glyphs (PangoRenderer *renderer,
PangoGlyphString *glyphs,
int x,
int y);
+void pango_renderer_draw_glyph_item (PangoRenderer *renderer,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ int x,
+ int y);
void pango_renderer_draw_rectangle (PangoRenderer *renderer,
PangoRenderPart part,
int x,
diff --git a/pango/pango.def b/pango/pango.def
index 89fae6c5..8823b2ed 100644
--- a/pango/pango.def
+++ b/pango/pango.def
@@ -329,6 +329,7 @@ EXPORTS
pango_renderer_deactivate
pango_renderer_draw_error_underline
pango_renderer_draw_glyph
+ pango_renderer_draw_glyph_item
pango_renderer_draw_glyphs
pango_renderer_draw_layout
pango_renderer_draw_layout_line
diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c
index ea100b0b..1fd7dbc3 100644
--- a/pango/pangocairo-render.c
+++ b/pango/pangocairo-render.c
@@ -37,6 +37,7 @@ struct _PangoCairoRenderer
cairo_t *cr;
gboolean do_path;
+ gboolean has_show_text_glyphs;
double x_offset, y_offset;
/* house-keeping options */
@@ -270,6 +271,9 @@ done:
cairo_restore (crenderer->cr);
}
+/* cairo_glyph_t is 24 bytes */
+#define MAX_STACK 40
+
static void
pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer,
PangoFont *font,
@@ -279,9 +283,6 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer,
{
PangoCairoRenderer *crenderer = (PangoCairoRenderer *) (renderer);
- /* cairo_glyph_t is 24 bytes */
-#define MAX_STACK 40
-
int i, count;
int x_position = 0;
cairo_glyph_t *cairo_glyphs;
@@ -354,10 +355,103 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer,
done:
cairo_restore (crenderer->cr);
+}
-#undef MAX_STACK
+static void
+pango_cairo_renderer_draw_glyph_item (PangoRenderer *renderer,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ int x,
+ int y)
+{
+ PangoCairoRenderer *crenderer = (PangoCairoRenderer *) (renderer);
+ PangoFont *font = glyph_item->item->analysis.font;
+ PangoGlyphString *glyphs = glyph_item->glyphs;
+
+ int i, count;
+ int x_position = 0;
+ cairo_glyph_t *cairo_glyphs;
+ cairo_glyph_t stack_glyphs[MAX_STACK];
+ double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
+ double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
+
+ if (!crenderer->has_show_text_glyphs || crenderer->do_path)
+ {
+ pango_cairo_renderer_draw_glyphs (renderer,
+ glyph_item->item->analysis.font,
+ glyph_item->glyphs,
+ x, y);
+ return;
+ }
+
+ cairo_save (crenderer->cr);
+ set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
+
+ if (!_pango_cairo_font_install (font, crenderer->cr))
+ {
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ PangoGlyphInfo *gi = &glyphs->glyphs[i];
+
+ if (gi->glyph != PANGO_GLYPH_EMPTY)
+ {
+ double cx = base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ double cy = gi->geometry.y_offset == 0 ?
+ base_y :
+ base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
+
+ /* XXX */
+ _pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
+ }
+ x_position += gi->geometry.width;
+ }
+
+ goto done;
+ }
+
+ if (glyphs->num_glyphs > MAX_STACK)
+ cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs);
+ else
+ cairo_glyphs = stack_glyphs;
+
+ count = 0;
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ PangoGlyphInfo *gi = &glyphs->glyphs[i];
+
+ if (gi->glyph != PANGO_GLYPH_EMPTY)
+ {
+ double cx = base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ double cy = gi->geometry.y_offset == 0 ?
+ base_y :
+ base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
+
+ if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
+ /* XXX */
+ _pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
+ else
+ {
+ cairo_glyphs[count].index = gi->glyph;
+ cairo_glyphs[count].x = cx;
+ cairo_glyphs[count].y = cy;
+ count++;
+ }
+ }
+ x_position += gi->geometry.width;
+ }
+
+ /* XXX */
+ cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
+
+ if (glyphs->num_glyphs > MAX_STACK)
+ g_free (cairo_glyphs);
+
+done:
+ cairo_restore (crenderer->cr);
}
+#undef MAX_STACK
+
static void
pango_cairo_renderer_draw_rectangle (PangoRenderer *renderer,
PangoRenderPart part,
@@ -544,6 +638,7 @@ pango_cairo_renderer_class_init (PangoCairoRendererClass *klass)
PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
renderer_class->draw_glyphs = pango_cairo_renderer_draw_glyphs;
+ renderer_class->draw_glyph_item = pango_cairo_renderer_draw_glyph_item;
renderer_class->draw_rectangle = pango_cairo_renderer_draw_rectangle;
renderer_class->draw_error_underline = pango_cairo_renderer_draw_error_underline;
renderer_class->draw_shape = pango_cairo_renderer_draw_shape;
@@ -582,6 +677,7 @@ release_renderer (PangoCairoRenderer *renderer)
{
renderer->cr = NULL;
renderer->do_path = FALSE;
+ renderer->has_show_text_glyphs = FALSE;
renderer->x_offset = 0.;
renderer->y_offset = 0.;
@@ -596,6 +692,9 @@ save_current_point (PangoCairoRenderer *renderer)
{
renderer->cr_had_current_point = cairo_has_current_point (renderer->cr);
cairo_get_current_point (renderer->cr, &renderer->x_offset, &renderer->y_offset);
+
+ /* abuse save_current_point() to cache cairo_has_show_text_glyphs() result */
+ renderer->has_show_text_glyphs = cairo_has_show_text_glyphs (renderer->cr);
}
static void
@@ -652,6 +751,45 @@ _pango_cairo_do_glyph_string (cairo_t *cr,
}
static void
+_pango_cairo_do_glyph_item (cairo_t *cr,
+ const char *text,
+ PangoGlyphItem *glyph_item,
+ gboolean do_path)
+{
+ PangoCairoRenderer *crenderer = acquire_renderer ();
+ PangoRenderer *renderer = (PangoRenderer *) crenderer;
+
+ crenderer->cr = cr;
+ crenderer->do_path = do_path;
+ save_current_point (crenderer);
+
+ if (!do_path)
+ {
+ /* unset all part colors, since when drawing just a glyph string,
+ * prepare_run() isn't called.
+ */
+
+ pango_renderer_activate (renderer);
+
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_FOREGROUND, NULL);
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_BACKGROUND, NULL);
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_UNDERLINE, NULL);
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_STRIKETHROUGH, NULL);
+ }
+
+ pango_renderer_draw_glyph_item (renderer, text, glyph_item, 0, 0);
+
+ if (!do_path)
+ {
+ pango_renderer_deactivate (renderer);
+ }
+
+ restore_current_point (crenderer);
+
+ release_renderer (crenderer);
+}
+
+static void
_pango_cairo_do_layout_line (cairo_t *cr,
PangoLayoutLine *line,
gboolean do_path)
@@ -739,6 +877,38 @@ pango_cairo_show_glyph_string (cairo_t *cr,
_pango_cairo_do_glyph_string (cr, font, glyphs, FALSE);
}
+
+/**
+ * pango_cairo_show_glyph_item:
+ * @cr: a Cairo context
+ * @text: the UTF-8 text that @glyph_item refers to
+ * @glyph_item: a #PangoGlyphItem
+ *
+ * Draws the glyphs in @glyph_item in the specified cairo context,
+ * embedding the text associated with the glyphs in the output if the
+ * output format supports it (PDF for example), otherwise it acts
+ * similar to pango_cairo_show_glyph_string().
+ *
+ * The origin of the glyphs (the left edge of the baseline) will
+ * be drawn at the current point of the cairo context.
+ *
+ * Note that @text is the start of the text for layout, which is then
+ * indexed by <literal>glyph_item->item->offset</literal>.
+ *
+ * Since: 1.20
+ **/
+void
+pango_cairo_show_glyph_item (cairo_t *cr,
+ const char *text,
+ PangoGlyphItem *glyph_item)
+{
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (text != NULL);
+ g_return_if_fail (glyph_item != NULL);
+
+ _pango_cairo_do_glyph_item (cr, text, glyph_item, FALSE);
+}
+
/**
* pango_cairo_show_layout_line:
* @cr: a Cairo context
diff --git a/pango/pangocairo.def b/pango/pangocairo.def
index 3bceacd2..f3052eb0 100644
--- a/pango/pangocairo.def
+++ b/pango/pangocairo.def
@@ -26,6 +26,7 @@ EXPORTS
pango_cairo_layout_path
pango_cairo_renderer_get_type
pango_cairo_show_error_underline
+ pango_cairo_show_glyph_item
pango_cairo_show_glyph_string
pango_cairo_show_layout
pango_cairo_show_layout_line
diff --git a/pango/pangocairo.h b/pango/pangocairo.h
index b9191cd8..f11bf65f 100644
--- a/pango/pangocairo.h
+++ b/pango/pangocairo.h
@@ -116,6 +116,9 @@ void pango_cairo_update_layout (cairo_t *cr,
void pango_cairo_show_glyph_string (cairo_t *cr,
PangoFont *font,
PangoGlyphString *glyphs);
+void pango_cairo_show_glyph_item (cairo_t *cr,
+ const char *text,
+ PangoGlyphItem *glyph_item);
void pango_cairo_show_layout_line (cairo_t *cr,
PangoLayoutLine *line);
void pango_cairo_show_layout (cairo_t *cr,