Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions src/Shaper/OtlTags.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ class OtlTags
/**
* The v2 Indic and Myanmar tags, each with the original tag that a font made to the earlier
* specification offers instead.
*
* Order is load-bearing. A v2 tag the font does not offer is tried against its own original tag
* and then against the original tags of every entry after it, not only its own: a Bengali run in
* a font offering neither bng2 nor beng is laid out as deva if the font has that. That is #192,
* kept here as it was.
*/
private static $originalIndicTags = [
'bng2' => 'beng',
Expand Down Expand Up @@ -60,14 +55,11 @@ public static function script(array $ScriptLang, $scripttag, $scriptblock, $shap
return [$scripttag, false];
}

if ($shaper) {
$reached = false;
foreach (self::$originalIndicTags as $v2 => $original) {
$reached = $reached || $v2 === $scripttag;
if ($reached && isset($ScriptLang[$original])) {
return [$original, true];
}
}
// Only the run's own original tag: another Indic script's lookups and reordering are no fit
// for it, and a font offering nothing for the script is laid out by its default entry
$original = isset(self::$originalIndicTags[$scripttag]) ? self::$originalIndicTags[$scripttag] : '';
if ($shaper && $original && isset($ScriptLang[$original])) {
return [$original, true];
}

foreach (['DFLT', 'dflt', 'latn'] as $fallback) {
Expand Down
39 changes: 39 additions & 0 deletions tests/Mpdf/IndicScriptFallbackTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Mpdf;

/**
* An Indic run in a font offering neither its v2 tag nor its original one is laid out with the
* font's default script, not with another Indic script's original tag.
*
* No font in the corpus offers another script's original tag without the run's own and has glyphs
* for the run, so NotoSansBengali-DevaScript-Synthetic is a subset of Noto Sans Bengali 3.011 (OFL
* 1.1) with its GSUB replaced. It offers DFLT and deva and nothing for Bengali, and each has one
* 'locl' lookup: DFLT's gives KA the glyph of GA, deva's the glyph of KHA. `hb-shape` draws GA.
*/
class IndicScriptFallbackTest extends \Yoast\PHPUnitPolyfills\TestCases\TestCase
{

const KA = 0x0995;

const GA = 0x0997;

public function testABengaliRunIsLaidOutWithTheDefaultScriptRatherThanDevanagari()
{
$mpdf = new TextRecordingMpdf([
'mode' => 'utf-8',
'fontDir' => [__DIR__ . '/../data/ttf'],
'fontdata' => ['notosansbengalidevascriptsynthetic' => [
'R' => 'NotoSansBengali-DevaScript-Synthetic.ttf',
'useOTL' => 0xFF,
]],
'default_font' => 'notosansbengalidevascriptsynthetic',
]);
$mpdf->WriteHTML(sprintf('<p>&#x%04X;</p>', self::KA));

$drawn = array_values(unpack('N*', mb_convert_encoding($mpdf->drawnText[0], 'UTF-32BE', 'UTF-8')));

$this->assertSame([self::GA], $drawn);
}

}
20 changes: 14 additions & 6 deletions tests/Mpdf/Shaper/OtlTagsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,22 @@ public function testTheOriginalIndicTagIsNotTriedWithoutAShaper()
}

/**
* Pins #192 as it stands: a v2 tag reaches the original tags listed after its own, but never
* those before it.
* @dataProvider originalTagFallbacks
*/
public function testAV2TagFallsThroughToTheOriginalTagsListedAfterItsOwn()
public function testAV2TagFallsBackToItsOwnOriginalTagAndNoOtherScriptsOriginalTag(array $offered, $scripttag, $scriptblock, array $expected)
{
$this->assertSame(['deva', true], OtlTags::script(['deva' => 'DFLT', 'DFLT' => 'DFLT'], 'bng2', Ucdn::SCRIPT_BENGALI, 'I', 0xFF));
$this->assertSame(['mymr', true], OtlTags::script(['mymr' => 'DFLT'], 'tml2', Ucdn::SCRIPT_TAMIL, 'I', 0xFF));
$this->assertSame(['DFLT', false], OtlTags::script(['beng' => 'DFLT', 'DFLT' => 'DFLT'], 'dev2', Ucdn::SCRIPT_DEVANAGARI, 'I', 0xFF));
$this->assertSame($expected, OtlTags::script($offered, $scripttag, $scriptblock, 'I', 0xFF));
}

public function originalTagFallbacks()
{
return [
'Bengali, where the font offers deva' => [['deva' => 'DFLT', 'DFLT' => 'DFLT'], 'bng2', Ucdn::SCRIPT_BENGALI, ['DFLT', false]],
'Devanagari, where the font offers gujr' => [['gujr' => 'DFLT', 'DFLT' => 'DFLT'], 'dev2', Ucdn::SCRIPT_DEVANAGARI, ['DFLT', false]],
'Tamil, where the font offers only mymr' => [['mymr' => 'DFLT'], 'tml2', Ucdn::SCRIPT_TAMIL, ['', false]],
'Devanagari, where the font offers beng' => [['beng' => 'DFLT', 'DFLT' => 'DFLT'], 'dev2', Ucdn::SCRIPT_DEVANAGARI, ['DFLT', false]],
'Bengali, where the font offers beng and deva' => [['deva' => 'DFLT', 'beng' => 'DFLT'], 'bng2', Ucdn::SCRIPT_BENGALI, ['beng', true]],
];
}

public function testATagThatIsNotAV2IndicTagHasNoOriginalToFallBackTo()
Expand Down
92 changes: 92 additions & 0 deletions tests/data/fontcache/NotoSansBengali-DevaScript-Synthetic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"_": "Generated by composer fontcache:update. See tests/Mpdf/Fonts/ParserGoldenMaster.php.",
"fullName": "NotoSansBengali-DevaScript-Synthetic",
"mtx": {
"GSUBScriptLang": {
"DFLT": "DFLT ",
"deva": "DFLT "
},
"GSUBFeatures": {
"DFLT": {
"DFLT": {
"locl": [
0
]
}
},
"deva": {
"DFLT": {
"locl": [
1
]
}
}
},
"GSUBLookups": [
{
"Type": 1,
"Flag": 0,
"SubtableCount": 1,
"Subtables": [
88
],
"MarkFilteringSet": ""
},
{
"Type": 1,
"Flag": 0,
"SubtableCount": 1,
"Subtables": [
102
],
"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": "114 bytes, sha256 db414921ffcf0b37c47e2d31afc271c25f46f9c9037a44e957346ab2cb8d203c",
"GSUBdata.json": [
[
{
"2453": 0
}
],
[
{
"2453": 0
}
]
]
}
}
34 changes: 34 additions & 0 deletions tests/data/otldump/NotoSansBengali-DevaScript-Synthetic.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<h1>GDEF table</h1>
<h2>Glyph classes</h2>
<h3>Glyph class 1</h3>
<h5>Base glyph (single character, spacing glyph)</h5>
<div class="glyphs">&#x00995; &#x00996; &#x00997; &#x009B7; &#x009BF; &#x025CC; </div>
<h3>Glyph class 3</h3>
<h5>Mark glyph (non-spacing combining glyph)</h5>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h1>Mark Glyph Sets</h1>
<h3>Mark Glyph Set class: 0</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h3>Mark Glyph Set class: 1</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h3>Mark Glyph Set class: 2</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h3>Mark Glyph Set class: 3</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h3>Mark Glyph Set class: 4</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h3>Mark Glyph Set class: 5</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h3>Mark Glyph Set class: 6</h3>
<div class="glyphs">&#x25cc;&#x009CD; </div>
<h1>GSUB Tables</h1>
<h3>GSUB Scripts &amp; Languages</h3>
<div class="glyphs">
<h5>DFLT</h5><div><a href="font_dump_otl.php?script=DFLT&amp;lang=DFLT">DFLT</a></b>: locl </div><h5>deva</h5><div><a href="font_dump_otl.php?script=deva&amp;lang=DFLT">DFLT</a></b>: locl </div>
</div>
<div>GPOS table not defined</div>

=== detail: script deva language DFLT ===
<h1>GSUB Tables</h1>
<bookmark level="0" content="GSUB features"><div class="level1"><h5 class="level1"><bookmark level="1" content="locl [#1]">Lookup #1 [tag: <span style="color:#000066;">locl</span>]</h5><div class="subtable">Subtable #0<bookmark level="2" content="Subtable #0"></div><div class="lookuptype">LookupType 1: Single Substitution Subtable</div><div class="substitution"><span class="unicode">U+0995&nbsp;</span> <span class="unchanged">&nbsp;&#x0995;</span>&nbsp; &raquo; &raquo; &nbsp;<span class="changed">&nbsp;&#x0996;</span>&nbsp; <span class="unicode">U+0996</span> </div></div>
<div>GPOS table not defined</div>
92 changes: 92 additions & 0 deletions tests/data/shaping/NotoSansBengali-DevaScript-Synthetic.txt
Original file line number Diff line number Diff line change
@@ -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 => 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
=== 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 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 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
12 changes: 6 additions & 6 deletions tests/data/shaping/NotoSansGurmukhiUI-GPOS71-Subset.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 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
Expand Down
Loading
Loading