OtlTags::language() (src/Shaper/OtlTags.php, upstream Otl::_getOTLLangTag() at src/Otl.php:6150) looks a tag up by its first subtag in Ucdn::$ot_languages. After #201 Chinese is the one exception. HarfBuzz 14.3.1 also maps several multi-subtag tags to a language system the first subtag doesn't give. They come from hb_ot_tags_from_complex_language() and the extended-language rule in hb_ot_tags_from_language():
- Variants and scripts that apply to any language (
hb-ot-tag-table.hh:1627-1689): -polyton → PGR, -provenc → PRO, -fonipa → IPPH, -fonnapa → APPH, -geok → KGE, -syre/-syrj/-syrn → SYRE/SYRJ/SYRN.
- Language and script or region:
ga-Latg → IRT (:2252), mnw-TH → MONT (:2651), ro-MD → MOL then ROM (:2741).
- Chinese languages other than
zh: cmn, yue, nan, hak, wuu, lzh, gan, hsn and a dozen more have no key in Ucdn::$ot_languages. HarfBuzz maps each to ZHS, except yue → ZHH and lzh → ZHT (:517-1141). It also gives each one the same script and region rules as zh (e.g. yue-Hans → ZHS, cmn-Hant-TW → ZHT).
- Extended language subtags (
hb-ot-tag.cc, hb_ot_tags_from_language()): where the second subtag is three letters, HarfBuzz looks that up instead, so zh-yue → ZHH and zh-lzh → ZHT.
- More than one tag for a language: the two-letter table lists
ga → IRI, IRT and nv → NAV, ATH. HarfBuzz tries each in turn, and Ucdn has only the first.
I measured each case below with a font whose script offers only HarfBuzz's tag, with a locl lookup under it. hb-shape --language selected that tag in every case. mPDF is OtlTags::language($lang, …) with every tag offered:
lang |
mPDF |
HarfBuzz |
el-polyton |
ELL |
PGR |
ga-Latg |
IRI |
IRT |
ro-MD |
ROM |
MOL |
mnw-TH |
MON |
MONT |
oc-provenc |
OCI |
PRO |
syr-Syre |
SYR |
SYRE |
en-fonipa |
DFLT |
IPPH |
ka-Geok |
DFLT |
KGE |
yue, yue-Hant-HK |
DFLT |
ZHH |
cmn-Hans |
DFLT |
ZHS |
lzh |
DFLT |
ZHT |
zh-yue |
ZHS |
ZHH |
zh-lzh |
ZHS |
ZHT |
Expected: follow HarfBuzz for these. #201 adds the ordered-candidates shape (ZHTM then ZHH) that ro-MD and the multi-tag languages need.
Found while fixing #201, which covers only zh.
OtlTags::language()(src/Shaper/OtlTags.php, upstreamOtl::_getOTLLangTag()atsrc/Otl.php:6150) looks a tag up by its first subtag inUcdn::$ot_languages. After #201 Chinese is the one exception. HarfBuzz 14.3.1 also maps several multi-subtag tags to a language system the first subtag doesn't give. They come fromhb_ot_tags_from_complex_language()and the extended-language rule inhb_ot_tags_from_language():hb-ot-tag-table.hh:1627-1689):-polyton→PGR,-provenc→PRO,-fonipa→IPPH,-fonnapa→APPH,-geok→KGE,-syre/-syrj/-syrn→SYRE/SYRJ/SYRN.ga-Latg→IRT(:2252),mnw-TH→MONT(:2651),ro-MD→MOLthenROM(:2741).zh:cmn,yue,nan,hak,wuu,lzh,gan,hsnand a dozen more have no key inUcdn::$ot_languages. HarfBuzz maps each toZHS, exceptyue→ZHHandlzh→ZHT(:517-1141). It also gives each one the same script and region rules aszh(e.g.yue-Hans→ZHS,cmn-Hant-TW→ZHT).hb-ot-tag.cc,hb_ot_tags_from_language()): where the second subtag is three letters, HarfBuzz looks that up instead, sozh-yue→ZHHandzh-lzh→ZHT.ga→IRI,IRTandnv→NAV,ATH. HarfBuzz tries each in turn, andUcdnhas only the first.I measured each case below with a font whose script offers only HarfBuzz's tag, with a
locllookup under it.hb-shape --languageselected that tag in every case. mPDF isOtlTags::language($lang, …)with every tag offered:langel-polytonELLPGRga-LatgIRIIRTro-MDROMMOLmnw-THMONMONToc-provencOCIPROsyr-SyreSYRSYREen-fonipaDFLTIPPHka-GeokDFLTKGEyue,yue-Hant-HKDFLTZHHcmn-HansDFLTZHSlzhDFLTZHTzh-yueZHSZHHzh-lzhZHSZHTExpected: follow HarfBuzz for these. #201 adds the ordered-candidates shape (
ZHTMthenZHH) thatro-MDand the multi-tag languages need.Found while fixing #201, which covers only
zh.