During my vacation I have been fixing some bugs in Planner, hoping to strike a few things off of my todo list for a change.
One of those things is support for the GTK+ printing API. Francisco Moraes implemented most of this already, but it needed some final touches: a property page allowing you to select what to print, a few minor changes in the layout and the removal of some magic numbers.
Most of these things I completed already a while ago, but there were a few problems with font sizes that I could not quite get a handle on. Francisco was aware of the issue when he was working on GTK+ printing support, but did not find a solution.
The problematic piece of code is in src/planner-print-job.c in the function planner_print_job_get_extents(). As you can see the current font description is set in the layout, a text string is also set and then the pango_layout_get_extents() function is used to get the dimensions of the rendered string. Unfortunately the width returned is about twice what you would expect.

When I got to work on GTK+ printing I saw the same thing; no matter what string I used, the (horizontal) size was always roughly double what I expected. As I’m no expert in pango and font stuff and because planner does not use the vertical size, I only had an estimate for what the horizontal size should be. It determined the width of columns and I could see they were about twice as wide as they needed to be for their content.
Then I thought, maybe it’s using the wrong font. So I searched for where current_font was assigned a value. I found it in planner_print_job_set_font_regular(), planner_print_job_set_font_bold() and planner_print_job_set_font_italic(), all of them in src/planner-print-job.c. They set priv->current_font to either priv->font or priv->bold_font. (I guess the italic function is not used =) ).
So now I wanted to know what priv->bold_font and priv->font were set to. Searching for them showed that they are assigned their value in planner_print_job_new(). In this function the font descriptions are created from a string like “Sans Regular 6″.
If these are the fonts used, then changing “Sans Regular 6″ to “Sans Regular 18″ should have an effect on the width returned by pango_layout_get_extents(), right?
Yes, it _should_ indeed, but it doesn’t. Instead it kept giving me the same width.
I suppose that could happen if the planner_print_job_set_font_* functions were not called, so let’s see what the font IS set to. I used pango_font_description_to_string() for that. Guess what?
(planner:25972): Pango-CRITICAL **: pango_font_description_to_string: assertion `desc != NULL' failed Determining extents with font: '(null)'
Oops! It turns out that planner_print_job_get_extents() is already called a couple of times before the first call to planner_print_job_set_font_*().
In order to find out where to add calls to planner_print_job_set_font_*(), I will look at where planner_print_job_get_extents() is called and go from there.
Adding a g_print() statement just before each call to planner_print_job_get_extents() that prints the name of the calling function gives me this:
print_job_begin_print (planner:27322): Pango-CRITICAL **: pango_font_description_to_string: assertion `desc != NULL' failed Determining extents with font: '(null)' planner_gantt_print_data_new 1 (planner:27322): Pango-CRITICAL **: pango_font_description_to_string: assertion `desc != NULL' failed Determining extents with font: '(null)' planner_gantt_print_data_new 2 (planner:27322): Pango-CRITICAL **: pango_font_description_to_string: assertion `desc != NULL' failed Determining extents with font: '(null)' planner_gantt_print_data_new 3 (planner:27322): Pango-CRITICAL **: pango_font_description_to_string: assertion `desc != NULL' failed Determining extents with font: '(null)' planner_print_job_set_font_regular planner_print_job_set_font_regular planner_print_job_set_font_bold planner_print_job_set_font_regular
Now let’s see if there’s a common parent function of all of these.
The ones with a number behind them are all from the planner_gantt_print_data_new function. A little grepping shows that this function is called from gantt_view_print_init(), which is set as the print_init function for the PlannerViewClass in src/planner-view.h. print_job_begin_print() in src/planner-print-job.c loops through planner’s views (gantt, task, resource usage) and calls print_init for each of them. Lucky for me this is also the function that makes the one call to planner_print_job_get_extents() that I did not yet cover. In other words, the perfect place to insert our call to planner_print_job_set_font_regular().
That concludes the overview of this debugging session.
I just checked in the the changes discussed in this post, so Planner now finally uses GTK+ printing instead of the old libgnomeprint. This should fix a bunch of long-standing problems people were having with printing on Windows. That is, if your GTK+ installation is recent enough.