diff --git a/src/Shaper/OtlTags.php b/src/Shaper/OtlTags.php
index 4d08247e9..1d86972aa 100644
--- a/src/Shaper/OtlTags.php
+++ b/src/Shaper/OtlTags.php
@@ -99,11 +99,12 @@ public static function language($ietf, $available)
$country = strtolower($tags[2]);
}
+ $region = $lang . '-' . $country;
+
if ($lang != '' && isset(Ucdn::$ot_languages[$lang])) {
$langsys = Ucdn::$ot_languages[$lang];
- } elseif ($lang != '' && $country != '' && isset(Ucdn::$ot_languages[$lang . $country])) {
- // Never matches: the region keys are written 'zh-hk' (#191)
- $langsys = Ucdn::$ot_languages[$lang . $country];
+ } elseif ($lang != '' && $country != '' && isset(Ucdn::$ot_languages[$region])) {
+ $langsys = Ucdn::$ot_languages[$region];
} else {
$langsys = 'DFLT';
}
diff --git a/tests/Mpdf/ChineseRegionLangSysTest.php b/tests/Mpdf/ChineseRegionLangSysTest.php
new file mode 100644
index 000000000..be97538a8
--- /dev/null
+++ b/tests/Mpdf/ChineseRegionLangSysTest.php
@@ -0,0 +1,55 @@
+ ['zh-HK', self::ZHH],
+ 'zh-TW' => ['zh-TW', self::ZHT],
+ 'zh-CN' => ['zh-CN', self::ZHS],
+ ];
+ }
+
+ /**
+ * @dataProvider regions
+ */
+ public function testTheRegionSelectsTheLanguageSystem($lang, $expected)
+ {
+ $mpdf = new TextRecordingMpdf([
+ 'mode' => 'utf-8',
+ 'fontDir' => [__DIR__ . '/../data/ttf'],
+ 'fontdata' => ['notosanstcregionlangsyssynthetic' => [
+ 'R' => 'NotoSansTC-RegionLangSys-Synthetic.ttf',
+ 'useOTL' => 0xFF,
+ ]],
+ 'default_font' => 'notosanstcregionlangsyssynthetic',
+ ]);
+ $mpdf->WriteHTML(sprintf('
%04X;
', $lang, self::BONE));
+
+ $drawn = array_values(unpack('N*', mb_convert_encoding($mpdf->drawnText[0], 'UTF-32BE', 'UTF-8')));
+
+ $this->assertSame([$expected], $drawn);
+ }
+
+}
diff --git a/tests/Mpdf/Shaper/OtlTagsTest.php b/tests/Mpdf/Shaper/OtlTagsTest.php
index 3120bc8cc..a421cb2fd 100644
--- a/tests/Mpdf/Shaper/OtlTagsTest.php
+++ b/tests/Mpdf/Shaper/OtlTagsTest.php
@@ -123,4 +123,37 @@ public function languages()
];
}
+ /**
+ * @dataProvider chineseRegions
+ */
+ public function testAChineseRegionSelectsItsLanguageSystem($ietf, $expected)
+ {
+ $this->assertSame($expected, OtlTags::language($ietf, 'DFLT ZHH ZHS ZHT '));
+ }
+
+ public function chineseRegions()
+ {
+ return [
+ 'Hong Kong' => ['zh-HK', 'ZHH '],
+ 'Hong Kong, after the script' => ['zh-Hant-HK', 'ZHH '],
+ 'Taiwan' => ['zh-TW', 'ZHT '],
+ 'Macao' => ['zh-MO', 'ZHT '],
+ 'China' => ['zh-CN', 'ZHS '],
+ 'Singapore' => ['zh-SG', 'ZHS '],
+ 'lower case' => ['zh-tw', 'ZHT '],
+ 'a region the table has no entry for' => ['zh-US', 'DFLT'],
+ ];
+ }
+
+ /**
+ * Pins #201 as it stands: without a region, Chinese has no language system, where HarfBuzz
+ * takes ZHS for zh and zh-Hans and ZHT for zh-Hant.
+ */
+ public function testChineseWithoutARegionHasNoLanguageSystem()
+ {
+ $this->assertSame('DFLT', OtlTags::language('zh', 'DFLT ZHH ZHS ZHT '));
+ $this->assertSame('DFLT', OtlTags::language('zh-Hant', 'DFLT ZHH ZHS ZHT '));
+ $this->assertSame('DFLT', OtlTags::language('zh-Hans', 'DFLT ZHH ZHS ZHT '));
+ }
+
}
diff --git a/tests/data/fontcache/NotoSansTC-RegionLangSys-Synthetic.json b/tests/data/fontcache/NotoSansTC-RegionLangSys-Synthetic.json
new file mode 100644
index 000000000..8ddbee6f7
--- /dev/null
+++ b/tests/data/fontcache/NotoSansTC-RegionLangSys-Synthetic.json
@@ -0,0 +1,92 @@
+{
+ "_": "Generated by composer fontcache:update. See tests/Mpdf/Fonts/ParserGoldenMaster.php.",
+ "fullName": "NotoSansTC-RegionLangSys-Synthetic",
+ "mtx": {
+ "GSUBScriptLang": {
+ "hani": "DFLT ZHH ZHS ZHT "
+ },
+ "GSUBFeatures": {
+ "hani": {
+ "ZHH ": {
+ "locl": [
+ 0
+ ]
+ },
+ "ZHS ": {
+ "locl": [
+ 1
+ ]
+ },
+ "ZHT ": {
+ "locl": [
+ 2
+ ]
+ }
+ }
+ },
+ "GSUBLookups": [
+ {
+ "Type": 1,
+ "Flag": 0,
+ "SubtableCount": 1,
+ "Subtables": [
+ 124
+ ],
+ "MarkFilteringSet": ""
+ },
+ {
+ "Type": 1,
+ "Flag": 0,
+ "SubtableCount": 1,
+ "Subtables": [
+ 138
+ ],
+ "MarkFilteringSet": ""
+ },
+ {
+ "Type": 1,
+ "Flag": 0,
+ "SubtableCount": 1,
+ "Subtables": [
+ 152
+ ],
+ "MarkFilteringSet": ""
+ }
+ ],
+ "GPOSScriptLang": [],
+ "GPOSFeatures": [],
+ "GPOSLookups": [],
+ "MarkGlyphSets": [],
+ "rtlPUAstr": "",
+ "haskernGPOS": false,
+ "hassmallcapsGSUB": false
+ },
+ "cache": {
+ "GDEFdata.json": {
+ "GlyphClassBases": " 04E00| 04E09| 04E8C| 09AA8",
+ "GlyphClassMarks": "",
+ "GlyphClassLigatures": "",
+ "GlyphClassComponents": "",
+ "MarkGlyphSets": [],
+ "MarkAttachmentType": []
+ },
+ "GSUB.dat": "164 bytes, sha256 806298eba96771ffa947e91279efff39c5b091473cd2d52e8caf0c74bf95a2a0",
+ "GSUBdata.json": [
+ [
+ {
+ "39592": 0
+ }
+ ],
+ [
+ {
+ "39592": 0
+ }
+ ],
+ [
+ {
+ "39592": 0
+ }
+ ]
+ ]
+ }
+}
diff --git a/tests/data/otldump/NotoSansTC-RegionLangSys-Synthetic.txt b/tests/data/otldump/NotoSansTC-RegionLangSys-Synthetic.txt
new file mode 100644
index 000000000..194dc7412
--- /dev/null
+++ b/tests/data/otldump/NotoSansTC-RegionLangSys-Synthetic.txt
@@ -0,0 +1,17 @@
+GDEF table
+Glyph classes
+Glyph class 1
+Base glyph (single character, spacing glyph)
+一 三 二 骨
+GSUB Tables
+GSUB Scripts & Languages
+
+GPOS table not defined
+
+=== detail: script hani language DFLT ===
+GSUB Tables
+This font's GSUB script "hani" offers no language system "DFLT". It has: ZHH, ZHS, ZHT
+
+GPOS table not defined
diff --git a/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt b/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt
new file mode 100644
index 000000000..ad76bec74
--- /dev/null
+++ b/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt
@@ -0,0 +1,92 @@
+=== latin ===
+0xFF 0041 0056 0041 0054 0061 0072 => 0041 0056 0041 0054 0061 0072 group=CCCCCC
+0x80 0041 0056 0041 0054 0061 0072 => 0041 0056 0041 0054 0061 0072 group=CCCCCC
+0xFF +kern -liga 0041 0056 0041 0054 0061 0072 => 0041 0056 0041 0054 0061 0072 group=CCCCCC
+=== cyrillic ===
+0xFF 0416 0430 0439 => 0416 0430 0439 group=CCC
+0x80 0416 0430 0439 => 0416 0430 0439 group=CCC
+0xFF +kern -liga 0416 0430 0439 => 0416 0430 0439 group=CCC
+=== greek ===
+0xFF 03B1 03B2 03C2 => 03B1 03B2 03C2 group=CCC
+0x80 03B1 03B2 03C2 => 03B1 03B2 03C2 group=CCC
+0xFF +kern -liga 03B1 03B2 03C2 => 03B1 03B2 03C2 group=CCC
+=== hiragana ===
+0xFF 3042 3043 3044 => 3042 3043 3044 group=CCC
+0x80 3042 3043 3044 => 3042 3043 3044 group=CCC
+0xFF +kern -liga 3042 3043 3044 => 3042 3043 3044 group=CCC
+=== arabic ===
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC
+=== syriac ===
+0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
+0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
+0xFF +kern -liga 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
+=== nko ===
+0xFF 07CA 07CB 07CC => 07CA 07CB 07CC group=CCC
+0x80 07CA 07CB 07CC => 07CA 07CB 07CC group=CCC
+0xFF +kern -liga 07CA 07CB 07CC => 07CA 07CB 07CC group=CCC
+=== devanagari ===
+0xFF 0915 094D 0937 093F => 0915 094D 0937 093F group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 0937 093F group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 0937 093F group=CCCC
+=== bengali ===
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09B7 09BF group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09B7 09BF group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09B7 09BF group=CCCC
+=== gurmukhi ===
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A38 0A3F group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A38 0A3F group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A38 0A3F group=CCCC
+=== tamil ===
+0xFF 0B95 0BCD 0BB7 0BBF => 0B95 0BCD 0BB7 0BBF group=CCCC
+0x80 0B95 0BCD 0BB7 0BBF => 0B95 0BCD 0BB7 0BBF group=CCCC
+0xFF +kern -liga 0B95 0BCD 0BB7 0BBF => 0B95 0BCD 0BB7 0BBF group=CCCC
+=== malayalam ===
+0xFF 0D15 0D4D 0D37 0D3F => 0D15 0D4D 0D37 0D3F group=CCCC
+0x80 0D15 0D4D 0D37 0D3F => 0D15 0D4D 0D37 0D3F group=CCCC
+0xFF +kern -liga 0D15 0D4D 0D37 0D3F => 0D15 0D4D 0D37 0D3F group=CCCC
+=== sinhala ===
+0xFF 0D9A 0DCA 0DBB 0DBB => 0D9A 0DCA 0DBB 0DBB group=CCCC
+0x80 0D9A 0DCA 0DBB 0DBB => 0D9A 0DCA 0DBB 0DBB group=CCCC
+0xFF +kern -liga 0D9A 0DCA 0DBB 0DBB => 0D9A 0DCA 0DBB 0DBB group=CCCC
+=== khmer ===
+0xFF 1780 17D2 1781 17C1 => 1780 17D2 1781 17C1 group=CCCC
+0x80 1780 17D2 1781 17C1 => 1780 17D2 1781 17C1 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 1780 17D2 1781 17C1 group=CCCC
+=== thai ===
+0xFF 0E01 0E34 0E48 0E23 => 0E01 0E34 0E48 0E23 group=CCCC
+0x80 0E01 0E34 0E48 0E23 => 0E01 0E34 0E48 0E23 group=CCCC
+0xFF +kern -liga 0E01 0E34 0E48 0E23 => 0E01 0E34 0E48 0E23 group=CCCC
+=== lao ===
+0xFF 0E81 0EB4 0E8D => 0E81 0EB4 0E8D group=CCC
+0x80 0E81 0EB4 0E8D => 0E81 0EB4 0E8D group=CCC
+0xFF +kern -liga 0E81 0EB4 0E8D => 0E81 0EB4 0E8D group=CCC
+=== myanmar ===
+0xFF 1000 103A 1039 1001 => 1000 103A 1039 1001 group=CCCC
+0x80 1000 103A 1039 1001 => 1000 103A 1039 1001 group=CCCC
+0xFF +kern -liga 1000 103A 1039 1001 => 1000 103A 1039 1001 group=CCCC
+=== new tai lue ===
+0xFF 1980 19B0 1981 => 1980 19B0 1981 group=CCC
+0x80 1980 19B0 1981 => 1980 19B0 1981 group=CCC
+0xFF +kern -liga 1980 19B0 1981 => 1980 19B0 1981 group=CCC
+=== cham ===
+0xFF AA00 AA33 AA01 => AA00 AA33 AA01 group=CCC
+0x80 AA00 AA33 AA01 => AA00 AA33 AA01 group=CCC
+0xFF +kern -liga AA00 AA33 AA01 => AA00 AA33 AA01 group=CCC
+=== tai tham ===
+0xFF 1A20 1A60 1A21 => 1A20 1A60 1A21 group=CCC
+0x80 1A20 1A60 1A21 => 1A20 1A60 1A21 group=CCC
+0xFF +kern -liga 1A20 1A60 1A21 => 1A20 1A60 1A21 group=CCC
+=== mixed scripts ===
+0xFF 0041 0628 0915 0042 => 0041 0628 0915 0042 group=CCCC
+0x80 0041 0628 0915 0042 => 0041 0628 0915 0042 group=CCCC
+0xFF +kern -liga 0041 0628 0915 0042 => 0041 0628 0915 0042 group=CCCC
+=== spaced ===
+0xFF 0041 0020 0628 0020 0042 => 0041 0020 0628 0020 0042 group=CSCSC
+0x80 0041 0020 0628 0020 0042 => 0041 0020 0628 0020 0042 group=CSCSC
+0xFF +kern -liga 0041 0020 0628 0020 0042 => 0041 0020 0628 0020 0042 group=CSCSC
+=== font characters 0 ===
+0xFF 0020 4E00 4E09 4E8C 9AA8 => 0020 4E00 4E09 4E8C 9AA8 group=SCCCC
+0x80 0020 4E00 4E09 4E8C 9AA8 => 0020 4E00 4E09 4E8C 9AA8 group=SCCCC
+0xFF +kern -liga 0020 4E00 4E09 4E8C 9AA8 => 0020 4E00 4E09 4E8C 9AA8 group=SCCCC
diff --git a/tests/data/subset/NotoSansTC-RegionLangSys-Synthetic.json b/tests/data/subset/NotoSansTC-RegionLangSys-Synthetic.json
new file mode 100644
index 000000000..5946e1a04
--- /dev/null
+++ b/tests/data/subset/NotoSansTC-RegionLangSys-Synthetic.json
@@ -0,0 +1,123 @@
+{
+ "_": "Generated by composer subset:update. See tests/Mpdf/Fonts/SubsetGoldenMaster.php.",
+ "useOTL=0x00": {
+ "characters": 6,
+ "makeSubset": {
+ "bytes": 1664,
+ "sha256": "a1abcfed401e3fbadad0a4d06b5c89cba642e450b0e345d7af41bd332f9eecf5",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x553CF586, sha256 4feb4a7666c967ad3bedc80ca0480d43b41a41ffe07c31028a6ef52218d38859",
+ "cmap": "100 bytes, checksum 0x506935CE, sha256 617bb8af96e99dca7a32eb0759763fceba3a5e07a1ced67d44c6ef500e154263",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "456 bytes, checksum 0xA597EF24, sha256 fc281ecb0dd8d40dfcf54cc27fea6f485a3ce29b31ad44a858037941a97e99ab",
+ "head": "54 bytes, checksum 0x26853AD1, sha256 45d88851434214798d0d8b28231c529a7605d9ea1bd550274e60e9d68585adc0",
+ "hhea": "36 bytes, checksum 0x087602F7, sha256 b77957ff705ba9eb769b43f6e686e2652d488fd9997e2bb142f0a393a164f499",
+ "hmtx": "24 bytes, checksum 0x14680159, sha256 2f03ee1162e724d677550e1eff1b811c49271a8317e699eb03cc6f7e93232863",
+ "loca": "14 bytes, checksum 0x016600D0, sha256 d3868833ca7cd5facd47d789fdfa8e947052e749acd0ed29963710cf0d6c9ff8",
+ "maxp": "32 bytes, checksum 0x000F0051, sha256 277ce9daa2e509e2027ecde2a2ace2ebfb7456a1a4649389f6c4c6b477d40007",
+ "name": "618 bytes, checksum 0x32424A7A, sha256 843256959a3f193a9c9b4b1991e6342af742cf0658dae6febbf7dfacf3c50595",
+ "post": "32 bytes, checksum 0xFF860032, sha256 22dd499f08932214bde96943f3882f3619324478217095c049b68a57c6c10693"
+ },
+ "maxUni": 65535,
+ "defaultWidth": 1000,
+ "codeToGlyph": "6 entries, sha256 249e8ea21e7631ac3f0c3cb3635abb85a5fa6606b6c9c93af3943ffe458bc252"
+ },
+ "makeSubsetSIP": {
+ "bytes": 1648,
+ "sha256": "0cc56fb4c1c1c9680f3dde8cf88cf9da35d5af339f0c44a71976e9abc4b92230",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x5910D1E4, sha256 6f8275c184ad73eed089c9ae3dab631cdca809361b253ce8f23e4bf592ce780d",
+ "cmap": "82 bytes, checksum 0x00420076, sha256 f6d9593a66846b174499232d5c653827aca29fb4afa95c9d48a8b1a05f33bb84",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "456 bytes, checksum 0xA597EF24, sha256 fc281ecb0dd8d40dfcf54cc27fea6f485a3ce29b31ad44a858037941a97e99ab",
+ "head": "54 bytes, checksum 0x26853AD1, sha256 bb97a5e85cf7f4157a7389f729781b0ccf97c4ce78c1c64f078108df0d7f2ede",
+ "hhea": "36 bytes, checksum 0x087602F7, sha256 b77957ff705ba9eb769b43f6e686e2652d488fd9997e2bb142f0a393a164f499",
+ "hmtx": "24 bytes, checksum 0x14680159, sha256 2f03ee1162e724d677550e1eff1b811c49271a8317e699eb03cc6f7e93232863",
+ "loca": "14 bytes, checksum 0x016600D0, sha256 d3868833ca7cd5facd47d789fdfa8e947052e749acd0ed29963710cf0d6c9ff8",
+ "maxp": "32 bytes, checksum 0x000F0051, sha256 277ce9daa2e509e2027ecde2a2ace2ebfb7456a1a4649389f6c4c6b477d40007",
+ "name": "618 bytes, checksum 0x323B4A7A, sha256 1c9f67517afb47c153afb54af026607704646d2f3e3908c8e0bdf007f288f974",
+ "post": "32 bytes, checksum 0xFF860032, sha256 22dd499f08932214bde96943f3882f3619324478217095c049b68a57c6c10693"
+ },
+ "maxUniChar": 65535,
+ "defaultWidth": 1000
+ },
+ "repackageTTF": {
+ "bytes": 1640,
+ "sha256": "f371f741569fcf26d365f58f366cedd2ed2a1d4193f97e39821c56f29877a52b",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x553CF586, sha256 4feb4a7666c967ad3bedc80ca0480d43b41a41ffe07c31028a6ef52218d38859",
+ "cmap": "84 bytes, checksum 0x9CAAE953, sha256 7099224c1a20cbdb0864041864d44a0fe6956d49b0759c97206a25d1b121f722",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "450 bytes, checksum 0x9F9AF520, sha256 8a6a9e3195830fdde21cc912fe50b04e40ef1b07d484fa55dfc90f061eeea27d",
+ "head": "54 bytes, checksum 0x26853AD1, sha256 085f676512d6f2f026e236b323e322ea539b32a88c026fae06545be7fce0f011",
+ "hhea": "36 bytes, checksum 0x087602F4, sha256 3b8df10855749dc2b94ca33deacd41aa368f250bd21bfe9561090e4dece3ed54",
+ "hmtx": "18 bytes, checksum 0x094000C9, sha256 d6dcf7d9a71a1793b58afdde15a319c3308777bb8a77dcb1561617fcdb87c4b6",
+ "loca": "14 bytes, checksum 0x015F00CA, sha256 2190e466db26bc483532782d3ea3b3fda85f12db1ef10acfa41e2aff62e640d8",
+ "maxp": "32 bytes, checksum 0x000F0051, sha256 277ce9daa2e509e2027ecde2a2ace2ebfb7456a1a4649389f6c4c6b477d40007",
+ "name": "618 bytes, checksum 0x32424A7A, sha256 843256959a3f193a9c9b4b1991e6342af742cf0658dae6febbf7dfacf3c50595",
+ "post": "32 bytes, checksum 0xFF860032, sha256 22dd499f08932214bde96943f3882f3619324478217095c049b68a57c6c10693"
+ },
+ "maxUni": 0
+ }
+ },
+ "useOTL=0xFF": {
+ "characters": 6,
+ "makeSubset": {
+ "bytes": 1664,
+ "sha256": "a1abcfed401e3fbadad0a4d06b5c89cba642e450b0e345d7af41bd332f9eecf5",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x553CF586, sha256 4feb4a7666c967ad3bedc80ca0480d43b41a41ffe07c31028a6ef52218d38859",
+ "cmap": "100 bytes, checksum 0x506935CE, sha256 617bb8af96e99dca7a32eb0759763fceba3a5e07a1ced67d44c6ef500e154263",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "456 bytes, checksum 0xA597EF24, sha256 fc281ecb0dd8d40dfcf54cc27fea6f485a3ce29b31ad44a858037941a97e99ab",
+ "head": "54 bytes, checksum 0x26853AD1, sha256 45d88851434214798d0d8b28231c529a7605d9ea1bd550274e60e9d68585adc0",
+ "hhea": "36 bytes, checksum 0x087602F7, sha256 b77957ff705ba9eb769b43f6e686e2652d488fd9997e2bb142f0a393a164f499",
+ "hmtx": "24 bytes, checksum 0x14680159, sha256 2f03ee1162e724d677550e1eff1b811c49271a8317e699eb03cc6f7e93232863",
+ "loca": "14 bytes, checksum 0x016600D0, sha256 d3868833ca7cd5facd47d789fdfa8e947052e749acd0ed29963710cf0d6c9ff8",
+ "maxp": "32 bytes, checksum 0x000F0051, sha256 277ce9daa2e509e2027ecde2a2ace2ebfb7456a1a4649389f6c4c6b477d40007",
+ "name": "618 bytes, checksum 0x32424A7A, sha256 843256959a3f193a9c9b4b1991e6342af742cf0658dae6febbf7dfacf3c50595",
+ "post": "32 bytes, checksum 0xFF860032, sha256 22dd499f08932214bde96943f3882f3619324478217095c049b68a57c6c10693"
+ },
+ "maxUni": 65535,
+ "defaultWidth": 1000,
+ "codeToGlyph": "6 entries, sha256 249e8ea21e7631ac3f0c3cb3635abb85a5fa6606b6c9c93af3943ffe458bc252"
+ },
+ "makeSubsetSIP": {
+ "bytes": 1648,
+ "sha256": "0cc56fb4c1c1c9680f3dde8cf88cf9da35d5af339f0c44a71976e9abc4b92230",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x5910D1E4, sha256 6f8275c184ad73eed089c9ae3dab631cdca809361b253ce8f23e4bf592ce780d",
+ "cmap": "82 bytes, checksum 0x00420076, sha256 f6d9593a66846b174499232d5c653827aca29fb4afa95c9d48a8b1a05f33bb84",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "456 bytes, checksum 0xA597EF24, sha256 fc281ecb0dd8d40dfcf54cc27fea6f485a3ce29b31ad44a858037941a97e99ab",
+ "head": "54 bytes, checksum 0x26853AD1, sha256 bb97a5e85cf7f4157a7389f729781b0ccf97c4ce78c1c64f078108df0d7f2ede",
+ "hhea": "36 bytes, checksum 0x087602F7, sha256 b77957ff705ba9eb769b43f6e686e2652d488fd9997e2bb142f0a393a164f499",
+ "hmtx": "24 bytes, checksum 0x14680159, sha256 2f03ee1162e724d677550e1eff1b811c49271a8317e699eb03cc6f7e93232863",
+ "loca": "14 bytes, checksum 0x016600D0, sha256 d3868833ca7cd5facd47d789fdfa8e947052e749acd0ed29963710cf0d6c9ff8",
+ "maxp": "32 bytes, checksum 0x000F0051, sha256 277ce9daa2e509e2027ecde2a2ace2ebfb7456a1a4649389f6c4c6b477d40007",
+ "name": "618 bytes, checksum 0x323B4A7A, sha256 1c9f67517afb47c153afb54af026607704646d2f3e3908c8e0bdf007f288f974",
+ "post": "32 bytes, checksum 0xFF860032, sha256 22dd499f08932214bde96943f3882f3619324478217095c049b68a57c6c10693"
+ },
+ "maxUniChar": 65535,
+ "defaultWidth": 1000
+ },
+ "repackageTTF": {
+ "bytes": 1648,
+ "sha256": "9791a9f8655fb19c326771aeb0030f7528ad4535e0359f0921d2996d5cfc13c3",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x553CF586, sha256 4feb4a7666c967ad3bedc80ca0480d43b41a41ffe07c31028a6ef52218d38859",
+ "cmap": "92 bytes, checksum 0x9CAAE980, sha256 e4692eb00f3df3286c3849816405f4499d6d2b1303588d995548e412dc50bbc0",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "450 bytes, checksum 0x9F9AF520, sha256 8a6a9e3195830fdde21cc912fe50b04e40ef1b07d484fa55dfc90f061eeea27d",
+ "head": "54 bytes, checksum 0x26853AD1, sha256 265b581a78ab6c32946ab7fdea796e29af28e7538ec71bf89f46ac44f51d6685",
+ "hhea": "36 bytes, checksum 0x087602F4, sha256 3b8df10855749dc2b94ca33deacd41aa368f250bd21bfe9561090e4dece3ed54",
+ "hmtx": "18 bytes, checksum 0x094000C9, sha256 d6dcf7d9a71a1793b58afdde15a319c3308777bb8a77dcb1561617fcdb87c4b6",
+ "loca": "14 bytes, checksum 0x015F00CA, sha256 2190e466db26bc483532782d3ea3b3fda85f12db1ef10acfa41e2aff62e640d8",
+ "maxp": "32 bytes, checksum 0x000F0051, sha256 277ce9daa2e509e2027ecde2a2ace2ebfb7456a1a4649389f6c4c6b477d40007",
+ "name": "618 bytes, checksum 0x32424A7A, sha256 843256959a3f193a9c9b4b1991e6342af742cf0658dae6febbf7dfacf3c50595",
+ "post": "32 bytes, checksum 0xFF860032, sha256 22dd499f08932214bde96943f3882f3619324478217095c049b68a57c6c10693"
+ },
+ "maxUni": 0
+ }
+ }
+}
diff --git a/tests/data/ttf/NotoSansTC-RegionLangSys-Synthetic.ttf b/tests/data/ttf/NotoSansTC-RegionLangSys-Synthetic.ttf
new file mode 100644
index 000000000..5ea726ebb
Binary files /dev/null and b/tests/data/ttf/NotoSansTC-RegionLangSys-Synthetic.ttf differ