diff --git a/src/Otl.php b/src/Otl.php
index 4f4675829..5a2715600 100644
--- a/src/Otl.php
+++ b/src/Otl.php
@@ -221,20 +221,22 @@ function applyOTL($str, $useOTL)
list($GSUBscriptTag, $GSUBlangsys, $GPOSscriptTag, $GPOSlangsys, $is_old_spec)
= $this->selectScriptAndLanguage($scriptblock, $useOTL);
- if (!$GSUBscriptTag && !$GSUBlangsys && !$GPOSscriptTag && !$GPOSlangsys) {
+ $this->shaper = $this->shaperForScriptTag($this->shaper, $scriptblock, $GSUBscriptTag);
+
+ // A run the font offers no script for still goes to its shaper, which reorders it with
+ // nothing to substitute. Every script with a shaper is one useOTL opens with 0x80, and a
+ // document that has not opened it gets nothing.
+ $shapeWithoutTables = $this->shaper && ($useOTL & 0x80);
+
+ if (!$GSUBscriptTag && !$GSUBlangsys && !$GPOSscriptTag && !$GPOSlangsys && !$shapeWithoutTables) {
$this->removeJoinControls(false);
$this->schOTLdata[$sch] = $this->OTLdata;
$this->OTLdata = [];
continue;
}
- // Don't use MYANMAR shaper unless using v2 scripttag
- if ($this->shaper == 'M' && $GSUBscriptTag != 'mym2') {
- $this->shaper = '';
- }
-
- $GSUBFeatures = (isset($this->mpdf->CurrentFont['GSUBFeatures'][$GSUBscriptTag][$GSUBlangsys]) ? $this->mpdf->CurrentFont['GSUBFeatures'][$GSUBscriptTag][$GSUBlangsys] : false);
- $GPOSFeatures = (isset($this->mpdf->CurrentFont['GPOSFeatures'][$GPOSscriptTag][$GPOSlangsys]) ? $this->mpdf->CurrentFont['GPOSFeatures'][$GPOSscriptTag][$GPOSlangsys] : false);
+ $GSUBFeatures = $this->features('GSUB', $GSUBscriptTag, $GSUBlangsys);
+ $GPOSFeatures = $this->features('GPOS', $GPOSscriptTag, $GPOSlangsys);
$this->assocLigs = []; // Ligatures[$posarr lpos] => nc
$this->assocMarks = []; // assocMarks[$posarr mpos] => array(compID, ligPos)
@@ -506,11 +508,17 @@ private function insertWordBoundaries($scriptblock)
*/
private function applyGSUB($GSUBscriptTag, $GSUBlangsys, $GSUBFeatures, $scriptblock, $is_old_spec)
{
- if (!$GSUBscriptTag || !$GSUBlangsys || !$GSUBFeatures) {
+ if (!$GSUBFeatures && !$this->shaper) {
return '';
}
- $this->loadGsubData($GSUBscriptTag, $GSUBlangsys);
+ $this->loadGsubDerivedData($GSUBscriptTag, $GSUBlangsys);
+
+ // A run with nothing to substitute still goes to its shaper, and its font need not have a
+ // GSUB table at all
+ if ($GSUBFeatures) {
+ $this->loadGsubLookups();
+ }
// 5. GSUB - Shaper
if ($this->shaper == 'A') {
@@ -539,16 +547,14 @@ private function applyGSUB($GSUBscriptTag, $GSUBlangsys, $GSUBFeatures, $scriptb
}
/**
- * Phase 4: what this font's GSUB table says, for this script and language system.
+ * What this font's GSUB table says, for this script and language system.
*
- * Three things, cached for the life of the document because a document sets the same font for
- * line after line: the derived tables the shapers work from, which the parser builds per script
- * and language; the coverage of every lookup, which is how a lookup is passed over without being
- * read; and the lookup list itself.
+ * Cached for the life of the document because a document sets the same font for line after line:
+ * the derived tables the shapers work from, which the parser builds per script and language, and
+ * which are empty where it built none.
*/
- private function loadGsubData($GSUBscriptTag, $GSUBlangsys)
+ private function loadGsubDerivedData($GSUBscriptTag, $GSUBlangsys)
{
- $this->readTable('GSUB');
$this->GSUBfont = $this->fontkey . '.GSUB.' . $GSUBscriptTag . '.' . $GSUBlangsys;
if (!isset($this->GSUBdata[$this->GSUBfont])) {
@@ -571,6 +577,15 @@ private function loadGsubData($GSUBscriptTag, $GSUBlangsys)
];
}
}
+ }
+
+ /**
+ * The coverage of every lookup, which is how a lookup is passed over without being read, and the
+ * lookup list itself.
+ */
+ private function loadGsubLookups()
+ {
+ $this->readTable('GSUB');
$fontCacheFilename = $this->fontkey . '.GSUBdata.json';
if (!isset($this->GSUBdata[$this->fontkey]) && $this->fontCache->jsonHas($fontCacheFilename)) {
@@ -1361,6 +1376,50 @@ private function selectShaper($scriptblock)
}
}
+ /**
+ * Which shaper a run gets once the font's GSUB script for it is known.
+ *
+ * As HarfBuzz's hb_ot_shaper_categorize(): a font designed for DFLT, or one where the choice fell
+ * through to latn, is laid out by its features alone, and no script at all is not a reason to
+ * skip the shaper. Khmer, Thai and Lao keep theirs whatever was chosen, Arabic too, and Syriac
+ * everywhere but under DFLT. Myanmar also gives the pre-specification mymr to the default shaper.
+ *
+ * @param string $shaper The shaper selectShaper() picked for the run's script
+ * @param int $scriptblock The run's Unicode script, as Ucdn::SCRIPT_*
+ * @param string $GSUBscriptTag The GSUB script chosen for it, or '' for none
+ *
+ * @return string The shaper, as selectShaper() names it
+ */
+ private function shaperForScriptTag($shaper, $scriptblock, $GSUBscriptTag)
+ {
+ if ($shaper == 'K' || $shaper == 'T' || $shaper == 'L' || $scriptblock == Ucdn::SCRIPT_ARABIC) {
+ return $shaper;
+ }
+
+ if ($scriptblock == Ucdn::SCRIPT_SYRIAC) {
+ return $GSUBscriptTag == 'DFLT' ? '' : $shaper;
+ }
+
+ if ($GSUBscriptTag == 'DFLT' || $GSUBscriptTag == 'latn' || ($shaper == 'M' && $GSUBscriptTag == 'mymr')) {
+ return '';
+ }
+
+ return $shaper;
+ }
+
+ /**
+ * @param string $table 'GSUB' or 'GPOS'
+ *
+ * @return array The features the table offers under a script and language system, by tag, or
+ * none where it offers neither
+ */
+ private function features($table, $scriptTag, $langsys)
+ {
+ return isset($this->mpdf->CurrentFont[$table . 'Features'][$scriptTag][$langsys])
+ ? $this->mpdf->CurrentFont[$table . 'Features'][$scriptTag][$langsys]
+ : [];
+ }
+
/**
* Phase 3: which script and language system of the font to lay this run out with.
*
@@ -1562,7 +1621,7 @@ function _applyGSUBrules($usetags, $scriptTag, $langsys)
// - Implemented in functions checkContextMatch and checkContextMatchMultiple by failing to match if outside scope of current 'syllable'
// if $this->restrictToSyllable is true
- $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys];
+ $GSUBFeatures = $this->features('GSUB', $scriptTag, $langsys);
$LookupList = [];
foreach ($GSUBFeatures as $tag => $arr) {
if (strpos($usetags, $tag) !== false) {
@@ -1623,7 +1682,7 @@ function _applyGSUBrulesSingly($usetags, $scriptTag, $langsys)
{
// Features are applied one at a time, working through each codepoint
- $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys];
+ $GSUBFeatures = $this->features('GSUB', $scriptTag, $langsys);
// A reverse Lookup runs the other way down the glyphs, so it cannot share the cursor the rest
// of the list walks forward. Taking each over the whole run up front costs nothing here: this
@@ -1711,7 +1770,7 @@ function _applyGSUBrulesMyanmar($usetags, $scriptTag, $langsys)
// $usetags = locl ccmp rphf pref blwf pstf';
// applied to all characters
- $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys];
+ $GSUBFeatures = $this->features('GSUB', $scriptTag, $langsys);
// ALL should be applied one syllable at a time
// Implemented in functions checkContextMatch and checkContextMatchMultiple by failing to match if outside scope of current 'syllable'
@@ -1784,7 +1843,7 @@ function _applyGSUBrulesIndic($usetags, $scriptTag, $langsys, $is_old_spec)
// rphf, pref, blwf, half, abvf, pstf, and init are only applied where ['mask'] indicates: Indic::FLAG(Indic::RPHF);
// The rest are applied to all characters
- $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys];
+ $GSUBFeatures = $this->features('GSUB', $scriptTag, $langsys);
// ALL should be applied one syllable at a time
// Implemented in functions checkContextMatch and checkContextMatchMultiple by failing to match if outside scope of current 'syllable'
diff --git a/tests/Mpdf/Shaper/SeaTest.php b/tests/Mpdf/Shaper/SeaTest.php
index 535ba7415..80d4736a0 100644
--- a/tests/Mpdf/Shaper/SeaTest.php
+++ b/tests/Mpdf/Shaper/SeaTest.php
@@ -10,14 +10,16 @@
* pass makes glyphs the categorising pass never saw, and Otl handed them on without a
* ['sea_category'] of their own - which the reorderer reads on the last glyph of a broken cluster.
*
- * Lanna Alif is the font throughout. Its 'ccmp' ligates a Sakot with the consonant after it into a
- * subscript form, and the glyph that comes out has no codepoint of its own, so it is mapped into the
- * Private Use Area as the subset is built.
+ * The shaper is only reached under a Tai Tham script tag, and no Tai Tham font in reach offers one:
+ * Lanna Alif has latn, and Noto Sans Tai Tham DFLT and latn, under which HarfBuzz and mPDF both use
+ * the default shaper. NotoSansTaiTham-LanaScript-Synthetic is a subset of Noto Sans Tai Tham 2.002
+ * (OFL 1.1) with its script retagged lana and its Sakot ligatures moved from 'liga' to 'ccmp'. The
+ * ligature has no codepoint of its own, so it is mapped into the Private Use Area as the subset is
+ * built. `hb-shape` draws what each test below expects.
*
* What the read turns on is that the last glyph of the cluster came out of that pass, not how long
- * the cluster is. Lanna Alif carries U+25CC, so a dotted circle is inserted ahead of the ligature
- * and the cluster is two elements; Noto Sans Tai Tham carries none, and the same cluster is one.
- * Both raised the warning.
+ * the cluster is. The font has no dotted circle to put in front of the ligature, so the cluster is
+ * one glyph; Lanna Alif, which has one, warned on a cluster of two.
*/
class SeaTest extends \Yoast\PHPUnitPolyfills\TestCases\TestCase
{
@@ -28,11 +30,8 @@ class SeaTest extends \Yoast\PHPUnitPolyfills\TestCases\TestCase
/** U+1A60 TAI THAM SIGN SAKOT, which subscripts the consonant after it */
const SAKOT = 0x1A60;
- /** U+25CC DOTTED CIRCLE, inserted in front of a cluster with no base consonant */
- const DOTTED_CIRCLE = 0x25CC;
-
- /** The subscript High Ka that Lanna Alif's 'ccmp' substitutes for Sakot + High Ka */
- const SAKOT_HIGH_KA = 0xF001;
+ /** The subscript High Ka that the font's 'ccmp' substitutes for Sakot + High Ka */
+ const SAKOT_HIGH_KA = 0xE002;
/**
* A Sakot with no consonant in front of it is a broken cluster, and the reorderer reads the
@@ -57,13 +56,12 @@ public function testAGlyphSubstitutedBeforeTheReorderingCarriesACategoryIntoIt()
restore_error_handler();
$this->assertSame([], $raised);
- $this->assertSame([self::DOTTED_CIRCLE, self::SAKOT_HIGH_KA], $drawn);
+ $this->assertSame([self::SAKOT_HIGH_KA], $drawn);
}
/**
* The same Sakot inside a well-formed cluster, which is what the rule is for: the consonant in
- * front of it is the base, no dotted circle is needed, and the pair after it is subscripted under
- * it.
+ * front of it is the base, and the pair after it is subscripted under it.
*/
public function testASakotInsideAClusterSubscriptsTheConsonantAfterIt()
{
@@ -94,8 +92,14 @@ private function drawn($codepoints)
$html .= sprintf('%04X;', $codepoint);
}
- $mpdf = new TextRecordingMpdf();
- $mpdf->WriteHTML('
' . $html . '
');
+ $mpdf = new TextRecordingMpdf([
+ 'fontDir' => [__DIR__ . '/../../data/ttf'],
+ 'fontdata' => ['notosanstaithamlanascriptsynthetic' => [
+ 'R' => 'NotoSansTaiTham-LanaScript-Synthetic.ttf',
+ 'useOTL' => 0xFF,
+ ]],
+ ]);
+ $mpdf->WriteHTML('' . $html . '
');
return array_values(unpack('N*', mb_convert_encoding($mpdf->drawnText[0], 'UTF-32BE', 'UTF-8')));
}
diff --git a/tests/Mpdf/ShaperChoiceTest.php b/tests/Mpdf/ShaperChoiceTest.php
new file mode 100644
index 000000000..7d3e78f56
--- /dev/null
+++ b/tests/Mpdf/ShaperChoiceTest.php
@@ -0,0 +1,95 @@
+assertSame([self::GA, self::I], $this->drawn('NotoSansBengali-DevaScript-Synthetic', [self::KA, self::I]));
+ }
+
+ public function testAnIndicRunTheFontOffersNoScriptForIsReorderedWithNothingSubstituted()
+ {
+ $this->assertSame([self::I, self::KA], $this->drawn('NotoSansBengali-GuruScript-Synthetic', [self::KA, self::I]));
+ }
+
+ /**
+ * The original specification puts the matra before the base consonant, SSA, and after the KA and
+ * virama in front of it. The v2 specification would put it before the whole conjunct.
+ */
+ public function testAnIndicRunWithNoScriptIsReorderedToTheOriginalSpecification()
+ {
+ $this->assertSame(
+ [self::KA, self::VIRAMA, self::I, self::SSA],
+ $this->drawn('NotoSansBengali-GuruScript-Synthetic', [self::KA, self::VIRAMA, self::SSA, self::I])
+ );
+ }
+
+ public function testARunInAScriptTheDocumentHasNotOpenedToOpenTypeLayoutIsNotShaped()
+ {
+ $this->assertSame([self::KA, self::I], $this->drawn('NotoSansBengali-GuruScript-Synthetic', [self::KA, self::I], 0x01));
+ }
+
+ /**
+ * Lanna Alif offers only latn. Its 'ccmp' ligates a Sakot with the High Ka after it, and with no
+ * South East Asian shaper the broken cluster gets no dotted circle in front of it.
+ */
+ public function testATaiThamRunUnderLatnIsLaidOutByTheFontsFeaturesAlone()
+ {
+ $mpdf = new TextRecordingMpdf();
+ $mpdf->WriteHTML('᩠ᨠ
');
+
+ // The ligature has no codepoint of its own, and is mapped into the Private Use Area
+ $this->assertSame([0xF001], $this->codepoints($mpdf->drawnText[0]));
+ }
+
+ private function drawn($font, array $codepoints, $useOTL = 0xFF)
+ {
+ $key = strtolower(str_replace('-', '', $font));
+
+ $mpdf = new TextRecordingMpdf([
+ 'mode' => 'utf-8',
+ 'fontDir' => [__DIR__ . '/../data/ttf'],
+ 'fontdata' => [$key => ['R' => $font . '.ttf', 'useOTL' => $useOTL]],
+ 'default_font' => $key,
+ ]);
+
+ $html = '';
+ foreach ($codepoints as $codepoint) {
+ $html .= sprintf('%04X;', $codepoint);
+ }
+ $mpdf->WriteHTML('' . $html . '
');
+
+ return $this->codepoints($mpdf->drawnText[0]);
+ }
+
+ private function codepoints($text)
+ {
+ return array_values(unpack('N*', mb_convert_encoding($text, 'UTF-32BE', 'UTF-8')));
+ }
+
+}
diff --git a/tests/Snapshots/TaiThamSakotSnapshotTest.php b/tests/Snapshots/TaiThamSakotSnapshotTest.php
index 4bc222f52..74cbcf986 100644
--- a/tests/Snapshots/TaiThamSakotSnapshotTest.php
+++ b/tests/Snapshots/TaiThamSakotSnapshotTest.php
@@ -14,15 +14,16 @@
* Myanmar categories onto them and carried nothing onto these, so a Sakot ligated with the consonant
* after it reached the reorderer with no category, and reading it was a warning per run.
*
- * Lanna Alif is the font throughout. Its 'ccmp' ligates a Sakot with the consonant after it into a
- * subscript form whose glyph has no codepoint of its own, so it is mapped into the Private Use Area
- * as the subset is built and the samples are read off the page and compared with each other rather
- * than named.
+ * The font throughout is NotoSansTaiTham-LanaScript-Synthetic, a subset of Noto Sans Tai Tham whose
+ * script is retagged lana: the shaper is only reached under a Tai Tham tag, and Lanna Alif, which
+ * offers latn, is laid out by the default shaper as HarfBuzz lays it out. Its 'ccmp' ligates a Sakot
+ * with the consonant after it into a subscript form whose glyph has no codepoint of its own, so it is
+ * mapped into the Private Use Area as the subset is built and the samples are read off the page and
+ * compared with each other rather than named.
*
* Nothing here is drawn differently: a missing category read as null matched nothing at the one test
- * that reads it, and the fixture is byte-identical to the one the code before the fix writes. What it
- * pins is a cluster that reaches the reorderer through a substitution, so moving where the category
- * comes from has to move a page to get through.
+ * that reads it. What it pins is a cluster that reaches the reorderer through a substitution, so
+ * moving where the category comes from has to move a page to get through.
*
* @group snapshot
*/
@@ -57,10 +58,22 @@ public function getId()
*/
public function generatePdf()
{
- $this->mpdf = $this->createMpdf(['mode' => 'utf-8']);
+ $this->mpdf = $this->createMpdf(self::config());
$this->mpdf->WriteHTML($this->style() . $this->samples());
}
+ private static function config()
+ {
+ return [
+ 'mode' => 'utf-8',
+ 'fontDir' => [__DIR__ . '/../data/ttf'],
+ 'fontdata' => ['taithamlana' => [
+ 'R' => 'NotoSansTaiTham-LanaScript-Synthetic.ttf',
+ 'useOTL' => 0xFF,
+ ]],
+ ];
+ }
+
private function style()
{
ob_start();
@@ -69,14 +82,14 @@ private function style()
h2 { font-size: 12pt; margin-bottom: 1mm; }
p.note { font-size: 9pt; color: #606060; margin-top: 0; }
p.label { font-size: 9pt; color: #606060; margin-bottom: 0; }
- p.sample { font-family: lannaalif; font-size: 28pt; margin-top: 0; margin-bottom: 3mm; }
+ p.sample { font-family: taithamlana; font-size: 28pt; margin-top: 0; margin-bottom: 3mm; }
mPDF
Tai Tham clusters joined by a Sakot
A Sakot subscripts the consonant after it, and the two are drawn as one glyph
the font substitutes for the pair. Written with no consonant in front of them they are a
- broken cluster, and a dotted circle is inserted to stand in for the consonant that is
+ broken cluster, and the font has no dotted circle to stand in for the consonant that is
missing. Read the subscript form under each: the broken cluster draws the same one the
well-formed cluster does.
sample('Sakot, High Ka - no base, so a dotted circle carries the pair', self::SAKOT . self::HIGH_KA)
+ return $this->sample('Sakot, High Ka - no base, so nothing carries the pair', self::SAKOT . self::HIGH_KA)
. $this->sample('High Ka, Sakot, High Ka - the same pair under a base, the form to match', self::HIGH_KA . self::SAKOT . self::HIGH_KA)
. $this->sample('High Ka alone - the base by itself', self::HIGH_KA)
. $this->sample('Sakot alone - nothing to subscript, drawn as it was written', self::SAKOT)
@@ -110,24 +123,23 @@ private function sample($label, $text)
*/
private function glyphsOf($text)
{
- $mpdf = new TextRecordingMpdf(['mode' => 'utf-8']);
+ $mpdf = new TextRecordingMpdf(self::config());
$mpdf->WriteHTML($this->style() . '' . $text . '
');
return array_values(unpack('N*', mb_convert_encoding(end($mpdf->drawnText), 'UTF-32BE', 'UTF-8')));
}
/**
- * The Sakot and the consonant after it become one glyph either way. In the broken cluster a dotted
- * circle stands where the base would be, and the subscript form is the same one the base takes.
+ * The Sakot and the consonant after it become one glyph either way, and the subscript form the
+ * broken cluster draws is the same one the base takes.
*/
public function testTheBrokenClusterDrawsTheSubscriptFormTheWellFormedClusterDraws()
{
$broken = $this->glyphsOf(self::SAKOT . self::HIGH_KA);
$wellFormed = $this->glyphsOf(self::HIGH_KA . self::SAKOT . self::HIGH_KA);
- $this->assertCount(2, $broken, 'the broken cluster draws something other than a stand-in and one subscript form');
+ $this->assertCount(1, $broken, 'the broken cluster draws something other than one subscript form');
$this->assertSame(end($wellFormed), end($broken), 'the broken cluster draws a subscript form the well-formed one does not');
- $this->assertNotSame($this->glyphsOf(self::HIGH_KA)[0], $broken[0], 'the stand-in is the consonant rather than a dotted circle');
}
/**
diff --git a/tests/data/fontcache/NotoSansBengali-GuruScript-Synthetic.json b/tests/data/fontcache/NotoSansBengali-GuruScript-Synthetic.json
new file mode 100644
index 000000000..fe189750d
--- /dev/null
+++ b/tests/data/fontcache/NotoSansBengali-GuruScript-Synthetic.json
@@ -0,0 +1,70 @@
+{
+ "_": "Generated by composer fontcache:update. See tests/Mpdf/Fonts/ParserGoldenMaster.php.",
+ "fullName": "NotoSansBengali-GuruScript-Synthetic",
+ "mtx": {
+ "GSUBScriptLang": {
+ "guru": "DFLT "
+ },
+ "GSUBFeatures": {
+ "guru": {
+ "DFLT": {
+ "locl": [
+ 0
+ ]
+ }
+ }
+ },
+ "GSUBLookups": [
+ {
+ "Type": 1,
+ "Flag": 0,
+ "SubtableCount": 1,
+ "Subtables": [
+ 56
+ ],
+ "MarkFilteringSet": ""
+ }
+ ],
+ "GPOSScriptLang": [],
+ "GPOSFeatures": [],
+ "GPOSLookups": [],
+ "MarkGlyphSets": [
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD"
+ ],
+ "rtlPUAstr": "",
+ "haskernGPOS": false,
+ "hassmallcapsGSUB": false
+ },
+ "cache": {
+ "GDEFdata.json": {
+ "GlyphClassBases": " 00995| 00996| 00997| 009B7| 009BF| 025CC",
+ "GlyphClassMarks": " 009CD",
+ "GlyphClassLigatures": "",
+ "GlyphClassComponents": "",
+ "MarkGlyphSets": [
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD",
+ " 009CD"
+ ],
+ "MarkAttachmentType": []
+ },
+ "GSUB.dat": "68 bytes, sha256 70783ab0e3f3e6d03df78c824bc1cb733550af9c202ae2b88ff0d2a22948c5b1",
+ "GSUBdata.json": [
+ [
+ {
+ "2453": 0
+ }
+ ]
+ ]
+ }
+}
diff --git a/tests/data/fontcache/NotoSansTaiTham-LanaScript-Synthetic.json b/tests/data/fontcache/NotoSansTaiTham-LanaScript-Synthetic.json
new file mode 100644
index 000000000..c522fd33a
--- /dev/null
+++ b/tests/data/fontcache/NotoSansTaiTham-LanaScript-Synthetic.json
@@ -0,0 +1,72 @@
+{
+ "_": "Generated by composer fontcache:update. See tests/Mpdf/Fonts/ParserGoldenMaster.php.",
+ "fullName": "NotoSansTaiTham-LanaScript-Synthetic",
+ "mtx": {
+ "GSUBScriptLang": {
+ "lana": "DFLT "
+ },
+ "GSUBFeatures": {
+ "lana": {
+ "DFLT": {
+ "ccmp": [
+ 1
+ ]
+ }
+ }
+ },
+ "GSUBLookups": [
+ {
+ "Type": 4,
+ "Flag": 0,
+ "SubtableCount": 1,
+ "Subtables": [
+ 58
+ ],
+ "MarkFilteringSet": ""
+ },
+ {
+ "Type": 6,
+ "Flag": 0,
+ "SubtableCount": 2,
+ "Subtables": [
+ 94,
+ 118
+ ],
+ "MarkFilteringSet": ""
+ }
+ ],
+ "GPOSScriptLang": [],
+ "GPOSFeatures": [],
+ "GPOSLookups": [],
+ "MarkGlyphSets": [],
+ "rtlPUAstr": "",
+ "haskernGPOS": false,
+ "hassmallcapsGSUB": false
+ },
+ "cache": {
+ "GDEFdata.json": {
+ "GlyphClassBases": " 00020| 01A20| 01A21| 01A63| 0E000| 0E001| 0E002",
+ "GlyphClassMarks": " 01A60",
+ "GlyphClassLigatures": "",
+ "GlyphClassComponents": "",
+ "MarkGlyphSets": [],
+ "MarkAttachmentType": []
+ },
+ "GSUB.dat": "148 bytes, sha256 e3e5d6c3ea5a2b4d5a5f7145427e1da577e58e9eb6d32eaa8acfc19bdf1859bb",
+ "GSUBdata.json": [
+ [
+ {
+ "6752": 0
+ }
+ ],
+ [
+ {
+ "6752": 0
+ },
+ {
+ "6752": 0
+ }
+ ]
+ ]
+ }
+}
diff --git a/tests/data/otldump/NotoSansBengali-GuruScript-Synthetic.txt b/tests/data/otldump/NotoSansBengali-GuruScript-Synthetic.txt
new file mode 100644
index 000000000..15a78c82c
--- /dev/null
+++ b/tests/data/otldump/NotoSansBengali-GuruScript-Synthetic.txt
@@ -0,0 +1,34 @@
+GDEF table
+Glyph classes
+Glyph class 1
+Base glyph (single character, spacing glyph)
+ক খ গ ষ ি ◌
+Glyph class 3
+Mark glyph (non-spacing combining glyph)
+◌্
+Mark Glyph Sets
+Mark Glyph Set class: 0
+◌্
+Mark Glyph Set class: 1
+◌্
+Mark Glyph Set class: 2
+◌্
+Mark Glyph Set class: 3
+◌্
+Mark Glyph Set class: 4
+◌্
+Mark Glyph Set class: 5
+◌্
+Mark Glyph Set class: 6
+◌্
+GSUB Tables
+GSUB Scripts & Languages
+
+GPOS table not defined
+
+=== detail: script guru language DFLT ===
+GSUB Tables
+Lookup #0 [tag: locl]
Subtable #0
LookupType 1: Single Substitution Subtable
U+0995 ক » » খ U+0996
+GPOS table not defined
diff --git a/tests/data/otldump/NotoSansTaiTham-LanaScript-Synthetic.txt b/tests/data/otldump/NotoSansTaiTham-LanaScript-Synthetic.txt
new file mode 100644
index 000000000..3ea0e5150
--- /dev/null
+++ b/tests/data/otldump/NotoSansTaiTham-LanaScript-Synthetic.txt
@@ -0,0 +1,19 @@
+GDEF table
+Glyph classes
+Glyph class 1
+Base glyph (single character, spacing glyph)
+ ᨠ ᨡ ᩣ
+Glyph class 3
+Mark glyph (non-spacing combining glyph)
+◌᩠
+GSUB Tables
+GSUB Scripts & Languages
+
+GPOS table not defined
+
+=== detail: script lana language DFLT ===
+GSUB Tables
+Lookup #1 [tag: ccmp]
Subtable #0
LookupType 6: Chaining Contextual Substitution Subtable
Format 3: Coverage-based Chaining Context Glyph Substitution
CONTEXT:
Input #0: ◌᩠
Input #1: ᨠ
Substitution Position: 0
Lookup #0 [tag: ccmp]
Subtable #0
LookupType 4: Ligature Substitution Subtable
U+1A60, U+1A20 ◌᩠ ᨠᨠ » » ᨠ M+E002
U+1A60, U+1A21 ◌᩠ ᨡᨠ » » ᨠ M+E001
Subtable #1
LookupType 6: Chaining Contextual Substitution Subtable
Format 3: Coverage-based Chaining Context Glyph Substitution
CONTEXT:
Input #0: ◌᩠
Input #1: ᨡ
Substitution Position: 0
Lookup #0 [tag: ccmp]
Subtable #0
LookupType 4: Ligature Substitution Subtable
U+1A60, U+1A20 ◌᩠ ᨠᨡ » » ᨡ M+E002
U+1A60, U+1A21 ◌᩠ ᨡᨡ » » ᨡ M+E001
+GPOS table not defined
diff --git a/tests/data/shaping/Carlito-MarkAttachmentType-Subset.txt b/tests/data/shaping/Carlito-MarkAttachmentType-Subset.txt
index 086b38621..534d2e30f 100644
--- a/tests/data/shaping/Carlito-MarkAttachmentType-Subset.txt
+++ b/tests/data/shaping/Carlito-MarkAttachmentType-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/Manjari-Regular.txt b/tests/data/shaping/Manjari-Regular.txt
index d2327c9b7..f1b3ee19e 100644
--- a/tests/data/shaping/Manjari-Regular.txt
+++ b/tests/data/shaping/Manjari-Regular.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/Molengo-GSUB52Class0-Subset.txt b/tests/data/shaping/Molengo-GSUB52Class0-Subset.txt
index c0cedf1f6..4f11dff58 100644
--- a/tests/data/shaping/Molengo-GSUB52Class0-Subset.txt
+++ b/tests/data/shaping/Molengo-GSUB52Class0-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/Noto-LanguageTags-Synthetic.txt b/tests/data/shaping/Noto-LanguageTags-Synthetic.txt
index c1ebd4bd4..0cb6c05f7 100644
--- a/tests/data/shaping/Noto-LanguageTags-Synthetic.txt
+++ b/tests/data/shaping/Noto-LanguageTags-Synthetic.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoMusic-GSUB52-Subset.txt b/tests/data/shaping/NotoMusic-GSUB52-Subset.txt
index 108f135e3..b7bf6bac3 100644
--- a/tests/data/shaping/NotoMusic-GSUB52-Subset.txt
+++ b/tests/data/shaping/NotoMusic-GSUB52-Subset.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-GPOS3-Synthetic.txt b/tests/data/shaping/NotoSans-GPOS3-Synthetic.txt
index 38685b72f..fbacbc1c3 100644
--- a/tests/data/shaping/NotoSans-GPOS3-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GPOS3-Synthetic.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSans-GPOS72-Synthetic.txt b/tests/data/shaping/NotoSans-GPOS72-Synthetic.txt
index 9ace39da1..2b3ba3a75 100644
--- a/tests/data/shaping/NotoSans-GPOS72-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GPOS72-Synthetic.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-GPOS73-Synthetic.txt b/tests/data/shaping/NotoSans-GPOS73-Synthetic.txt
index 9ace39da1..2b3ba3a75 100644
--- a/tests/data/shaping/NotoSans-GPOS73-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GPOS73-Synthetic.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-GPOS83-Guard-Synthetic.txt b/tests/data/shaping/NotoSans-GPOS83-Guard-Synthetic.txt
index a51361715..de4738988 100644
--- a/tests/data/shaping/NotoSans-GPOS83-Guard-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GPOS83-Guard-Synthetic.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-GSUB2-BigSubtable-Synthetic.txt b/tests/data/shaping/NotoSans-GSUB2-BigSubtable-Synthetic.txt
index 411ff40af..28f422bc3 100644
--- a/tests/data/shaping/NotoSans-GSUB2-BigSubtable-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GSUB2-BigSubtable-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-GSUB53-NestedAdvance-Synthetic.txt b/tests/data/shaping/NotoSans-GSUB53-NestedAdvance-Synthetic.txt
index f734637e2..1cfb2a2c8 100644
--- a/tests/data/shaping/NotoSans-GSUB53-NestedAdvance-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GSUB53-NestedAdvance-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-GSUBClassZero-Synthetic.txt b/tests/data/shaping/NotoSans-GSUBClassZero-Synthetic.txt
index 44f21332e..857030c23 100644
--- a/tests/data/shaping/NotoSans-GSUBClassZero-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-GSUBClassZero-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-PlaneSixteenMark-Synthetic.txt b/tests/data/shaping/NotoSans-PlaneSixteenMark-Synthetic.txt
index 0848d5b42..00c72ae47 100644
--- a/tests/data/shaping/NotoSans-PlaneSixteenMark-Synthetic.txt
+++ b/tests/data/shaping/NotoSans-PlaneSixteenMark-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSans-Regular.txt b/tests/data/shaping/NotoSans-Regular.txt
index 5be89e56f..06d10fb64 100644
--- a/tests/data/shaping/NotoSans-Regular.txt
+++ b/tests/data/shaping/NotoSans-Regular.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => E562 E3B3 group=CC
0xFF +kern -liga 0915 094D 0937 093F => E562 E3B3 group=CC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansArabic-ContextEdge-Synthetic.txt b/tests/data/shaping/NotoSansArabic-ContextEdge-Synthetic.txt
index b22550262..d077bd4d6 100644
--- a/tests/data/shaping/NotoSansArabic-ContextEdge-Synthetic.txt
+++ b/tests/data/shaping/NotoSansArabic-ContextEdge-Synthetic.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansArabic-GSUB11Wrap-Synthetic.txt b/tests/data/shaping/NotoSansArabic-GSUB11Wrap-Synthetic.txt
index fc0233178..f8789871a 100644
--- a/tests/data/shaping/NotoSansArabic-GSUB11Wrap-Synthetic.txt
+++ b/tests/data/shaping/NotoSansArabic-GSUB11Wrap-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansArabic-GSUB5Form-Synthetic.txt b/tests/data/shaping/NotoSansArabic-GSUB5Form-Synthetic.txt
index 46b19791d..164b20808 100644
--- a/tests/data/shaping/NotoSansArabic-GSUB5Form-Synthetic.txt
+++ b/tests/data/shaping/NotoSansArabic-GSUB5Form-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansArabic-GSUB62Positions-Synthetic.txt b/tests/data/shaping/NotoSansArabic-GSUB62Positions-Synthetic.txt
index 3320dea0b..7ab662624 100644
--- a/tests/data/shaping/NotoSansArabic-GSUB62Positions-Synthetic.txt
+++ b/tests/data/shaping/NotoSansArabic-GSUB62Positions-Synthetic.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansArabic-Joining-Subset.txt b/tests/data/shaping/NotoSansArabic-Joining-Subset.txt
index d5bd0d353..5ba47f8a1 100644
--- a/tests/data/shaping/NotoSansArabic-Joining-Subset.txt
+++ b/tests/data/shaping/NotoSansArabic-Joining-Subset.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansArabic-MultipleFinal-Subset.txt b/tests/data/shaping/NotoSansArabic-MultipleFinal-Subset.txt
index 237a49a18..6badfee89 100644
--- a/tests/data/shaping/NotoSansArabic-MultipleFinal-Subset.txt
+++ b/tests/data/shaping/NotoSansArabic-MultipleFinal-Subset.txt
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansArabic-MultipleForm-Subset.txt b/tests/data/shaping/NotoSansArabic-MultipleForm-Subset.txt
index 3288884f4..265c0950d 100644
--- a/tests/data/shaping/NotoSansArabic-MultipleForm-Subset.txt
+++ b/tests/data/shaping/NotoSansArabic-MultipleForm-Subset.txt
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansBengali-DevaScript-Synthetic.txt b/tests/data/shaping/NotoSansBengali-DevaScript-Synthetic.txt
index 2cf00a3c5..4a07587b4 100644
--- a/tests/data/shaping/NotoSansBengali-DevaScript-Synthetic.txt
+++ b/tests/data/shaping/NotoSansBengali-DevaScript-Synthetic.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0997 09CD 09BF 09B7 group=CMCC
-0x80 0995 09CD 09B7 09BF => 0997 09CD 09BF 09B7 group=CMCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0997 09CD 09BF 09B7 group=CMCC
+0xFF 0995 09CD 09B7 09BF => 0997 09CD 09B7 09BF group=CMCC
+0x80 0995 09CD 09B7 09BF => 0997 09CD 09B7 09BF group=CMCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0997 09CD 09B7 09BF group=CMCC
=== gurmukhi ===
-0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
@@ -87,6 +87,6 @@
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 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0997 0996 0997 09BF 09B7 09CD 25CC group=SCCCCCMC
-0x80 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0997 0996 0997 09BF 09B7 09CD 25CC group=SCCCCCMC
-0xFF +kern -liga 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0997 0996 0997 09BF 09B7 09CD 25CC group=SCCCCCMC
+0xFF 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0997 0996 0997 09B7 09BF 09CD 25CC group=SCCCCCMC
+0x80 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0997 0996 0997 09B7 09BF 09CD 25CC group=SCCCCCMC
+0xFF +kern -liga 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0997 0996 0997 09B7 09BF 09CD 25CC group=SCCCCCMC
diff --git a/tests/data/shaping/NotoSansBengali-GuruScript-Synthetic.txt b/tests/data/shaping/NotoSansBengali-GuruScript-Synthetic.txt
new file mode 100644
index 000000000..27bbe3efa
--- /dev/null
+++ b/tests/data/shaping/NotoSansBengali-GuruScript-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 gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+=== 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 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+=== bengali ===
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CMCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CMCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CMCC
+=== gurmukhi ===
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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 25CC 1039 1001 group=CCCCC
+0x80 1000 103A 1039 1001 => 1000 103A 25CC 1039 1001 group=CCCCC
+0xFF +kern -liga 1000 103A 1039 1001 => 1000 103A 25CC 1039 1001 group=CCCCC
+=== 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 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0995 0996 0997 09BF 09B7 09CD 25CC group=SCCCCCMC
+0x80 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0995 0996 0997 09BF 09B7 09CD 25CC group=SCCCCCMC
+0xFF +kern -liga 0020 0995 0996 0997 09B7 09BF 09CD 25CC => 0020 0995 0996 0997 09BF 09B7 09CD 25CC group=SCCCCCMC
diff --git a/tests/data/shaping/NotoSansCoptic-GSUB81-Subset.txt b/tests/data/shaping/NotoSansCoptic-GSUB81-Subset.txt
index 4abb2bd60..327333bfa 100644
--- a/tests/data/shaping/NotoSansCoptic-GSUB81-Subset.txt
+++ b/tests/data/shaping/NotoSansCoptic-GSUB81-Subset.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansCoptic-IgnoreMarksClass-Synthetic.txt b/tests/data/shaping/NotoSansCoptic-IgnoreMarksClass-Synthetic.txt
index 4abb2bd60..327333bfa 100644
--- a/tests/data/shaping/NotoSansCoptic-IgnoreMarksClass-Synthetic.txt
+++ b/tests/data/shaping/NotoSansCoptic-IgnoreMarksClass-Synthetic.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansDevanagari-ContextualLocl-Subset.txt b/tests/data/shaping/NotoSansDevanagari-ContextualLocl-Subset.txt
index b7d6be7db..22f354c70 100644
--- a/tests/data/shaping/NotoSansDevanagari-ContextualLocl-Subset.txt
+++ b/tests/data/shaping/NotoSansDevanagari-ContextualLocl-Subset.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansGurmukhi-NestedCoverage-Subset.txt b/tests/data/shaping/NotoSansGurmukhi-NestedCoverage-Subset.txt
index 09420c36d..814c8bcf7 100644
--- a/tests/data/shaping/NotoSansGurmukhi-NestedCoverage-Subset.txt
+++ b/tests/data/shaping/NotoSansGurmukhi-NestedCoverage-Subset.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansGurmukhiUI-GPOS71-Subset.txt b/tests/data/shaping/NotoSansGurmukhiUI-GPOS71-Subset.txt
index 582d0fed0..c099a5e36 100644
--- a/tests/data/shaping/NotoSansGurmukhiUI-GPOS71-Subset.txt
+++ b/tests/data/shaping/NotoSansGurmukhiUI-GPOS71-Subset.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,13 +27,13 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
=== gurmukhi ===
0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansMono-GDEF13-Subset.txt b/tests/data/shaping/NotoSansMono-GDEF13-Subset.txt
index 612aaa725..972554502 100644
--- a/tests/data/shaping/NotoSansMono-GDEF13-Subset.txt
+++ b/tests/data/shaping/NotoSansMono-GDEF13-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansSaurashtra-GSUB53-Subset.txt b/tests/data/shaping/NotoSansSaurashtra-GSUB53-Subset.txt
index 08a21a318..12d4e1c15 100644
--- a/tests/data/shaping/NotoSansSaurashtra-GSUB53-Subset.txt
+++ b/tests/data/shaping/NotoSansSaurashtra-GSUB53-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansSinhala-Subset.txt b/tests/data/shaping/NotoSansSinhala-Subset.txt
index 2d3e54d84..c4213c368 100644
--- a/tests/data/shaping/NotoSansSinhala-Subset.txt
+++ b/tests/data/shaping/NotoSansSinhala-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansSyriac-Joining-Subset.txt b/tests/data/shaping/NotoSansSyriac-Joining-Subset.txt
index 94b657ecc..e95bfa5b6 100644
--- a/tests/data/shaping/NotoSansSyriac-Joining-Subset.txt
+++ b/tests/data/shaping/NotoSansSyriac-Joining-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansTC-MacaoLangSys-Synthetic.txt b/tests/data/shaping/NotoSansTC-MacaoLangSys-Synthetic.txt
index 7c53de204..5aed8af70 100644
--- a/tests/data/shaping/NotoSansTC-MacaoLangSys-Synthetic.txt
+++ b/tests/data/shaping/NotoSansTC-MacaoLangSys-Synthetic.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt b/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt
index ad76bec74..1949581c7 100644
--- a/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt
+++ b/tests/data/shaping/NotoSansTC-RegionLangSys-Synthetic.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/NotoSansTaiTham-LanaScript-Synthetic.txt b/tests/data/shaping/NotoSansTaiTham-LanaScript-Synthetic.txt
new file mode 100644
index 000000000..f6a009923
--- /dev/null
+++ b/tests/data/shaping/NotoSansTaiTham-LanaScript-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 gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+=== 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 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+=== bengali ===
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+=== gurmukhi ===
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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 E001 group=CC
+0x80 1A20 1A60 1A21 => 1A20 E001 group=CC
+0xFF +kern -liga 1A20 1A60 1A21 => 1A20 E001 group=CC
+=== 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 1A20 1A21 1A60 1A63 E000 E001 E002 => 0020 1A20 1A21 1A60 1A63 E000 E001 E002 group=SCCMCCCC
+0x80 0020 1A20 1A21 1A60 1A63 E000 E001 E002 => 0020 1A20 1A21 1A60 1A63 E000 E001 E002 group=SCCMCCCC
+0xFF +kern -liga 0020 1A20 1A21 1A60 1A63 E000 E001 E002 => 0020 1A20 1A21 1A60 1A63 E000 E001 E002 group=SCCMCCCC
diff --git a/tests/data/shaping/NotoSansTakri-GPOS81-Subset.txt b/tests/data/shaping/NotoSansTakri-GPOS81-Subset.txt
index 2d00a7ca6..bdea46b74 100644
--- a/tests/data/shaping/NotoSansTakri-GPOS81-Subset.txt
+++ b/tests/data/shaping/NotoSansTakri-GPOS81-Subset.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansTakri-GSUB53-Subset.txt b/tests/data/shaping/NotoSansTakri-GSUB53-Subset.txt
index 70ccfe1e9..af3d569d5 100644
--- a/tests/data/shaping/NotoSansTakri-GSUB53-Subset.txt
+++ b/tests/data/shaping/NotoSansTakri-GSUB53-Subset.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/NotoSansWancho-ScriptTag-Subset.txt b/tests/data/shaping/NotoSansWancho-ScriptTag-Subset.txt
index 63e57e1dd..0e50d88d6 100644
--- a/tests/data/shaping/NotoSansWancho-ScriptTag-Subset.txt
+++ b/tests/data/shaping/NotoSansWancho-ScriptTag-Subset.txt
@@ -15,9 +15,9 @@
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
+0xFF 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0x80 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
+0xFF +kern -liga 0628 0640 0645 0644 0627 => 0628 0640 0645 0644 0627 group=CCCCC gpos={"1":{"kashida":8}}
=== syriac ===
0xFF 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
0x80 0710 0712 0713 0715 => 0710 0712 0713 0715 group=CCCC
@@ -27,17 +27,17 @@
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
+0xFF 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 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
+0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 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
+0xFF 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 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
@@ -51,9 +51,9 @@
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
+0xFF 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0x80 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 group=CCCC
+0xFF +kern -liga 1780 17D2 1781 17C1 => 17C1 1780 17D2 1781 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
diff --git a/tests/data/shaping/Poppins-Regular.txt b/tests/data/shaping/Poppins-Regular.txt
index 1a2c8e6fa..b6e9c24bc 100644
--- a/tests/data/shaping/Poppins-Regular.txt
+++ b/tests/data/shaping/Poppins-Regular.txt
@@ -31,13 +31,13 @@
0x80 0915 094D 0937 093F => E219 E000 group=CC
0xFF +kern -liga 0915 094D 0937 093F => E219 E000 group=CC
=== bengali ===
-0xFF 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/shaping/SedanSC-EmptyFeature-Subset.txt b/tests/data/shaping/SedanSC-EmptyFeature-Subset.txt
index be8834bae..4abaf6741 100644
--- a/tests/data/shaping/SedanSC-EmptyFeature-Subset.txt
+++ b/tests/data/shaping/SedanSC-EmptyFeature-Subset.txt
@@ -27,17 +27,17 @@
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 093F 0937 group=CCCC
-0x80 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
-0xFF +kern -liga 0915 094D 0937 093F => 0915 094D 093F 0937 group=CCCC
+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 09BF 09B7 group=CCCC
-0x80 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
-0xFF +kern -liga 0995 09CD 09B7 09BF => 0995 09CD 09BF 09B7 group=CCCC
+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 0A3F 0A38 group=CCCC
-0x80 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
-0xFF +kern -liga 0A15 0A4D 0A38 0A3F => 0A15 0A4D 0A3F 0A38 group=CCCC
+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
diff --git a/tests/data/snapshots/tai-tham-sakot.pdf b/tests/data/snapshots/tai-tham-sakot.pdf
index e55cd21af..f1f33e900 100644
Binary files a/tests/data/snapshots/tai-tham-sakot.pdf and b/tests/data/snapshots/tai-tham-sakot.pdf differ
diff --git a/tests/data/subset/NotoSansBengali-GuruScript-Synthetic.json b/tests/data/subset/NotoSansBengali-GuruScript-Synthetic.json
new file mode 100644
index 000000000..88db6e53c
--- /dev/null
+++ b/tests/data/subset/NotoSansBengali-GuruScript-Synthetic.json
@@ -0,0 +1,123 @@
+{
+ "_": "Generated by composer subset:update. See tests/Mpdf/Fonts/SubsetGoldenMaster.php.",
+ "useOTL=0x00": {
+ "characters": 9,
+ "makeSubset": {
+ "bytes": 2172,
+ "sha256": "daed5a8a702380648982d2f7e9da14ac5f8f3d5404fb967c863fddae6ff08313",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x805479C8, sha256 9cdd48b09cc447f76c442e442f291973e5714da75917e3f81368e260671a2172",
+ "cmap": "108 bytes, checksum 0x394D146C, sha256 ab74a71cdee3ef547f433849232e56931cce629a6fb644c9be66e18832c4790d",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "1004 bytes, checksum 0x17873991, sha256 b147e21d29e0207fad56ab068b6224b76a19c0a1dbfc102a33c92d69f2e10283",
+ "head": "54 bytes, checksum 0x1E5ECCDE, sha256 c5648d974758747ac74170cba8c3b40aa54c5915f1962341692d76f20e8f9484",
+ "hhea": "36 bytes, checksum 0x068903B5, sha256 e7330e6f902fd111c3cb0932e4da6c2d5ee8208a28a8ba30bd33515f007c69c8",
+ "hmtx": "36 bytes, checksum 0x111C007C, sha256 793b6cad091178302ca7acf847b6a98b3f1d3fb83671c6456914464e17a3dd3e",
+ "loca": "20 bytes, checksum 0x047C054C, sha256 d7a03b8d662bbcbf0886ecac8efc8edeea8a1144b9c08cf4f003b45e9922c56a",
+ "maxp": "32 bytes, checksum 0x00120045, sha256 9b5303cdff58e0fc16dbdeec5fc8df4437bd1daf3b8feb4d9bc5371f666cbd60",
+ "name": "554 bytes, checksum 0x30964869, sha256 1470a1e9edf83ac4991c1d9303d3425f86dd4bafa480c3c48533b6be07679532",
+ "post": "32 bytes, checksum 0xFF9F0032, sha256 4fdc83d5e42fe44650fe86f15a645d5cc926d07355ba945e1ede42737607bf83"
+ },
+ "maxUni": 65535,
+ "defaultWidth": 600,
+ "codeToGlyph": "9 entries, sha256 27676bbb4e70064f70b3bcbe0ddaa10526e80cd0f75ace6dd28e137393622478"
+ },
+ "makeSubsetSIP": {
+ "bytes": 2152,
+ "sha256": "841c91a3f892f1a848659e146c01baa91548ce5d4a44a1bce1a53996f9268694",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x6633D504, sha256 b29abfebe280b7b9247efba33c975d35734f180921ca523e732af21026e0f8c8",
+ "cmap": "88 bytes, checksum 0x0046009F, sha256 a51feaf8ac92130c6dbb6928e930ab98438f8538e2d11d389bc59faa982dcf4a",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "1004 bytes, checksum 0x17873991, sha256 3e3813ae7fcb41995ce434a59ec7809da764e031159772f810ee8ef726af543b",
+ "head": "54 bytes, checksum 0x1E5ECCDE, sha256 7ce499c3231416297ac2b4368de966cdb6822e889dc469d8d619f28ecc1c693d",
+ "hhea": "36 bytes, checksum 0x068903B5, sha256 e7330e6f902fd111c3cb0932e4da6c2d5ee8208a28a8ba30bd33515f007c69c8",
+ "hmtx": "36 bytes, checksum 0x111C007C, sha256 9ffe6237ef9b4c84c931452a84f34f09c417f51e5ac1ef50c9cdd7864cfaa26f",
+ "loca": "20 bytes, checksum 0x03E0051A, sha256 a5c051ad4bb0091359bd0da187ad4cfc7a4794bb4e8ce4d647a8ece4dcaa05fd",
+ "maxp": "32 bytes, checksum 0x00120045, sha256 9b5303cdff58e0fc16dbdeec5fc8df4437bd1daf3b8feb4d9bc5371f666cbd60",
+ "name": "554 bytes, checksum 0x308F4869, sha256 b26e64e250583c6c3b6d4cdc533d80645cb7e30d08b0bbc6fd11f6eb835764ae",
+ "post": "32 bytes, checksum 0xFF9F0032, sha256 4fdc83d5e42fe44650fe86f15a645d5cc926d07355ba945e1ede42737607bf83"
+ },
+ "maxUniChar": 65535,
+ "defaultWidth": 600
+ },
+ "repackageTTF": {
+ "bytes": 2224,
+ "sha256": "070934bfa3e32fe6d2dae7fe85a3ccee7f30544f104f93cd616b7c0d9265c87c",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x805479C8, sha256 9cdd48b09cc447f76c442e442f291973e5714da75917e3f81368e260671a2172",
+ "cmap": "92 bytes, checksum 0x5EC8EEB7, sha256 96f224410f3d7266dae94d9626b249591d84eab39e6e3653531088e1a0790b8d",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "996 bytes, checksum 0xB3639DAF, sha256 c9f3a1edbb1e3aee2c874d0401a77a00fd372d34321f0adbf8eef95ba179eaae",
+ "head": "54 bytes, checksum 0x1E5ECCDE, sha256 c7a47cbfbaaee77576b4f81c920aa21cc074b6b9cdf3e08771f480a3fb9b97b3",
+ "hhea": "36 bytes, checksum 0x068903B5, sha256 e7330e6f902fd111c3cb0932e4da6c2d5ee8208a28a8ba30bd33515f007c69c8",
+ "hmtx": "36 bytes, checksum 0x111C007C, sha256 793b6cad091178302ca7acf847b6a98b3f1d3fb83671c6456914464e17a3dd3e",
+ "loca": "20 bytes, checksum 0x04740542, sha256 3bce5cbaf580b8c53a539a8644b950d6c140731d00189bfaa6a721c8cfadf87b",
+ "maxp": "32 bytes, checksum 0x00120045, sha256 9b5303cdff58e0fc16dbdeec5fc8df4437bd1daf3b8feb4d9bc5371f666cbd60",
+ "name": "554 bytes, checksum 0x30964869, sha256 1470a1e9edf83ac4991c1d9303d3425f86dd4bafa480c3c48533b6be07679532",
+ "post": "108 bytes, checksum 0x8B7ABECC, sha256 f00be54574ac6dd29adbf678f195657fd56d5fd05bcc9338426d891783123f0c"
+ },
+ "maxUni": 0
+ }
+ },
+ "useOTL=0xFF": {
+ "characters": 9,
+ "makeSubset": {
+ "bytes": 2172,
+ "sha256": "daed5a8a702380648982d2f7e9da14ac5f8f3d5404fb967c863fddae6ff08313",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x805479C8, sha256 9cdd48b09cc447f76c442e442f291973e5714da75917e3f81368e260671a2172",
+ "cmap": "108 bytes, checksum 0x394D146C, sha256 ab74a71cdee3ef547f433849232e56931cce629a6fb644c9be66e18832c4790d",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "1004 bytes, checksum 0x17873991, sha256 b147e21d29e0207fad56ab068b6224b76a19c0a1dbfc102a33c92d69f2e10283",
+ "head": "54 bytes, checksum 0x1E5ECCDE, sha256 c5648d974758747ac74170cba8c3b40aa54c5915f1962341692d76f20e8f9484",
+ "hhea": "36 bytes, checksum 0x068903B5, sha256 e7330e6f902fd111c3cb0932e4da6c2d5ee8208a28a8ba30bd33515f007c69c8",
+ "hmtx": "36 bytes, checksum 0x111C007C, sha256 793b6cad091178302ca7acf847b6a98b3f1d3fb83671c6456914464e17a3dd3e",
+ "loca": "20 bytes, checksum 0x047C054C, sha256 d7a03b8d662bbcbf0886ecac8efc8edeea8a1144b9c08cf4f003b45e9922c56a",
+ "maxp": "32 bytes, checksum 0x00120045, sha256 9b5303cdff58e0fc16dbdeec5fc8df4437bd1daf3b8feb4d9bc5371f666cbd60",
+ "name": "554 bytes, checksum 0x30964869, sha256 1470a1e9edf83ac4991c1d9303d3425f86dd4bafa480c3c48533b6be07679532",
+ "post": "32 bytes, checksum 0xFF9F0032, sha256 4fdc83d5e42fe44650fe86f15a645d5cc926d07355ba945e1ede42737607bf83"
+ },
+ "maxUni": 65535,
+ "defaultWidth": 600,
+ "codeToGlyph": "9 entries, sha256 27676bbb4e70064f70b3bcbe0ddaa10526e80cd0f75ace6dd28e137393622478"
+ },
+ "makeSubsetSIP": {
+ "bytes": 2152,
+ "sha256": "841c91a3f892f1a848659e146c01baa91548ce5d4a44a1bce1a53996f9268694",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x6633D504, sha256 b29abfebe280b7b9247efba33c975d35734f180921ca523e732af21026e0f8c8",
+ "cmap": "88 bytes, checksum 0x0046009F, sha256 a51feaf8ac92130c6dbb6928e930ab98438f8538e2d11d389bc59faa982dcf4a",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "1004 bytes, checksum 0x17873991, sha256 3e3813ae7fcb41995ce434a59ec7809da764e031159772f810ee8ef726af543b",
+ "head": "54 bytes, checksum 0x1E5ECCDE, sha256 7ce499c3231416297ac2b4368de966cdb6822e889dc469d8d619f28ecc1c693d",
+ "hhea": "36 bytes, checksum 0x068903B5, sha256 e7330e6f902fd111c3cb0932e4da6c2d5ee8208a28a8ba30bd33515f007c69c8",
+ "hmtx": "36 bytes, checksum 0x111C007C, sha256 9ffe6237ef9b4c84c931452a84f34f09c417f51e5ac1ef50c9cdd7864cfaa26f",
+ "loca": "20 bytes, checksum 0x03E0051A, sha256 a5c051ad4bb0091359bd0da187ad4cfc7a4794bb4e8ce4d647a8ece4dcaa05fd",
+ "maxp": "32 bytes, checksum 0x00120045, sha256 9b5303cdff58e0fc16dbdeec5fc8df4437bd1daf3b8feb4d9bc5371f666cbd60",
+ "name": "554 bytes, checksum 0x308F4869, sha256 b26e64e250583c6c3b6d4cdc533d80645cb7e30d08b0bbc6fd11f6eb835764ae",
+ "post": "32 bytes, checksum 0xFF9F0032, sha256 4fdc83d5e42fe44650fe86f15a645d5cc926d07355ba945e1ede42737607bf83"
+ },
+ "maxUniChar": 65535,
+ "defaultWidth": 600
+ },
+ "repackageTTF": {
+ "bytes": 2232,
+ "sha256": "1f791abccd8fcc26af63ea617893f00f9cb7f118c8c960a8acba38751d9b9d40",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x805479C8, sha256 9cdd48b09cc447f76c442e442f291973e5714da75917e3f81368e260671a2172",
+ "cmap": "100 bytes, checksum 0x5EC8EEE4, sha256 82f1e3137c11b2b5df509fae504c72128e559311b143b570891f83b225628bcc",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "996 bytes, checksum 0xB3639DAF, sha256 c9f3a1edbb1e3aee2c874d0401a77a00fd372d34321f0adbf8eef95ba179eaae",
+ "head": "54 bytes, checksum 0x1E5ECCDE, sha256 12ad7c04737cce6b56575d034ca25a85f1398f13529371a9f963babcc95630a4",
+ "hhea": "36 bytes, checksum 0x068903B5, sha256 e7330e6f902fd111c3cb0932e4da6c2d5ee8208a28a8ba30bd33515f007c69c8",
+ "hmtx": "36 bytes, checksum 0x111C007C, sha256 793b6cad091178302ca7acf847b6a98b3f1d3fb83671c6456914464e17a3dd3e",
+ "loca": "20 bytes, checksum 0x04740542, sha256 3bce5cbaf580b8c53a539a8644b950d6c140731d00189bfaa6a721c8cfadf87b",
+ "maxp": "32 bytes, checksum 0x00120045, sha256 9b5303cdff58e0fc16dbdeec5fc8df4437bd1daf3b8feb4d9bc5371f666cbd60",
+ "name": "554 bytes, checksum 0x30964869, sha256 1470a1e9edf83ac4991c1d9303d3425f86dd4bafa480c3c48533b6be07679532",
+ "post": "108 bytes, checksum 0x8B7ABECC, sha256 f00be54574ac6dd29adbf678f195657fd56d5fd05bcc9338426d891783123f0c"
+ },
+ "maxUni": 0
+ }
+ }
+}
diff --git a/tests/data/subset/NotoSansTaiTham-LanaScript-Synthetic.json b/tests/data/subset/NotoSansTaiTham-LanaScript-Synthetic.json
new file mode 100644
index 000000000..0d16ba2ef
--- /dev/null
+++ b/tests/data/subset/NotoSansTaiTham-LanaScript-Synthetic.json
@@ -0,0 +1,123 @@
+{
+ "_": "Generated by composer subset:update. See tests/Mpdf/Fonts/SubsetGoldenMaster.php.",
+ "useOTL=0x00": {
+ "characters": 6,
+ "makeSubset": {
+ "bytes": 1652,
+ "sha256": "1c046042cd31245c1bc344c19b4712174240b9f3a0d04b3fb245b305f5c759f2",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x62867003, sha256 223e1e34a0e510a770c27333b1bd4ed290c3604051892b0ec2a1774c1084e71d",
+ "cmap": "100 bytes, checksum 0x347C3581, sha256 0396bed186025aa7dea024e460be494f3c274717fc34fb406f4392a631f1adab",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "504 bytes, checksum 0x4002F834, sha256 6da5814507f437da72e4c49d9dbc02160678a48700b093bb30b21dbafbb8e5c1",
+ "head": "54 bytes, checksum 0x21F43A40, sha256 352604018d7734c7f091946407360833734318e959bf6e0950dbb0ca653dd031",
+ "hhea": "36 bytes, checksum 0x05500064, sha256 482dc9526afb95617a6bd0f8bd3c894ff478a2518dc1628ca1100767a1797dff",
+ "hmtx": "24 bytes, checksum 0x0CAE020B, sha256 8860e66ee50df9ef3a122950ba40a3a276aae2b3518aacec04d63b3c901e64b4",
+ "loca": "14 bytes, checksum 0x023C01B0, sha256 ed0b5d8a97bc4b6e3afd46bbb4cd83565d44acc1077fadc105fb5aaa41f2fff2",
+ "maxp": "32 bytes, checksum 0x000B0078, sha256 49ff426e03fe2641d4dea8eb3c9271e9e5cc2a2a9d8d7ac25c2be28f4181e01e",
+ "name": "560 bytes, checksum 0x303B48C5, sha256 5fa8da46289162eac1235dc1ec4e73ef61f3e2599d5e177cf6e19682e51f1f3e",
+ "post": "32 bytes, checksum 0xFFB80032, sha256 77a232e4db6b60c21f7b76ccf821e3c80c519901f11d10efb8c8df04ca82a4e8"
+ },
+ "maxUni": 65535,
+ "defaultWidth": 619,
+ "codeToGlyph": "6 entries, sha256 e350b4ff46f1c3855ed9dd091c5df0def90c937bffea4c1fb63b6f9e8ebcc16b"
+ },
+ "makeSubsetSIP": {
+ "bytes": 1636,
+ "sha256": "3f8939badfa0fad8c19dae8b5eab7f4965cc441ef0fa5043fcb8af4b1cb24092",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x6865D6A6, sha256 4c3b19c8ae72f32d4bac521a615063fcb8a31d296c1aaea32cf9e2f71e52abed",
+ "cmap": "82 bytes, checksum 0x00420076, sha256 f6d9593a66846b174499232d5c653827aca29fb4afa95c9d48a8b1a05f33bb84",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "504 bytes, checksum 0x4002F834, sha256 dddfaa3e3c129073f11c85fb05e209a376cdf97cc1d85420788af89628478243",
+ "head": "54 bytes, checksum 0x21F43A40, sha256 2cbbca66ee4647454a0581d60cfb6f64a5a0ab840a987989ce3659a4a865e25c",
+ "hhea": "36 bytes, checksum 0x05500064, sha256 482dc9526afb95617a6bd0f8bd3c894ff478a2518dc1628ca1100767a1797dff",
+ "hmtx": "24 bytes, checksum 0x0CAE020B, sha256 9c5e5a96ff0b113f4f5b223cf715a8a9c6f676d5c6e8a591ab02685fb8c182b5",
+ "loca": "14 bytes, checksum 0x01C60150, sha256 fdeab992766afdd530752ec3392a5154df70487c8d3431085edd3634d0b25003",
+ "maxp": "32 bytes, checksum 0x000B0078, sha256 49ff426e03fe2641d4dea8eb3c9271e9e5cc2a2a9d8d7ac25c2be28f4181e01e",
+ "name": "560 bytes, checksum 0x303448C5, sha256 4355ebe3a62e2d449df4301d1f39f9fb83e94cf8cf78031a7e9bed4aacfc3379",
+ "post": "32 bytes, checksum 0xFFB80032, sha256 77a232e4db6b60c21f7b76ccf821e3c80c519901f11d10efb8c8df04ca82a4e8"
+ },
+ "maxUniChar": 65535,
+ "defaultWidth": 619
+ },
+ "repackageTTF": {
+ "bytes": 2028,
+ "sha256": "ecc951d3c33573b3cd98926bd77b6c4c32ce432c24cbeee06128f9bf329a165d",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x62867003, sha256 223e1e34a0e510a770c27333b1bd4ed290c3604051892b0ec2a1774c1084e71d",
+ "cmap": "80 bytes, checksum 0x4EB51B15, sha256 17b5d1e2ebb574ecdc4be5d119434c458894cb47655d442be42b6457e40eb6a7",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "790 bytes, checksum 0x1112BBA1, sha256 ea724f9268c5f7f5d83f111929a2f24bfa6c439df23a9052f70188f3f6ecac1e",
+ "head": "54 bytes, checksum 0x21F43A40, sha256 ab292f9d49d28251d9cfe9bfe526e43306ffad9cb75696b0bade6925def384bf",
+ "hhea": "36 bytes, checksum 0x05500067, sha256 8008d6840a167444cf66260d90c57a3b3d30ad18b892000362c2d5fb32f20aa0",
+ "hmtx": "36 bytes, checksum 0x0CB0FB43, sha256 d9535bccab58fda90a198a0e37151ec354e4be18ba03e8c7ecb1e220ccce3c4d",
+ "loca": "20 bytes, checksum 0x042204FD, sha256 c1c0faeb02e2f115d0f95e0055d64e70fae8ec176462e0801a7cca14e6aa49ed",
+ "maxp": "32 bytes, checksum 0x000E0078, sha256 d313a56897cd4fbd9de4c105d5b4b031af87210ead69c34e17995667cb07f5e0",
+ "name": "560 bytes, checksum 0x303B48C5, sha256 5fa8da46289162eac1235dc1ec4e73ef61f3e2599d5e177cf6e19682e51f1f3e",
+ "post": "124 bytes, checksum 0xD6A58816, sha256 da3f0007e4fbbea000daa270e069659b9c64d7009a83904872045ff341b1e1bd"
+ },
+ "maxUni": 0
+ }
+ },
+ "useOTL=0xFF": {
+ "characters": 9,
+ "makeSubset": {
+ "bytes": 1972,
+ "sha256": "2d03a84a14d09ce0db3a85eb5190164bc55c18285f96c01d525eb3c0fb50590b",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x62867003, sha256 223e1e34a0e510a770c27333b1bd4ed290c3604051892b0ec2a1774c1084e71d",
+ "cmap": "108 bytes, checksum 0x14A8356F, sha256 a4e4463aa089ccb282e6911bdeeba8e4ed85d4f7a8eca51d06f6463e93cb055a",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "800 bytes, checksum 0xA34E2963, sha256 5f7c125c2cad36b939563e8795520acbe479b75d18864a42b46afd948d6b1732",
+ "head": "54 bytes, checksum 0x21F43A40, sha256 8a3916ebdfc05d6238b64bc900d81e3fcbc082e9f889e26c1afb8fe05f1bdaff",
+ "hhea": "36 bytes, checksum 0x05500067, sha256 8008d6840a167444cf66260d90c57a3b3d30ad18b892000362c2d5fb32f20aa0",
+ "hmtx": "36 bytes, checksum 0x0CB0FB43, sha256 d9535bccab58fda90a198a0e37151ec354e4be18ba03e8c7ecb1e220ccce3c4d",
+ "loca": "20 bytes, checksum 0x042C050A, sha256 9a1dc6179d64bf9997774ee965d64a439c24efd4d0e24b0826f3c5aea31512d1",
+ "maxp": "32 bytes, checksum 0x000E0078, sha256 d313a56897cd4fbd9de4c105d5b4b031af87210ead69c34e17995667cb07f5e0",
+ "name": "560 bytes, checksum 0x303B48C5, sha256 5fa8da46289162eac1235dc1ec4e73ef61f3e2599d5e177cf6e19682e51f1f3e",
+ "post": "32 bytes, checksum 0xFFB80032, sha256 77a232e4db6b60c21f7b76ccf821e3c80c519901f11d10efb8c8df04ca82a4e8"
+ },
+ "maxUni": 65535,
+ "defaultWidth": 619,
+ "codeToGlyph": "9 entries, sha256 9391bb61221eced9d8c0f9d990c87a5959d374dad7961cc6a7332108eda0b259"
+ },
+ "makeSubsetSIP": {
+ "bytes": 1952,
+ "sha256": "3d5199e8035ddda5ce042df4917ec92727d43dbfce18afd9f0a769dd8f7e3b84",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x6865D6A9, sha256 c2d76e430d6422a33826a5406025605dd713700f6b8bbeea1e8dbcd7736effbf",
+ "cmap": "88 bytes, checksum 0x0046009F, sha256 a51feaf8ac92130c6dbb6928e930ab98438f8538e2d11d389bc59faa982dcf4a",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "800 bytes, checksum 0xA3502963, sha256 e6ffdbd1a8b846ed5b667ccc76c05ace7bcf6694dc1ec45d69ea2be1950d4aae",
+ "head": "54 bytes, checksum 0x21F43A40, sha256 06799e26738cdeaba947e7be4b8f3e6166d04bb8925dc072461a56caf17248fd",
+ "hhea": "36 bytes, checksum 0x05500067, sha256 8008d6840a167444cf66260d90c57a3b3d30ad18b892000362c2d5fb32f20aa0",
+ "hmtx": "36 bytes, checksum 0x0CB0FB43, sha256 a35a27ee75aa89f6d12499b6bb4bd1a3efa26988cc76f3f0378e53785dd41a33",
+ "loca": "20 bytes, checksum 0x034E042C, sha256 a49f4272a25d76c957fbb96e2026c1f71a52b75842182d5509c27e7595a69e05",
+ "maxp": "32 bytes, checksum 0x000E0078, sha256 d313a56897cd4fbd9de4c105d5b4b031af87210ead69c34e17995667cb07f5e0",
+ "name": "560 bytes, checksum 0x303448C5, sha256 4355ebe3a62e2d449df4301d1f39f9fb83e94cf8cf78031a7e9bed4aacfc3379",
+ "post": "32 bytes, checksum 0xFFB80032, sha256 77a232e4db6b60c21f7b76ccf821e3c80c519901f11d10efb8c8df04ca82a4e8"
+ },
+ "maxUniChar": 65535,
+ "defaultWidth": 619
+ },
+ "repackageTTF": {
+ "bytes": 2048,
+ "sha256": "0a1ed9e2cb68ddfb28d767e661f5d34b484fa35ff83bdf70fd09b7b14f4a05dc",
+ "tables": {
+ "OS/2": "96 bytes, checksum 0x62867003, sha256 223e1e34a0e510a770c27333b1bd4ed290c3604051892b0ec2a1774c1084e71d",
+ "cmap": "100 bytes, checksum 0xF4835587, sha256 04c65ef6477b9a9f8263b94332170dd23672f12dcb4366a2715844bad3df7378",
+ "gasp": "8 bytes, checksum 0x00000010, sha256 4ca731f86ad506ac0e320283dc9461926346de3c4d91d539ea7f6620d3826940",
+ "glyf": "790 bytes, checksum 0x1112BBA1, sha256 ea724f9268c5f7f5d83f111929a2f24bfa6c439df23a9052f70188f3f6ecac1e",
+ "head": "54 bytes, checksum 0x21F43A40, sha256 fad5095b1e69fc129c46063d8f6a623988cfb5480f7003569f25dc1e8dd365df",
+ "hhea": "36 bytes, checksum 0x05500067, sha256 8008d6840a167444cf66260d90c57a3b3d30ad18b892000362c2d5fb32f20aa0",
+ "hmtx": "36 bytes, checksum 0x0CB0FB43, sha256 d9535bccab58fda90a198a0e37151ec354e4be18ba03e8c7ecb1e220ccce3c4d",
+ "loca": "20 bytes, checksum 0x042204FD, sha256 c1c0faeb02e2f115d0f95e0055d64e70fae8ec176462e0801a7cca14e6aa49ed",
+ "maxp": "32 bytes, checksum 0x000E0078, sha256 d313a56897cd4fbd9de4c105d5b4b031af87210ead69c34e17995667cb07f5e0",
+ "name": "560 bytes, checksum 0x303B48C5, sha256 5fa8da46289162eac1235dc1ec4e73ef61f3e2599d5e177cf6e19682e51f1f3e",
+ "post": "124 bytes, checksum 0xD6A58816, sha256 da3f0007e4fbbea000daa270e069659b9c64d7009a83904872045ff341b1e1bd"
+ },
+ "maxUni": 0
+ }
+ }
+}
diff --git a/tests/data/ttf/NotoSansBengali-GuruScript-Synthetic.ttf b/tests/data/ttf/NotoSansBengali-GuruScript-Synthetic.ttf
new file mode 100644
index 000000000..e57242d93
Binary files /dev/null and b/tests/data/ttf/NotoSansBengali-GuruScript-Synthetic.ttf differ
diff --git a/tests/data/ttf/NotoSansTaiTham-LanaScript-Synthetic.ttf b/tests/data/ttf/NotoSansTaiTham-LanaScript-Synthetic.ttf
new file mode 100644
index 000000000..0215a854f
Binary files /dev/null and b/tests/data/ttf/NotoSansTaiTham-LanaScript-Synthetic.ttf differ