Bug 48766 - Support for Font Kerning is Broken
Summary: Support for Font Kerning is Broken
Status: NEW
Alias: None
Product: Fop - Now in Jira
Classification: Unclassified
Component: fonts (show other bugs)
Version: all
Hardware: All All
: P3 normal
Target Milestone: ---
Assignee: fop-dev
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-18 14:29 UTC by Vincent Hennebert
Modified: 2012-04-07 01:52 UTC (History)
0 users



Attachments
Sample FO file showing the issue (1.57 KB, text/plain)
2010-02-18 14:34 UTC, Vincent Hennebert
Details
PDF result; the right borders should be aligned (87.40 KB, application/x-download)
2010-02-18 14:35 UTC, Vincent Hennebert
Details
Screenshot from OpenOffice Writer (9.15 KB, image/png)
2010-02-18 16:10 UTC, Jeremias Maerki
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vincent Hennebert 2010-02-18 14:29:33 UTC
The method o.a.f.fonts.Font.getKernValue expects two Unicode code points and returns the amount of kerning between the two corresponding glyphs. However, the implementation for Type 1 fonts interprets the two integers as character codes in the font's internal encoding (see o.a.f.fonts.type1.AFMFile.java). Those usually have nothing to do with Unicode code points.

Moreover, trying to get kerning between two characters is inherently wrong: kerning applies to glyphs and not characters. A font may have several glyph variants for a same character, and kerning is likely to be different for each variant.
Comment 1 Vincent Hennebert 2010-02-18 14:34:29 UTC
Created attachment 25016 [details]
Sample FO file showing the issue

This sample file uses the Nimbus Sans L font available on most Unix systems and downloadable here:
http://sourceforge.net/projects/gs-fonts/

The AFM file gives the same kerning between 'Y' and all the accented variants of the 'A' letter. Yet kerning is applied only between 'Y' and non-accented 'A'.
Comment 2 Vincent Hennebert 2010-02-18 14:35:42 UTC
Created attachment 25017 [details]
PDF result; the right borders should be aligned
Comment 3 Jeremias Maerki 2010-02-18 15:15:25 UTC
Currently, kerning only works for characters within the main single-byte encoding. The implementation uses character codes, not Unicode values, for kerning pairs. That feature didn't make the transition from a single single-byte encoding to multiple single-byte encodings. Type1Loader and especially AFMFile will probably need to be improved to support kerning for all available glyphs.
Comment 4 Vincent Hennebert 2010-02-18 15:41:09 UTC
(In reply to comment #3)
> Currently, kerning only works for characters within the main single-byte
> encoding.

No, kerning doesn't work at all. Like I said the layout engine expects Unicode code points while the font uses character codes. It's only a chance if they are the same. Basically, for Adobe Standard Encoding, only the characters (and not even all) from the Basic Latin range (U+0000–U+007F). Try “YA” vs “YÆ”, or “Fo” vs “Fø” (kerning should be the same). All in Nimbus Sans L's base encoding.


> The implementation uses character codes, not Unicode values, for
> kerning pairs. That feature didn't make the transition from a single
> single-byte encoding to multiple single-byte encodings. Type1Loader and
> especially AFMFile will probably need to be improved to support kerning for all
> available glyphs.
Comment 5 Jeremias Maerki 2010-02-18 16:10:06 UTC
Created attachment 25018 [details]
Screenshot from OpenOffice Writer

I've just tested with Nimbus Sans L (V 1.05) and kerning works just fine for those combinations for which there is data in the AFM, with PDF and PS. The AFM I have doesn't have kerning info for “YÆ” or “Fø”. Maybe you just expect characters like "A" and "Æ" to be equivalent, but I don't remember any mention in any of the Type1-related specs where it is listed which glyphs are interchangeable concerning kerning. Take "AY" and "ÆY": this combination can definitely not be the same as the font shapes are quite different.

Not even OpenOffice does this kind of kerning, not even with Arial or any other font I've checked. So IMO, it's a bit much to say it "doesn't work at all".
Comment 6 Vincent Hennebert 2010-02-19 15:23:57 UTC
(In reply to comment #5)
> Created an attachment (id=25018) [details]
> Screenshot from OpenOffice Writer
> 
> I've just tested with Nimbus Sans L (V 1.05) and kerning works just fine for
> those combinations for which there is data in the AFM, with PDF and PS. The AFM
> I have doesn't have kerning info for “YÆ” or “Fø”.

Then please download the font from the link above.


> Maybe you just expect
> characters like "A" and "Æ" to be equivalent, but I don't remember any mention
> in any of the Type1-related specs where it is listed which glyphs are
> interchangeable concerning kerning. Take "AY" and "ÆY": this combination can
> definitely not be the same as the font shapes are quite different.
> 
> Not even OpenOffice does this kind of kerning, not even with Arial or any other
> font I've checked. So IMO, it's a bit much to say it "doesn't work at all".

So where is the code that makes the conversion between Unicode code points as provided by the layout engine and the character codes as stored in the font's kerning map?
Comment 7 Jeremias Maerki 2010-02-19 15:48:02 UTC
Ah, I see, they added many more kerning pairs from version 1.05 to 1.06 of Nimbus Sans L.

The code that builds the kerning map from the AFM file is AFMFile.createXKerningMapEncoded(). So, as mentioned before, the problem is that this method is only aware of the primary single-byte encoding. I can't deal with the supplemental encodings in which characters like "Æ" will be found. You can see how the character codes are derived from the multiple encodings in SingleByteFont.mapChar()/mapUnencodedChar(). Maybe it makes sense to just keep the kerning pairs with their glyph names (rather than building the map based on character codes) and store the whole map in SingleByteFont. But that may also be a bit slower. HTH
Comment 8 Glenn Adams 2012-04-07 01:44:44 UTC
resetting P2 open bugs to P3 pending further review