Do

GNOME-Do does not render fonts using system DPI setting

Bug #323271 reported by ShackJack on 2009-01-30
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Do
Low
Unassigned

Bug Description

Gnome-Do defaults to its own DPI setting (96 DPI?) and will not render using the DPI set for system if it is different. For example GNOME-Do will render fonts much smaller for systems set with 128DPI as shown in the example screenshot.

i confirm this with 0.8 release
Do uses its own dpi

Changed in do:
status: New → Confirmed
Robert Dyer (psybers) on 2009-06-18
Changed in do:
importance: Undecided → Low
Mirco Müller (macslow) wrote :
Download full text (4.0 KiB)

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);
 pang...

Read more...

Mirco Müller (macslow) wrote :

Hm... looking through Docky's sources I guess that the code doing all the text-rendering is TextPathAtPoint located at ./do/Do.Interface.Linux.Docky/src/Docky.Interface/DrawingService.cs:57. Since that uses Pango.CairoHelper.LayoutPath (C#-variant of pango_cairo_layout_path) it is currently not possible to make use of the technique presented in my last comment above (the one just before this here).

Why is it using Pango.CairoHelper.LayoutPath() and not Pango.CairoHelper.ShowLayout()? Is there any special implementation reason for that? Why does it have to be rendered via a path (and later filled) instead of doing the more direct painting-operation-like ShowLayout()? DBO, any input you can provide to enlighten me about your implementation-decision here?

Looking through the C#/Mono documentation of the Cairo- and Pango-bindings, I came to this code-snippet doing the main beef for getting font-rendering preserving system-wide text-rendering-options:

 ...
 // pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts);
 Pango.CairoHelper.??? (layout.Context, ReferenceWidget.Screen.FontOptions);
 // pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi);
 Pango.CairoHelper.ContextSetResolution (layout.Context, ReferenceWidget.Screen.Resolution);
 // pango_layout_context_changed (layout);
 layout.ContextChanged ();
 ...
 cr.MoveTo (x, y);
 Pango.CairoHelper.ShowLayout (cr, layout);
 ...

This is assuming we have a ShowLayout-based text-rendering in Docky of course. As you see I've not been able to find a C#-equivalent for pango_cairo_context_set_font_options() yet. Any help is appreciated.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers