mardi 4 août 2015

Create Pango Layout Before Cairo Surface

In my application, I am using Pango and Cairo to create text textures. These textures have their width fixed, but should scale their height to fit text contents. The parent objects involved in this situation will then scale their heights to match the text.

The problem is, the way I have been initializing Pango and Cairo does not allow for this. Currently, the system is set up by:

cairo_surface_t* cairoSurface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, sizeX, sizeY );
cairo_t* cairoContext = cairo_create( cairoSurface );
PangoLayout* pangoLayout = pango_cairo_create_layout( cairoContext );

Which fixes the height, at least of the surface - something I do not want to do, at least not all the time.

My understanding is that if the layout height is not specified, it will automatically scale the height, which can then be found via pango_layout_get_size(). I would like to create the layout first and then use the output of this function to create the surface.

However, pango_cairo_create_layout() requires the surface to already be created, and I have been unable to find a way to render a layout from pango_layout_new() via Cairo. The API docs one of the render functions, pango_cairo_update_layout(), specify that pango_cairo_create_layout() had to be used to create the layout; however, the more important function, pango_cairo_show_layout(), notes no such requirement, and I am not sure if that means that any Pango layout is allowed or not. While I could test if it works, I'm afraid that trial and error could lead me to undefined behavior.

I feel like I'm stuck in a chicken and egg situation, and the documentation for Pango is mostly an API reference with little explanation of how the library is intended to be used. Is there a way to do this properly?


Updating this with some more information.

It seems to partially work if I pass a layout from pango_layout_new() to pango_cairo_show_layout(). To be specific, if I do not set up any kind of fonts, just create an empty ft2 fontmap, it will render, but with boxes for all characters. If I do set up a fontmap, it crashes on pango_cairo_show_layout(). The relevant portions of the setup are:

FcConfig *fontConfig = FcConfigCreate();
gchar* workingDir = g_get_current_dir();
gchar* resourceDir = g_strjoin( NULL, workingDir, "/Resources", (char*)0 );
FcConfigAppFontAddDir( fontConfig, (const FcChar8*)resourceDir );
g_free(workingDir);
g_free(resourceDir);
FcConfigBuildFonts( fontConfig );
FcConfigSetCurrent( fontConfig );

PangoFontMap* font_map = pango_ft2_font_map_new();
PangoContext* context = pango_font_map_create_context( font_map );
PangoLayout* pangoLayout = pango_layout_new( context );

PangoFontDescription* font_desc = pango_font_description_from_string( defaultFont.c_str( ) );
pango_layout_set_font_description( pangoLayout, font_desc );
pango_font_map_load_font( font_map, context, font_desc );
pango_font_description_free( font_desc );

pango_cairo_show_layout( cairoContext, pangoLayout );

I'm still at a complete loss as to how to handle any of this, let alone why the program would crash without any kind of feedback on this function. Even potentially helpful documentations or examples would be appreciated.

Aucun commentaire:

Enregistrer un commentaire