[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