Black and blueAnd who knows which is which and who is whoUp and downAnd in the end it's only round and roundAnd round

[Announcement: The deadline for submitting Google Summer of Code proposals is about 24 hours from now. We still have not got enough strong proposals for GNOME. If you are student, if you love GNOME, go ahead and submit. There's a looong list of ideas, and you are more than welcome to submit your own ideas.]

Since Gtk+ 2.8 moved to PangoCairo, there have been a few highly dupped irritating bugs all with the same theme of hinting and off-by-one issues. Past few weeks I managed to debug and bash them all. In the chronological order here they come, with their patches:

Ironically I suggested this patch in December, but Owen said it wouldn't work AND the reporter said it didn't. It turned out this is the correct fix indeed.

pango_layout_get_pixel_extents and pango_layout_get_pixel_size cause off-by-one metrics. This one was not reported and I opened myself, but was also raised in an email thread by Morten. I suspect the fix for this may have had some of the above bugs fixed, or maybe not. Anyway, it looks more correct now. The question to answer is how to round logical and ink rectangle metrics. The current code was simply rounding x, y, width, and height. Say your rounding function is f(.). There are two problems with this:

First, f(x)+f(width) has twice the error of what you get for f(x+width). So I changed the width rounding to use (f(x+width) - f(x)) instead. Ditto for height.

Next, shall we floor, round, or ceil? It used to round them all. Now we use separate functions for logical and ink extents.

For ink rectangle, in Owen's words, the guarantee that we make is that you can render a layout onto a pixmap the size of its ink metrics and it won't get clipped. So I made it to floor x and y, and ceil x+width and y+height. The real thing looks like:

For logical rectangle, we are more interested that the rounded extents of adjacent chunks of text do not overlap or have any gaps. Which means, if x1+width1 = x2 before rounding, it should hold after rounding too. This means the same function f() should be used for x and x+width, and round() is the obvious choice here.

I also audited gdkpango.c for places that roundings can be improved, not many more candidates, but there are a lot of PANGO_PIXELS and PANGO_SCALE occurences in gtk+/gtk. They all can use a pair of eyes, replacing some of them with PANGO_PIXELS_FLOOR or PANGO_PIXELS_CEIL.

Apparently I managed to not blog for two weeks. Hopefully this rather long post broke the thin ice.

Out of the way, it's a busy day I've got things on my mind For want of the price of tea and a slice The old man died