[cairo] rendering UTF8 text
behdad at behdad.org
Thu Jun 28 12:23:32 PDT 2007
On Thu, 2007-06-28 at 21:15 +0200, Ulrich Mierendorff wrote:
> Thank you for information about that. Now, that I have seen all the
> benefits of cairo-pango, I will use it.
> However, I have one question left. If I render a complicated pango
> layout with much text how can I determine the size for the cairo
> rendering context before actually rendering it, because I must create
> the surface before ("cairo_image_surface_create(..,SIZEX,SIZEY);")
> rendering. I think it will be impossible? So how to do? Rendering twice?
> Maybe one fast pass without AA enabled to determine the size and a
> second one with quality enabled?
> I do not know if this is cairo or pango dependent...
Yes, render twice, but don't worry about the performance impact. You
can already make the second pass quite fast by reusing the same layout
with a new cairo_t. Just call pango_cairo_update_layout() on it.
> Behdad Esfahbod schrieb:
> > On Tue, 2007-06-26 at 10:32 -0400, Carl Worth wrote:
> >> http://people.freedesktop.org/~cworth/utf8test-pango.c
> >> (Although, the last time I shared that with somebody, Behdad pointed
> >> out a couple of style issues with it, and I haven't fixed them. I plan
> >> to resurrect the cairo wiki this week and we can start hosting
> >> examples there for people to collaborate on improving them.)
> > Here it goes for the record:
> > /* cc `pkg-config --cflags --libs pangocairo libpng12` utf8test-pango.c -o utf8test-pango */
> > Instead of hardcoding libpng12, you can use cairo-png.
> > if (width || height)
> > pango_layout_get_size (layout, &pango_width, &pango_height);
> > if (width)
> > *width = (double) pango_width / PANGO_SCALE;
> > if (height)
> > *height = (double) pango_height / PANGO_SCALE;
> > You can use pango_layout_get_pixel_size() to avoid the divisions. It
> > will return rounded integers though, but that's what you need most of
> > the time.
> > cairo_translate (cr, 10, 30 - height);
> > pango_cairo_show_layout(cr, layout);
> > This will position the bottom-left of the layout at 10,30. I guess what
> > you want however is to have the baseline-left at that position. To do
> > that, use:
> > cairo_move_to (cr, 10, 30);
> > pango_cairo_show_layout_line (cr, pango_layout_get_line (layout, 0));
> > You notice I used cairo_move_to() instead of cairo_translate(). The
> > reason is that pango renders the layout at the current point of the
> > cairo context. Now normally the current point is invariant the context
> > matrix, which means, if the cairo context had a current point, the
> > cairo_translate() doesn't move the place the layout is rendered. But,
> > if the context has no current point, cairo returns (0,0) as current
> > point, and since that (0,0) is interpreted in user space, a
> > cairo_translate() on a context with no current point moves the place of
> > the rendered layout. Yuck!
"Those who would give up Essential Liberty to purchase a little
Temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin, 1759
More information about the cairo