Skip to content

Commit 7bc2097

Browse files
SnipxiText-CI
authored andcommitted
OTF: Support GposLookupType1 - table subformat 2
DEVSIX-5160 Autoported commit. Original commit hash: [ff08e8fde]
1 parent 30c2776 commit 7bc2097

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

itext.tests/itext.io.tests/itext/io/font/otf/GposLookupType1Test.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class GposLookupType1Test : ExtendedITextTest {
3232
.CurrentContext.TestDirectory) + "/resources/itext/io/font/otf/GposLookupType1Test/";
3333

3434
[NUnit.Framework.Test]
35-
public virtual void VerifyXAdvanceIsApplied() {
35+
public virtual void VerifyXAdvanceIsAppliedSubFormat1() {
3636
TrueTypeFont fontProgram = (TrueTypeFont)FontProgramFactory.CreateFont(RESOURCE_FOLDER + "NotoSansMyanmar-Regular.ttf"
3737
);
3838
GlyphPositioningTableReader gposTableReader = fontProgram.GetGposTable();
@@ -47,7 +47,7 @@ public virtual void VerifyXAdvanceIsApplied() {
4747
}
4848

4949
[NUnit.Framework.Test]
50-
public virtual void VerifyPositionIsNotAppliedForIrrelevantGlyph() {
50+
public virtual void VerifyPositionIsNotAppliedForIrrelevantGlyphSubFormat1() {
5151
TrueTypeFont fontProgram = (TrueTypeFont)FontProgramFactory.CreateFont(RESOURCE_FOLDER + "NotoSansMyanmar-Regular.ttf"
5252
);
5353
GlyphPositioningTableReader gposTableReader = fontProgram.GetGposTable();
@@ -60,5 +60,26 @@ public virtual void VerifyPositionIsNotAppliedForIrrelevantGlyph() {
6060
NUnit.Framework.Assert.IsFalse(lookup.TransformOne(gl));
6161
NUnit.Framework.Assert.AreEqual(0, gl.Get(0).GetXAdvance());
6262
}
63+
64+
[NUnit.Framework.Test]
65+
public virtual void VerifyDifferentXAdvanceIsAppliedSubFormat2() {
66+
TrueTypeFont fontProgram = (TrueTypeFont)FontProgramFactory.CreateFont(RESOURCE_FOLDER + "NotoSansMyanmar-Regular.ttf"
67+
);
68+
GlyphPositioningTableReader gposTableReader = fontProgram.GetGposTable();
69+
GposLookupType1 lookup = (GposLookupType1)gposTableReader.GetLookupTable(16);
70+
IList<Glyph> glyphs = JavaUtil.ArraysAsList(new Glyph(fontProgram.GetGlyphByCode(401)), new Glyph(fontProgram
71+
.GetGlyphByCode(5)));
72+
GlyphLine gl = new GlyphLine(glyphs);
73+
NUnit.Framework.Assert.AreEqual(0, gl.Get(0).GetXAdvance());
74+
NUnit.Framework.Assert.IsTrue(lookup.TransformOne(gl));
75+
NUnit.Framework.Assert.AreEqual(109, gl.Get(0).GetXAdvance());
76+
// Subtable type 2 defines different GposValueRecords for different coverage glyphs
77+
glyphs = JavaUtil.ArraysAsList(new Glyph(fontProgram.GetGlyphByCode(508)), new Glyph(fontProgram.GetGlyphByCode
78+
(5)));
79+
gl = new GlyphLine(glyphs);
80+
NUnit.Framework.Assert.AreEqual(0, gl.Get(0).GetXAdvance());
81+
NUnit.Framework.Assert.IsTrue(lookup.TransformOne(gl));
82+
NUnit.Framework.Assert.AreEqual(158, gl.Get(0).GetXAdvance());
83+
}
6384
}
6485
}

itext/itext.io/itext/io/font/otf/GposLookupType1.cs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2020
You should have received a copy of the GNU Affero General Public License
2121
along with this program. If not, see <https://www.gnu.org/licenses/>.
2222
*/
23+
using System;
2324
using System.Collections.Generic;
2425

2526
namespace iText.IO.Font.Otf {
@@ -45,8 +46,8 @@ public override bool TransformOne(GlyphLine line) {
4546
GposValueRecord valueRecord = valueRecordMap.Get(glyphCode);
4647
if (valueRecord != null) {
4748
Glyph newGlyph = new Glyph(line.Get(line.idx));
48-
newGlyph.xAdvance += (short)valueRecord.XAdvance;
49-
newGlyph.yAdvance += (short)valueRecord.YAdvance;
49+
newGlyph.SetXAdvance((short)(newGlyph.GetXAdvance() + valueRecord.XAdvance));
50+
newGlyph.SetYAdvance((short)(newGlyph.GetYAdvance() + valueRecord.YAdvance));
5051
line.Set(line.idx, newGlyph);
5152
positionApplied = true;
5253
}
@@ -56,13 +57,32 @@ public override bool TransformOne(GlyphLine line) {
5657

5758
protected internal override void ReadSubTable(int subTableLocation) {
5859
openReader.rf.Seek(subTableLocation);
59-
openReader.rf.ReadShort();
60-
int coverage = openReader.rf.ReadUnsignedShort();
60+
int subTableFormat = openReader.rf.ReadShort();
61+
int coverageOffset = openReader.rf.ReadUnsignedShort();
6162
int valueFormat = openReader.rf.ReadUnsignedShort();
62-
GposValueRecord valueRecord = OtfReadCommon.ReadGposValueRecord(openReader, valueFormat);
63-
IList<int> coverageGlyphIds = openReader.ReadCoverageFormat(subTableLocation + coverage);
64-
foreach (int? glyphId in coverageGlyphIds) {
65-
valueRecordMap.Put((int)glyphId, valueRecord);
63+
if (subTableFormat == 1) {
64+
GposValueRecord valueRecord = OtfReadCommon.ReadGposValueRecord(openReader, valueFormat);
65+
IList<int> coverageGlyphIds = openReader.ReadCoverageFormat(subTableLocation + coverageOffset);
66+
foreach (int? glyphId in coverageGlyphIds) {
67+
valueRecordMap.Put((int)glyphId, valueRecord);
68+
}
69+
}
70+
else {
71+
if (subTableFormat == 2) {
72+
int valueCount = openReader.rf.ReadUnsignedShort();
73+
IList<GposValueRecord> valueRecords = new List<GposValueRecord>();
74+
for (int i = 0; i < valueCount; i++) {
75+
GposValueRecord valueRecord = OtfReadCommon.ReadGposValueRecord(openReader, valueFormat);
76+
valueRecords.Add(valueRecord);
77+
}
78+
IList<int> coverageGlyphIds = openReader.ReadCoverageFormat(subTableLocation + coverageOffset);
79+
for (int i = 0; i < coverageGlyphIds.Count; i++) {
80+
valueRecordMap.Put((int)coverageGlyphIds[i], valueRecords[i]);
81+
}
82+
}
83+
else {
84+
throw new ArgumentException("Bad subtable format identifier: " + subTableFormat);
85+
}
6686
}
6787
}
6888
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
304ce6d86d44b034d84e409ffc93300db3d097a7
1+
ff08e8fdea70e17ac8b6294045d8c23209f42a63

0 commit comments

Comments
 (0)