Skip to content

Commit 99260f1

Browse files
ars18wrwiText-CI
authored andcommitted
If one glyph is substituted to many glyphs, actual text should be distributed
DEVSIX-4529
1 parent 1d72156 commit 99260f1

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

io/src/main/java/com/itextpdf/io/font/otf/GlyphLine.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ public void substituteOneToOne(OpenTypeFontTableReader tableReader, int substitu
300300
public void substituteOneToMany(OpenTypeFontTableReader tableReader, int[] substGlyphIds) {
301301
//sequence length shall be at least 1
302302
int substCode = substGlyphIds[0];
303+
Glyph oldGlyph = glyphs.get(idx);
303304
Glyph glyph = tableReader.getGlyph(substCode);
304305
glyphs.set(idx, glyph);
305306

@@ -311,6 +312,14 @@ public void substituteOneToMany(OpenTypeFontTableReader tableReader, int[] subst
311312
additionalGlyphs.add(glyph);
312313
}
313314
addAllGlyphs(idx + 1, additionalGlyphs);
315+
if (null != actualText) {
316+
if (null == actualText.get(idx)) {
317+
actualText.set(idx, new ActualText(oldGlyph.getUnicodeString()));
318+
}
319+
for (int i = 0; i < additionalGlyphs.size(); i++) {
320+
this.actualText.set(idx + 1 + i, actualText.get(idx));
321+
}
322+
}
314323
idx += substGlyphIds.length - 1;
315324
end += substGlyphIds.length - 1;
316325
}

io/src/test/java/com/itextpdf/io/font/otf/GlyphLineTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ This file is part of the iText (R) project.
4242
*/
4343
package com.itextpdf.io.font.otf;
4444

45+
import com.itextpdf.io.font.PdfEncodings;
4546
import com.itextpdf.io.font.TrueTypeFont;
4647
import com.itextpdf.io.util.StreamUtil;
4748
import com.itextpdf.test.ExtendedITextTest;
4849
import com.itextpdf.test.annotations.type.UnitTest;
50+
51+
import java.io.FileNotFoundException;
4952
import org.junit.Assert;
5053
import org.junit.Test;
5154
import org.junit.experimental.categories.Category;
@@ -192,4 +195,59 @@ public void testContentReplacingWithNullActualText() throws IOException {
192195
// Test that no exception has been thrown. Also check the content.
193196
Assert.assertEquals("Belarus", lineToBeReplaced.toString());
194197
}
198+
199+
@Test
200+
public void testActualTextForSubstitutedGlyphProcessingInSubstituteOneToMany01() throws IOException {
201+
String expectedActualTextForFirstGlyph = "0";
202+
String expectedActualTextForSecondGlyph = "A";
203+
204+
byte[] ttf = StreamUtil.inputStreamToArray(new FileInputStream("./src/test/resources/com/itextpdf/io/font/otf/FreeSans.ttf"));
205+
TrueTypeFont font = new TrueTypeFont(ttf);
206+
207+
// no actual text for the second glyph is set - it should be created during substitution
208+
GlyphLine line = new GlyphLine(constructGlyphListFromString("AA", font));
209+
line.setActualText(0, 1, expectedActualTextForFirstGlyph);
210+
line.idx = 1;
211+
212+
line.substituteOneToMany(font.getGsubTable(), new int[] {39, 40});
213+
214+
Assert.assertNotNull(line.actualText);
215+
Assert.assertEquals(3, line.actualText.size());
216+
Assert.assertSame(line.actualText.get(1), line.actualText.get(2));
217+
Assert.assertEquals(expectedActualTextForSecondGlyph, line.actualText.get(1).value);
218+
// check that it hasn't been corrupted
219+
Assert.assertEquals(expectedActualTextForFirstGlyph, line.actualText.get(0).value);
220+
}
221+
222+
@Test
223+
public void testActualTextForSubstitutedGlyphProcessingInSubstituteOneToMany02() throws IOException {
224+
String expectedActualTextForFirstGlyph = "A";
225+
226+
byte[] ttf = StreamUtil.inputStreamToArray(new FileInputStream("./src/test/resources/com/itextpdf/io/font/otf/FreeSans.ttf"));
227+
TrueTypeFont font = new TrueTypeFont(ttf);
228+
229+
GlyphLine line = new GlyphLine(constructGlyphListFromString("A", font));
230+
line.setActualText(0, 1, expectedActualTextForFirstGlyph);
231+
232+
line.substituteOneToMany(font.getGsubTable(), new int[] {39, 40});
233+
234+
Assert.assertNotNull(line.actualText);
235+
Assert.assertEquals(2, line.actualText.size());
236+
Assert.assertSame(line.actualText.get(0), line.actualText.get(1));
237+
Assert.assertEquals(expectedActualTextForFirstGlyph, line.actualText.get(0).value);
238+
}
239+
240+
@Test
241+
public void testActualTextForSubstitutedGlyphProcessingInSubstituteOneToMany03() throws IOException {
242+
byte[] ttf = StreamUtil.inputStreamToArray(new FileInputStream("./src/test/resources/com/itextpdf/io/font/otf/FreeSans.ttf"));
243+
TrueTypeFont font = new TrueTypeFont(ttf);
244+
245+
// no actual text is set
246+
GlyphLine line = new GlyphLine(constructGlyphListFromString("A", font));
247+
248+
line.substituteOneToMany(font.getGsubTable(), new int[] {39, 40});
249+
250+
Assert.assertNull(line.actualText);
251+
}
195252
}
253+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This software uses the following test resources under the following licenses:
2+
| FreeSans | GPL | https://www.gnu.org/licenses |
3+
| FreeSansBold | GPL | https://www.gnu.org/licenses |

0 commit comments

Comments
 (0)