Skip to content

Commit a4d916e

Browse files
committed
Otf features refactoring for autoport.
1 parent b44bf3b commit a4d916e

File tree

9 files changed

+114
-104
lines changed

9 files changed

+114
-104
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.itextpdf.io.font.otf;
2+
3+
import com.itextpdf.io.util.TextUtil;
4+
5+
import java.util.Iterator;
6+
7+
public class ActualTextIterator implements Iterator<GlyphLine.GlyphLinePart> {
8+
9+
private GlyphLine glyphLine;
10+
11+
public ActualTextIterator(GlyphLine glyphLine) {
12+
this.glyphLine = glyphLine;
13+
this.pos = glyphLine.start;
14+
}
15+
16+
public ActualTextIterator(GlyphLine glyphLine, int start, int end) {
17+
this(new GlyphLine(glyphLine.glyphs, glyphLine.actualText, start, end));
18+
}
19+
20+
private int pos;
21+
22+
@Override
23+
public boolean hasNext() {
24+
return pos < glyphLine.end;
25+
}
26+
27+
@Override
28+
public GlyphLine.GlyphLinePart next() {
29+
if (glyphLine.actualText == null) {
30+
GlyphLine.GlyphLinePart result = new GlyphLine.GlyphLinePart(pos, glyphLine.end, null);
31+
pos = glyphLine.end;
32+
return result;
33+
} else {
34+
GlyphLine.GlyphLinePart currentResult = nextGlyphLinePart(pos);
35+
if (currentResult == null) {
36+
return null;
37+
}
38+
pos = currentResult.end;
39+
while (pos < glyphLine.end && !glyphLinePartNeedsActualText(currentResult)) {
40+
currentResult.actualText = null;
41+
GlyphLine.GlyphLinePart nextResult = nextGlyphLinePart(pos);
42+
if (nextResult != null && !glyphLinePartNeedsActualText(nextResult)) {
43+
currentResult.end = nextResult.end;
44+
pos = nextResult.end;
45+
} else {
46+
break;
47+
}
48+
}
49+
return currentResult;
50+
}
51+
}
52+
53+
@Override
54+
public void remove() {
55+
throw new IllegalStateException("Operation not supported");
56+
}
57+
58+
private GlyphLine.GlyphLinePart nextGlyphLinePart(int pos) {
59+
if (pos >= glyphLine.end) {
60+
return null;
61+
}
62+
int startPos = pos;
63+
GlyphLine.ActualText startActualText = glyphLine.actualText.get(pos);
64+
while (pos < glyphLine.end && glyphLine.actualText.get(pos) == startActualText) {
65+
pos++;
66+
}
67+
return new GlyphLine.GlyphLinePart(startPos, pos, startActualText != null ? startActualText.value : null);
68+
}
69+
70+
private boolean glyphLinePartNeedsActualText(GlyphLine.GlyphLinePart glyphLinePart) {
71+
if (glyphLinePart.actualText == null) {
72+
return false;
73+
}
74+
boolean needsActualText = false;
75+
StringBuilder toUnicodeMapResult = new StringBuilder();
76+
for (int i = glyphLinePart.start; i < glyphLinePart.end; i++) {
77+
Glyph currentGlyph = glyphLine.glyphs.get(i);
78+
if (currentGlyph.getUnicode() == null) {
79+
needsActualText = true;
80+
break;
81+
}
82+
// TODO zero glyph is a special case. Unicode might be special
83+
toUnicodeMapResult.append(TextUtil.convertFromUtf32(currentGlyph.getUnicode()));
84+
}
85+
86+
return needsActualText || !toUnicodeMapResult.toString().equals(glyphLinePart.actualText);
87+
}
88+
}

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

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
import com.itextpdf.io.util.TextUtil;
44

55
import java.util.ArrayList;
6-
import java.util.Collections;
76
import java.util.Iterator;
87
import java.util.List;
98

