[cairo] Help needed with pangocairo.

Hazen Babcock hbabcock at mac.com
Wed Mar 19 19:08:11 PDT 2008


I'm working on a program (well actually a the cairo driver for the  
PLplot graphing library) and I've run into a problem. The problem  
appears when I create a surface/context, render some text using  
pango, destroy the surface/context, create a new surface/context and  
try to render some more text. The error message I'm getting is the  

(process:8456): GLib-GObject-WARNING **: cannot register existing  
type `PangoCairoFcFontMap'

(process:8456): GLib-GObject-WARNING **: cannot register existing  
type `PangoCairoFontMap'

(process:8456): GLib-GObject-CRITICAL **:  
g_type_interface_add_prerequisite: assertion `G_TYPE_IS_INTERFACE  
(interface_type)' failed

(process:8456): GLib-GObject-CRITICAL **:  
g_type_add_interface_static: assertion `G_TYPE_IS_INSTANTIATABLE  
(instance_type)' failed

The error messages come from calling pango_cairo_create_layout().  
This function is called many times between the creation and  
destruction of the first surface/context. It fails on the first call  
after the creation of the new surface/context.

Unfortunately I have not been able to reproduce this problem in a  
simpler test program. I'm hoping that someone will have a good guess  
about what I might be doing wrong or where to look.

Thank you,

The hopefully relevant section of the source:

// proc_str()
// Processes strings for display.

void proc_str(PLStream *pls, EscText *args)
   int i;
   float fontSize;
   int textXExtent, textYExtent;
   char *textWithPangoMarkup;
   PLFLT rotation, shear, cos_rot, sin_rot, cos_shear, sin_shear;
   cairo_matrix_t *cairoTransformMatrix;
   cairo_font_options_t *cairoFontOptions;
   PangoContext *context;
   PangoLayout *layout;
   PLCairo *aStream;

   aStream = (PLCairo *)pls->dev;


   // Check that we got unicode, warning message and return if not
   if(args->unicode_array_len == 0){
     printf("Non unicode string passed to a cairo driver, ignoring\n");
   // Check that unicode string isn't longer then the max we allow	
   if(args->unicode_array_len >= MAX_STRING_LEN){
     printf("Sorry, the cairo drivers only handles strings of length  
< %d\n", MAX_STRING_LEN);

   // Calculate the font size (in pixels)
   fontSize = pls->chrht * DPI/25.4;

   // Convert the escape characters into the appropriate Pango markup
   textWithPangoMarkup = ucs4_to_pango_markup_format(args- 
 >unicode_array, args->unicode_array_len, fontSize);

   // Create the Pango text layout so we can figure out how big it is
   layout = pango_cairo_create_layout(aStream->cairoContext);
   pango_layout_set_markup(layout, textWithPangoMarkup, -1);
   pango_layout_get_pixel_size(layout, &textXExtent, &textYExtent);

   // Set font aliasing
   context = pango_layout_get_context(layout);
   cairoFontOptions = cairo_font_options_create();
   cairo_font_options_set_antialias(cairoFontOptions, aStream- 
   pango_cairo_context_set_font_options(context, cairoFontOptions);


   // Save current transform matrix & clipping region

   // Set up the clipping region if we are doing text clipping
     cairo_rectangle(aStream->cairoContext, DOWNSCALE * pls->clpxmi,  
DOWNSCALE * pls->clpymi, DOWNSCALE * (pls->clpxma - pls->clpxmi),  
DOWNSCALE * (pls->clpyma - pls->clpymi));

   // Move to the string reference point
   cairo_move_to(aStream->cairoContext, DOWNSCALE * (double) args->x,  
DOWNSCALE * (double) args->y);

   // Invert the coordinate system so that the text is drawn right  
side up
   cairoTransformMatrix = (cairo_matrix_t *) malloc (sizeof 
   cairo_matrix_init(cairoTransformMatrix, 1.0, 0.0, 0.0, -1.0, 0.0,  
   cairo_transform(aStream->cairoContext, cairoTransformMatrix);

   // Extract rotation angle and shear from the PLplot tranformation  
   // Compute sines and cosines of the angles as an optimization.
   plRotationShear(args->xform, &rotation, &shear);
   rotation -= pls->diorot * 3.14159 / 2.0;
   cos_rot = cos(rotation);
   sin_rot = sin(rotation);
   cos_shear = cos(shear);
   sin_shear = sin(shear);

   // Apply the transform matrix
		    cos_rot * sin_shear + sin_rot * cos_shear,
		    -sin_rot * sin_shear + cos_rot * cos_shear,
   cairo_transform(aStream->cairoContext, cairoTransformMatrix);

   // Move to the text starting point
		    (double)(-1.0 * args->just * (double)textXExtent),
		    (double)(-0.5 * textYExtent));

   // Render the text
   pango_cairo_show_layout(aStream->cairoContext, layout);

   // Restore the transform matrix to its state prior to the text  

   // Free the layout object and the markup string.

More information about the cairo mailing list