[cairo] Help needed with pangocairo.

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


Hello,

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  
following:

(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,
-Hazen


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;

   set_current_context(pls);

   // 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");
     return;
   }
	
   // 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);
     return;
   }

   // 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- 
 >text_anti_aliasing);
   pango_cairo_context_set_font_options(context, cairoFontOptions);
   pango_layout_context_changed(layout);

   cairo_font_options_destroy(cairoFontOptions);

   // Save current transform matrix & clipping region
   cairo_save(aStream->cairoContext);

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

   // 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_t));
   cairo_matrix_init(cairoTransformMatrix, 1.0, 0.0, 0.0, -1.0, 0.0,  
0.0);
   cairo_transform(aStream->cairoContext, cairoTransformMatrix);

   // Extract rotation angle and shear from the PLplot tranformation  
matrix.
   // 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
   cairo_matrix_init(cairoTransformMatrix,
		    cos_rot,
		    -sin_rot,
		    cos_rot * sin_shear + sin_rot * cos_shear,
		    -sin_rot * sin_shear + cos_rot * cos_shear,
		    0,0);
   cairo_transform(aStream->cairoContext, cairoTransformMatrix);
   free(cairoTransformMatrix);

   // Move to the text starting point
   cairo_rel_move_to(aStream->cairoContext,
		    (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  
transform.
   cairo_restore(aStream->cairoContext);

   // Free the layout object and the markup string.
   g_object_unref(layout);
   free(textWithPangoMarkup);
}



More information about the cairo mailing list