Computing cairo surface dimensions in advance
- From: Daniel Elstner <daniel kitta googlemail com>
- To: gtk-i18n-list gnome org
- Subject: Computing cairo surface dimensions in advance
- Date: Mon, 11 Dec 2006 23:35:06 +0100
Hello,
in one of my pet projects I use Pango and cairo to render text into an
intensity texture for OpenGL drawing. To save space while keeping
things flexible, I put each user interface string into a separate
rectangle texture, tightly fitting around the ink extents of the layout.
But to do that, I need to know the dimensions of the layout in advance
before creating the cairo image surface to draw on. This leads to a
chicken'n'egg problem of course since I can't call
pango_cairo_update_layout() before creating a cairo surface. In fact it
happens to work even if I don't call pango_cairo_update_layout() at all
(I get the PangoLayout from gtk_widget_create_pango_layout). But that's
probably just by chance. Trying to do things the Right Way (tm), my
code now looks like this:
// Try to do things correctly and create a dummy cairo context with surface
// type and transformation matching what we are going to use at draw time.
// According to the pangocairo documentation, not doing so might result in
// wrong measurements due to possible differences in hinting and such.
{
cairo_surface_t *const surface = cairo_image_surface_create(CAIRO_FORMAT_A8, 1, 1);
cairo_t *const context = cairo_create(surface);
cairo_surface_destroy(surface); // drop reference
cairo_scale(context, 1.0, -1.0);
pango_cairo_update_layout(context, layout->gobj());
layout->get_pixel_extents(ink, logical);
cairo_destroy(context);
}
[... code computing the image size and other stuff ...]
// Create a Cairo surface to draw the layout directly into the texture
// image -- upside-down and at the right position. This rocking new
// functionality allows us to get away without any buffer copies, yay!
{
cairo_surface_t *const surface = cairo_image_surface_create_for_data(
&tex_image[0], CAIRO_FORMAT_A8, img_width, img_height, img_width * sizeof(GLubyte));
cairo_t *const context = cairo_create(surface);
cairo_surface_destroy(surface); // drop reference
cairo_scale(context, 1.0, -1.0);
cairo_move_to(context, img_border + PADDING - ink.get_x(),
-(img_border + PADDING + ink.get_y() + ink.get_height()));
pango_cairo_show_layout(context, layout->gobj());
cairo_destroy(context);
}
'Tis ain't pretty. Is the code above actually correct? Is there a
better to do this kind of thing?
Thanks a lot for your help,
--Daniel
P.S.: Sorry if this has been asked before; the search facility of the
mail.gnome.org archives is currently broken.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]