Cairo font face reference count

I have written a small code with gtk-3 and C++. I set cairo_select_face and query the reference to font-face. I get count as one and it is expected.
But when i use cairo_show_text, the font_face reference count becomes 2. After that, any number of cairo_show_text ()do not change the reference count and reference count is always 2. I am wondering why
cairo_show_text () when called the first time increases the count to 2 for the first time. expect reference count to say 1 always.

My code is below

#include <cairo.h>
#include <gtk/gtk.h>

gboolean timer = TRUE;
int i = 1;
int current_count =0;
cairo_font_face_t* font_face;

static gboolean do_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
  cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);

  cairo_select_font_face(cr, "Purisa",
      CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_BOLD);
  font_face = cairo_get_font_face (cr);
  current_count =cairo_font_face_get_reference_count (font_face);
    fprintf (stderr, "refernce_count in drawing: %d\n", current_count); ----------> prints 1

  cairo_set_font_size(cr, 13);
  font_face = cairo_get_font_face (cr);
current_count =cairo_font_face_get_reference_count (font_face);
fprintf (stderr, "refernce_count in drawing: %d\n", current_count);---------> prints 1

   cairo_move_to(cr, 20, 30);
  cairo_show_text(cr, "Most relationships seem so transitory");
  font_face = cairo_get_font_face (cr);
  current_count =cairo_font_face_get_reference_count (font_face);
   fprintf (stderr, "reference_count in drawing------: %d\n", current_count);----------------->print 2

  cairo_move_to(cr, 20, 60);
  cairo_show_text(cr, "They're all good but not the permanent one");
  font_face = cairo_get_font_face (cr);
current_count =cairo_font_face_get_reference_count (font_face);
fprintf (stderr, "reference_count in drawing: %d\n", current_count);------------->prints 2from here

  cairo_move_to(cr, 20, 120);
  cairo_show_text(cr, "Who doesn't long for someone to hold");
  font_face = cairo_get_font_face (cr);
current_count =cairo_font_face_get_reference_count (font_face);
fprintf (stderr, "refernce_count in drawing: %d\n", current_count);font_face = cairo_get_font_face (cr);
current_count =cairo_font_face_get_reference_count (font_face);
fprintf (stderr, "reference_count in drawing: %d\n", current_count);
  cairo_move_to(cr, 20, 180);
  cairo_show_text(cr, "Somebody tell me why I'm on my own");
  font_face = cairo_get_font_face (cr);
current_count =cairo_font_face_get_reference_count (font_face);
fprintf (stderr, "reference_count in drawing: %d\n", current_count);
  cairo_move_to(cr, 20, 210);
  cairo_show_text(cr, "If there's a soulmate for everyone");
  font_face = cairo_get_font_face (cr);
 current_count =cairo_font_face_get_reference_count (font_face);
 fprintf (stderr, "reference_count in drawing: %d\n", current_count);------------->prints 2

}
static gboolean time_handler(GtkWidget *widget)
{
    if (i > 15) return FALSE;
    printf("drawing frame %d\n", i);
    gtk_widget_queue_draw(widget);
    i++;
    return TRUE;
}

int main(int argc, char *argv[])
{
    // gtk inits
     gtk_init(&argc, &argv);
     GtkWidget *window  = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *drawarea = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), drawarea);
    gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
    g_signal_connect(G_OBJECT(drawarea), "draw", G_CALLBACK(do_draw), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_timeout_add(200, (GSourceFunc) time_handler, (gpointer) window);
    gtk_widget_show_all(window);
   gtk_main();
  return 0;
}
  cairo_move_to(cr, 20, 150);
  cairo_show_text(cr, "Who knows how to love you without being told");

What is your concrete issue with that? Are you creating language bindings for some of the modern new languages, or fixing old bindings? Or do you have an app that leaks memory?

I guess you know that cairo has its dedicated mailing list? And that this list is nearly death? Actually I think questions like that comes 15 years too late now. Cairo somehow works, it is a bit slow. If you should be new to Cairo, and intent to use it from C or C++, I would suggest to you using Blend2d instead. It is faster and more fun, as it is still alive. In case that you intent to use Rust, you may also read Raph Levien’s blog about piet-gpu and other interesting Rust (GUI) projects, see https://raphlinus.github.io/.

To your refcount 2 issue, I could imagine that cairo somehow tries to cache some data internally, so increase the refcount once to have always one ref for reuse. I created the Nim cairo bindings maybe six years ago, and am now too lazy to really invest that issue.

Thanks for your detailed response.
I am not new to Cairo and I use it for displays with GTK.
I like Cairo even though , it keeps the pointers open. However, msize and VmPeak after several runs remain the same.

But in one of my app, i see that memory keeps increasing slighly for every run, and I don’t have any obvious memory leak in my code.
I wanted to destroy font-face , but since reference count is 2 , it is not possible to destroy as refcount >1.
I can try other ways, but just thought i would ask so that ome one may have a suggestion.

Many thanks for your detailed response.
Thanks.

1 Like

Have you considered asking Google? Search term “cairo_show_text memory leak” gives us this link: c++ - cairo_show_text memory leak - Stack Overflow

There fontconfig is mentioned, and calling FcFini() is recommended. Maybe you can try that.

I have tried all that already.
Unless refcount is 0, FCFini () we will not work.
Thank you.

Likely because Cairo keeps a reference on the font face in its cache.

You should use the Cairo mailing list for questions about Cairo, as Cairo developers are unlikely to read topics on the GNOME Discourse. You should also not use the Cairo toy text API: use Pango instead.

1 Like

Thanks for your time.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.