diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2008-08-06 08:38:47 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2008-08-06 08:38:47 +0000 |
commit | fb5d6ad85ca10e67db70575b0604894fa8c484f5 (patch) | |
tree | 6d981e7a19a26d9e73af5940ccc2f8451940e940 /pango/pangocairo-render.c | |
parent | 1c37e9281dfb928291911f13e2ffb21589024725 (diff) | |
download | pango-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/pangocairo-render.c')
-rw-r--r-- | pango/pangocairo-render.c | 178 |
1 files changed, 174 insertions, 4 deletions
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 |