[cairo] Issue with Font_Face reference count?

Anne et Damien Carbonne aetdcarbonne at free.fr
Sun Dec 14 10:09:34 PST 2008


Hi,

Whilst updating the Ada binding, I found a problem with font face ref 
count in the binding.
I wrote a small C example that reproduces the issue I have with Ada: 
both versions have the same behaviour.
So, either I wrongly use cairo, or there is an issue inside cairo.

I use cairo 1.8.0 on a Linux box.

C code is hereafter. It is instrumented to print info on font face, but 
could be easily reduced.
One just needs to comment out this line:
  cairo_font_extents (context, &font_extents);
in order to obtain what I think is the expected result.
I noticed that this issue also happens with other calls than this one.

Help would be welcome!

Regards,

Damien Carbonne

Note : I didn't check with Cairo-1.8.4 as I didn't see any related topic 
in release note of 1.8.2 and 1.8.4.
But I could if necessary.


/*************************************************************************************/
#include "cairo/cairo.h"
#include <stdio.h>

static const char*
font_type_to_string (cairo_font_type_t font_type)
{
   switch (font_type)
   {
   case CAIRO_FONT_TYPE_TOY: return "CAIRO_FONT_TYPE_TOY";
   case CAIRO_FONT_TYPE_FT: return "CAIRO_FONT_TYPE_FT";
   case CAIRO_FONT_TYPE_WIN32: return "CAIRO_FONT_TYPE_WIN32";
   case CAIRO_FONT_TYPE_QUARTZ: return "CAIRO_FONT_TYPE_QUARTZ";
   case CAIRO_FONT_TYPE_USER: return "CAIRO_FONT_TYPE_USER";
   default: return "Invalid Font Type";
   }
}

/*
 * Print info (address, ref count, font type) on a font face
 */
static void
print_ff (const cairo_font_face_t* font_face)
{
  if (font_face)
  {
     printf ("ff:%x count:%d type:%s\n",
             font_face,
             cairo_font_face_get_reference_count (font_face),
             font_type_to_string (cairo_font_face_get_type (font_face)));
  }
  else
  {
     printf ("ff: NULL\n");
  }
}

static void
context_destroy(void* data)
{
   printf ("Context Destroy\n");
}

static void
surface_destroy(void* data)
{
   printf ("Surface Destroy\n");
}

static void
font_face_destroy(void* data)
{
   printf ("Font Face Destroy\n");
}

int
main (int argc, char** argv)
{
  cairo_surface_t* surface = 0;
  cairo_t* context = 0;
  cairo_font_face_t* font_face = 0;
  cairo_font_extents_t font_extents;
  static int key = 0;
  static int data = 0;

  printf("issue_001\n");
  print_ff (font_face);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 64, 64);
  cairo_surface_set_user_data (surface, &key, &data, surface_destroy);
  context = cairo_create (surface);
  cairo_set_user_data (context, &key, &data, context_destroy);
  font_face = cairo_toy_font_face_create ("Arial", 
CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  print_ff (font_face);
  cairo_font_face_set_user_data (font_face, &key, &data, font_face_destroy);
  print_ff (font_face);
  cairo_set_font_face (context, font_face);
  print_ff (font_face);

  /* The following call (cairo_font_extents) increments reference count 
of font_face
   * The font_face user data destroy cb is never called
   * If you comment it out, then the font_face user data destroy cb is 
called
   */
  cairo_font_extents (context, &font_extents);

  print_ff (font_face);

  cairo_surface_destroy (surface);
  cairo_font_face_destroy (font_face);
  cairo_destroy (context);

  return 0;
}
/*************************************************************************************/


More information about the cairo mailing list