10-
public class GlyphLine implements Iterable<GlyphLine.GlyphLinePart> {
9+
public class GlyphLine {
1110
protected List<Glyph> glyphs;
1211
protected List<ActualText> actualText;
1312
public int start;
@@ -54,7 +53,7 @@ public GlyphLine(GlyphLine other, int start, int end) {
5453
}
5554

5655
public String toUnicodeString(int start, int end) {
57-
Iterator<GlyphLinePart> iter = new GlyphLinePartIterator(this, start, end);
56+
Iterator<GlyphLinePart> iter = new ActualTextIterator(this, start, end);
5857
StringBuilder str = new StringBuilder();
5958
while (iter.hasNext()) {
6059
GlyphLinePart part = iter.next();
@@ -226,9 +225,8 @@ public void setActualText(int left, int right, String text) {
226225
}
227226
}
228227

229-
@Override
230228
public Iterator<GlyphLinePart> iterator() {
231-
return new GlyphLinePartIterator(this);
229+
return new ActualTextIterator(this);
232230
}
233231

234232
private void removeGlyph(int index) {
@@ -270,87 +268,4 @@ public ActualText(String value) {
270268

271269
public String value;
272270
}
273-
274-
private static class GlyphLinePartIterator implements Iterator<GlyphLinePart> {
275-
276-
private GlyphLine glyphLine;
277-
278-
public GlyphLinePartIterator(GlyphLine glyphLine) {
279-
this.glyphLine = glyphLine;
280-
this.pos = glyphLine.start;
281-
}
282-
283-
public GlyphLinePartIterator(GlyphLine glyphLine, int start, int end) {
284-
this(new GlyphLine(glyphLine.glyphs, glyphLine.actualText, start, end));
285-
}
286-
287-
private int pos;
288-
289-
@Override
290-
public boolean hasNext() {
291-
return pos < glyphLine.end;
292-
}
293-
294-
@Override
295-
public GlyphLinePart next() {
296-
if (glyphLine.actualText == null) {
297-
GlyphLinePart result = new GlyphLinePart(pos, glyphLine.end, null);
298-
pos = glyphLine.end;
299-
return result;
300-
} else {
301-
GlyphLinePart currentResult = nextGlyphLinePart(pos);
302-
if (currentResult == null) {
303-
return null;
304-
}
305-
pos = currentResult.end;
306-
while (pos < glyphLine.end && !glyphLinePartNeedsActualText(currentResult)) {
307-
currentResult.actualText = null;
308-
GlyphLinePart nextResult = nextGlyphLinePart(pos);
309-
if (nextResult != null && !glyphLinePartNeedsActualText(nextResult)) {
310-
currentResult.end = nextResult.end;
311-
pos = nextResult.end;
312-
} else {
313-
break;
314-
}
315-
}
316-
return currentResult;
317-
}
318-
}
319-
320-
@Override
321-
public void remove() {
322-
throw new IllegalStateException("Operation not supported");
323-
}
324-
325-
private GlyphLinePart nextGlyphLinePart(int pos) {
326-
if (pos >= glyphLine.end) {
327-
return null;
328-
}
329-
int startPos = pos;
330-
ActualText startActualText = glyphLine.actualText.get(pos);
331-
while (pos < glyphLine.end && glyphLine.actualText.get(pos) == startActualText) {
332-
pos++;
333-
}
334-
return new GlyphLinePart(startPos, pos, startActualText != null ? startActualText.value : null);
335-
}
336-
337-
private boolean glyphLinePartNeedsActualText(GlyphLinePart glyphLinePart) {
338-
if (glyphLinePart.actualText == null) {
339-
return false;
340-
}
341-
boolean needsActualText = false;
342-
StringBuilder toUnicodeMapResult = new StringBuilder();
343-
for (int i = glyphLinePart.start; i < glyphLinePart.end; i++) {
344-
Glyph currentGlyph = glyphLine.glyphs.get(i);
345-
if (currentGlyph.getUnicode() == null) {
346-
needsActualText = true;
347-
break;
348-
}
349-
// TODO zero glyph is a special case. Unicode might be special
350-
toUnicodeMapResult.append(TextUtil.convertFromUtf32(currentGlyph.getUnicode()));
351-
}
352-
353-
return needsActualText || !toUnicodeMapResult.toString().equals(glyphLinePart.actualText);
354-
}
355-
}
356271
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.HashSet;
66
import java.util.List;
77
import java.util.Map;
8-
import java.util.Set;
8+
99

1010
/**
1111
* Lookup Type 2:
@@ -118,7 +118,7 @@ protected void readSubTable(int subTableLocation) throws java.io.IOException {
118118
private static class PairPosAdjustmentFormat2 extends OpenTableLookup {
119119
private OtfClass classDef1;
120120
private OtfClass classDef2;
121-
private Set<Integer> coverageSet;
121+
private HashSet<Integer> coverageSet;
122122
private Map<Integer,PairValueFormat[]> posSubs = new HashMap<>();
123123

124124
public PairPosAdjustmentFormat2(OpenTypeFontTableReader openReader, int lookupFlag, int subtableLocation) throws java.io.IOException {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ protected void readSubTableFormat2(int subTableLocation) throws java.io.IOExcept
137137
int[] inputClassIds = openReader.readUShortArray(glyphCount - 1);
138138
SubstLookupRecord[] substLookupRecords = openReader.readSubstLookupRecords(substCount);
139139

140-
rule = t.new SubstRuleFormat2(inputClassIds, substLookupRecords);
140+
rule = new SubTableLookup5Format2.SubstRuleFormat2(t, inputClassIds, substLookupRecords);
141141
subClassSet.add(rule);
142142
}
143143
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ protected void readSubTableFormat2(int subTableLocation) throws java.io.IOExcept
9292
int substCount = openReader.rf.readUnsignedShort();
9393
SubstLookupRecord[] substLookupRecords = openReader.readSubstLookupRecords(substCount);
9494

95-
rule = t.new SubstRuleFormat2(backtrackClassIds, inputClassIds, lookAheadClassIds, substLookupRecords);
95+
rule = new SubTableLookup6Format2.SubstRuleFormat2(t, backtrackClassIds, inputClassIds, lookAheadClassIds, substLookupRecords);
9696
subClassSet.add(rule);
9797
}
9898
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import com.itextpdf.io.source.RandomAccessFileOrArray;
4949

5050
import java.util.ArrayList;
51-
import java.util.Collections;
5251
import java.util.HashSet;
5352
import java.util.List;
5453
import java.util.Map;
@@ -158,7 +157,10 @@ public List<FeatureRecord> getSpecificFeatures(List<FeatureRecord> features, Str
158157
return features;
159158
}
160159
Set<String> hs = new HashSet<String>();
161-
Collections.addAll(hs, specific);
160+
//noinspection ManualArrayToCollectionCopy
161+
for (String s : specific) {
162+
hs.add(s);
163+
}
162164
List<FeatureRecord> recs = new ArrayList<FeatureRecord>();
163165
for (FeatureRecord rec : features) {
164166
if (hs.contains(rec.tag)) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import java.text.MessageFormat;
66
import java.util.ArrayList;
7-
import java.util.Collections;
87
import java.util.HashSet;
98
import java.util.List;
109
import java.util.Set;
@@ -52,7 +51,8 @@ public static List<Integer> readCoverageFormat(RandomAccessFileOrArray rf, int c
5251
throw new UnsupportedOperationException(MessageFormat.format("Invalid coverage format: {0}", coverageFormat));
5352
}
5453

55-
return Collections.unmodifiableList(glyphIds);
54+
//return Collections.unmodifiableList(glyphIds);
55+
return glyphIds;
5656
}
5757

5858
private static void readRangeRecord(RandomAccessFileOrArray rf, List<Integer> glyphIds) throws java.io.IOException {

io/src/main/java/com/itextpdf/io/font/otf/lookuptype5/SubTableLookup5Format2.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,17 @@ protected List<ContextualSubstRule> getSetOfRulesForStartGlyph(int startId) {
3939
return new ArrayList<>(0);
4040
}
4141

42-
public class SubstRuleFormat2 extends ContextualSubstRule {
42+
public static class SubstRuleFormat2 extends ContextualSubstRule {
4343
// inputClassIds array omits the first class in the sequence,
4444
// the first class is defined by corresponding index of subClassSet array
4545
private int[] inputClassIds;
4646
private SubstLookupRecord[] substLookupRecords;
47+
private OtfClass classDefinition;
4748

48-
public SubstRuleFormat2(int[] inputClassIds, SubstLookupRecord[] substLookupRecords) {
49+
public SubstRuleFormat2(SubTableLookup5Format2 subTable, int[] inputClassIds, SubstLookupRecord[] substLookupRecords) {
4950
this.inputClassIds = inputClassIds;
5051
this.substLookupRecords = substLookupRecords;
52+
this.classDefinition = subTable.classDefinition;
5153
}
5254

5355
@Override
@@ -64,6 +66,5 @@ public SubstLookupRecord[] getSubstLookupRecords() {
6466
public boolean isGlyphMatchesInput(int glyphId, int atIdx) {
6567
return classDefinition.getOtfClass(glyphId) == inputClassIds[atIdx - 1];
6668
}
67-
6869
}
6970
}

io/src/main/java/com/itextpdf/io/font/otf/lookuptype6/SubTableLookup6Format2.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ protected List<ContextualSubstRule> getSetOfRulesForStartGlyph(int startId) {
4242
return new ArrayList<>(0);
4343
}
4444

45-
public class SubstRuleFormat2 extends ContextualSubstRule {
45+
public static class SubstRuleFormat2 extends ContextualSubstRule {
4646
// inputClassIds array omits the first class in the sequence,
4747
// the first class is defined by corresponding index of subClassSet array
4848
private int[] backtrackClassIds;
@@ -51,7 +51,11 @@ public class SubstRuleFormat2 extends ContextualSubstRule {
5151

5252
private SubstLookupRecord[] substLookupRecords;
5353

54-
public SubstRuleFormat2(int[] backtrackClassIds, int[] inputClassIds, int[] lookAheadClassIds, SubstLookupRecord[] substLookupRecords) {
54+
private SubTableLookup6Format2 subTable;
55+
56+
public SubstRuleFormat2(SubTableLookup6Format2 subTable, int[] backtrackClassIds, int[] inputClassIds,
57+
int[] lookAheadClassIds, SubstLookupRecord[] substLookupRecords) {
58+
this.subTable = subTable;
5559
this.backtrackClassIds = backtrackClassIds;
5660
this.inputClassIds = inputClassIds;
5761
this.lookAheadClassIds = lookAheadClassIds;
@@ -78,15 +82,15 @@ public SubstLookupRecord[] getSubstLookupRecords() {
7882

7983
@Override
8084
public boolean isGlyphMatchesInput(int glyphId, int atIdx) {
81-
return inputClassDefinition.getOtfClass(glyphId) == inputClassIds[atIdx - 1];
85+
return subTable.inputClassDefinition.getOtfClass(glyphId) == inputClassIds[atIdx - 1];
8286
}
8387
@Override
8488
public boolean isGlyphMatchesLookahead(int glyphId, int atIdx) {
85-
return lookaheadClassDefinition.getOtfClass(glyphId) == lookAheadClassIds[atIdx];
89+
return subTable.lookaheadClassDefinition.getOtfClass(glyphId) == lookAheadClassIds[atIdx];
8690
}
8791
@Override
8892
public boolean isGlyphMatchesBacktrack(int glyphId, int atIdx) {
89-
return backtrackClassDefinition.getOtfClass(glyphId) == backtrackClassIds[atIdx];
93+
return subTable.backtrackClassDefinition.getOtfClass(glyphId) == backtrackClassIds[atIdx];
9094
}
9195
}
9296
}

0 commit comments

Comments
 (0)