Do

Comment 3 for bug 323271

Revision history for this message
Mirco Müller (macslow) wrote :

Indeed GNOME-Do/Docky's text-rendering does not take into account the system-wide font-rendering options (DPI, hinting, subpixel-order, antialiasing etc.). I assume that's due to it using cairo's image-surface and not cairo's xlib-surfaces, which would inherit those font-rendering options automatically.

If GNOME-Do would do the text-rendering using PangoCairo, it can easily get the correct font-options being used for image-surfaces by doing something like this (C not C#, skipping failure tests intentionally to keep example brief):

 // involved variables and types, where you get those from depends on your particular use-case
 cairo_surface_t* surface;
 cairo_t* cr;
 PangoFontDescription* desc;
 PangoLayout* layout;
 gchar* string_to_render;
 guint surface_width;
 guint surface_height;
 GtkWidget* top_level_widget;
 PangoRectangle ink_rect;
 PangoRectangle log_rect;
 const cairo_font_options_t* font_opts;
 gdouble dpi;
 gdouble text_pos_x;
 gdouble text_pos_y;
 gdouble text_color_r;
 gdouble text_color_g;
 gdouble text_color_b;
 gdouble text_color_a;

 ...

 // setup image-surface and context
 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface_width, surface_height);
 cr = cairo_create (surface);

 // clear context
 cairo_scale (cr, 1.0f, 1.0f);
 cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
 cairo_paint (cr);

 // setup pango's layout and font-decription structures
 layout = pango_cairo_create_layout (cr);
 desc = pango_font_description_new ();
 pango_layout_set_width (layout, surface_width * PANGO_SCALE);
 pango_layout_set_height (layout, surface_height * PANGO_SCALE);

 // set some example attributes for the text-rendering, chose whatever you like
 pango_font_description_set_size (desc, 12 * PANGO_SCALE);
 pango_font_description_set_family_static (desc, "Candara");
 pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
 pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
 pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
 pango_layout_set_font_description (layout, desc);
 pango_font_description_free (desc);
 pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
 pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);

 // get font-options and screen-DPI, top_level_widget must be realized by now at least
 font_opts = gdk_screen_get_font_options (gtk_widget_get_screen (top_level_widget));
 dpi = gdk_screen_get_resolution (gtk_widget_get_screen (top_level_widget));

 // set text to print, -1 indicates a '\0'-terminated string is assumed
 pango_layout_set_text (layout, string_to_render, -1);

 // one usually needs these at some point
 pango_layout_get_extents (layout, &ink_rect, &log_rect);

 // make sure system-wide font-options like hinting, antialiasing etc. are taken into account
 pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts);
 pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi);
 pango_layout_context_changed (layout);

 // draw pango-text to our cairo-context
 cairo_move_to (cr, text_pos_x, text_pos_y);
 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
 cairo_set_source_rgba (cr, text_color_r, text_color_g, text_color_b, text_color_a);
 pango_cairo_show_layout (cr, layout);

 // clean up
 g_object_unref (layout);
 cairo_destroy (cr);

 // now do something with the resulting surface, e.g. write to png
 cairo_surface_write_to_png (surface, "./surface.png");

 ...

 // get rid of surface after it's no longer needed
 cairo_surface_destroy (surface);

I learned all the gory details from working on notify-osd and want to share my findings with the David, Jason and the other GNOME-do developers. Providing you with the relevant C-code is probably the best solution, as I'm not very familiar with C# and Docky's code-base and you folks probably don't want to do all the needed research involved with text-rendering using PangoCairo. My guess it that with the provided information you'll be able to quickly adopt GNOME-Do/Docky to do super-slick text-rendering preserving any system-wide font-settings.