Jason Harrop created FOP-3342:
---------------------------------

             Summary: A script's default language system is dropped when its 
table is shared with a named language system, so DejaVu Sans is never kerned 
under a default language
                 Key: FOP-3342
                 URL: https://issues.apache.org/jira/browse/FOP-3342
             Project: FOP
          Issue Type: Bug
          Components: font/opentype
    Affects Versions: 2.11
            Reporter: Jason Harrop


OTFAdvancedTypographicTableReader.readScriptTable reads a script's LangSys 
records and, for each one, compares its offset with the default LangSys offset:

{noformat}
if (dl == lo) {
    dl = 0;
    dt = lt;
}
{noformat}

When they are equal the default is not read; the script's default-language tag 
is set to that named language instead. constructLookups then registers the 
features under (script, that language) only, and nothing under (script, "dflt").

Font builders share the table on purpose. FontForge writes one LangSys table 
for the default and for every language whose feature list equals the default's, 
and it is the default LangSys offset that points at it. On this machine 252 of 
1356 installed OpenType fonts have the shape (every DejaVu face, Cousine, 
Inconsolata, Adwaita Sans among them), the GPOS table more often than GSUB 
because kerning is rarely language-specific.

What is lost depends on the font's DFLT script, where the request lands after 
the fallback:

{noformat}
DejaVu Sans, GPOS      latn default = latn/ROM = the eight Sami systems: kern 
lookups 14 and 15
                       DFLT/dflt:                                        kern 
lookup 15 only
                       Lookup 14 is the Latin class kerning (97 first glyphs); 
lookup 15
                       covers 20 glyphs and no Latin letter. So under any 
default language
                       DejaVu Sans has no Latin kerning at all.
DejaVu Serif, GPOS     latn default shared likewise, but DFLT/dflt lists the 
same lookup
                       as latn, so nothing is lost.
DejaVuLGCSerif, GPOS   (the font in FOP's own test tree) latn default = 
latn/AZE, and GPOS
                       has no DFLT script at all: no kerning under a default 
language.
{noformat}

Measured on the 2.11 command line, DejaVu Sans, kerning="true", 14pt "AVATAR To 
Ye", line width from mutool stext:

{noformat}
language="en"      99.68 pt   (falls to DFLT)
no language        99.68 pt   (script default, not found; falls to DFLT)
language="ro"      91.55 pt   (latn/ROM, which is the shared table: kerned)
language="se"      91.55 pt   (latn/NSM, likewise)
{noformat}

and on the same font loaded through FontLoader, matchLookupSpecs("latn", 
"dflt", "kern") is empty while ("latn", "ROM", "kern") is not. The 
pair-positioning subtables themselves work: performPositioning("AV", "latn", 
"ROM") gives -63/1000 em.

This is the mechanism behind "FOP does not kern DejaVu Sans", which is easy to 
misread as a PairPos format 2 problem, since the two subtables involved are 
class-based.

h3. Fix

Read the default LangSys table and register it under "dflt" whether or not a 
named record points at the same table: delete the three lines above. Nothing 
else changes; a named language sharing the table is still read under its own 
tag.

Test: SharedDefaultLanguageSystemTestCase, on the DejaVuLGCSerif already in the 
tree: matchLookupSpecs("latn", "dflt", "kern") must match, hasFeature(GPOS, 
"latn", "dflt", "kern") must be true, and performPositioning("AV", "latn", 
"dflt") must return a negative x-advance. The first assertion fails on the 
current code.

h3. Related

The lookup fallback report (FOP-3341): with the language code never translated 
and (script, dflt) never tried, a run with language="en" reaches DFLT/dflt 
whatever this report's fix does; both are needed before DejaVu Sans kerns 
through a producer that sets the language, as docx4j does.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to