[HarfBuzz] Should MarkToBase attachment zero the mark advance?
behdad at behdad.org
Wed Sep 15 11:54:32 PDT 2010
On 08/23/10 13:46, Jonathan Kew wrote:
> Hi Behdad,
> I notice that the code in MarkArray::apply() includes the following:
> hb_internal_glyph_position_t &o = c->buffer->pos[c->buffer->i];
> o.x_advance = 0;
> o.y_advance = 0;
> o.x_offset = base_x - mark_x;
> o.y_offset = base_y - mark_y;
> o.back = c->buffer->i - glyph_pos;
> i.e. in addition to setting x_offset and y_offset so as to position the mark glyph, it also explicitly overrides any existing x_advance and y_advance values for the glyph, settings them to zero. In many cases, this is harmless (though redundant), as mark glyphs are typically designed with zero advance anyway.
> However, I'm seeing problems in several monospaced fonts as a result of this; an example is DejaVuSansMono.ttf. Here, the mark glyphs have the same (non-zero) advance as the rest of the glyphs -- logical, I suppose, for a fixed-width font. There is a GPOS 'mark' feature that positions diacritics such as the U+03xx range. The trouble is that this feature actually executes TWO lookups for these glyphs: first, it does a MarkToBase Attachment (type 4), to place the diacritic over the base glyph, AND THEN it does a Single Adjustment that modifies the advance of the diacritic glyph by the negative of its original advance. This is clearly intended to make it become zero-width; but because harfbuzz has already zeroed the advance, it now ends up with a NEGATIVE advance, and the result is that the next glyph completely overprints the accented character.
> So unless you know of specific reasons why it is necessary to zero the x_advance and y_advance values here (are there examples of fonts where the rendering is incorrect without this?), I'd suggest removing those two lines, as in the attached patch.
> With that change, I'm getting the expected rendering with DejaVuSansMono. (The same issue occurs with the Consolas font on Windows7, for example.)
I see how Pango was working previously... Interesting. What Pango did before
was that in MarkArray::apply() it's set a flag which would mean "zero the
advance", and check for the flag when all GPOS is done, in effect, not
accumulating the further adjustments.
I thought carried the logic forward, but obviously have broken it in the way
you found. I do want to do a quick survey of popular fonts before I fix that
though. I'll try to do that soonish, but it's not trivial. We're interested
in fonts that have a GPOS table, but have mark glyphs with non-zero advance.
Conceptually I think the code as is makes a lot of sense, but if that's not
how Uniscribe works, well...
More information about the HarfBuzz