summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2017-09-13 08:32:17 +0000
committerSimon Steiner <ssteiner@apache.org>2017-09-13 08:32:17 +0000
commit3dc1ca2cb1d36104467d11a7e98024ea12a37c27 (patch)
treeac09f187978ff54a9534e92005b90d78fb33dea5
parentb0eefade3a3ed215b03939436710cf42c15fd937 (diff)
downloadxmlgraphics-fop-3dc1ca2cb1d36104467d11a7e98024ea12a37c27.tar.gz
xmlgraphics-fop-3dc1ca2cb1d36104467d11a7e98024ea12a37c27.zip
FOP-2736: Change font table order depending on offset size
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1808210 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java45
-rw-r--r--fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java60
2 files changed, 93 insertions, 12 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
index 70ac3cb62..ee534ba2e 100644
--- a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
+++ b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
@@ -174,17 +174,19 @@ public class OTFSubSetFile extends OTFSubSetWriter {
//Top DICT Index and Data
int topDictDataOffset = topDictOffset + writeTopDICT();
+ boolean hasFDSelect = cffReader.getFDSelect() != null;
+
//Create the char string index data and related local / global subroutines
- if (cffReader.getFDSelect() == null) {
- createCharStringData();
- } else {
+ if (hasFDSelect) {
createCharStringDataCID();
+ } else {
+ createCharStringData();
}
//If it is a CID-Keyed font, store each FD font and add each SID
List<Integer> fontNameSIDs = null;
List<Integer> subsetFDFonts = null;
- if (cffReader.getFDSelect() != null) {
+ if (hasFDSelect) {
subsetFDFonts = getUsedFDFonts();
fontNameSIDs = storeFDStrings(subsetFDFonts);
}
@@ -200,19 +202,29 @@ public class OTFSubSetFile extends OTFSubSetWriter {
//Charset table
int charsetOffset = currentPos;
- writeCharsetTable(cffReader.getFDSelect() != null);
+ writeCharsetTable(hasFDSelect);
//FDSelect table
int fdSelectOffset = currentPos;
- if (cffReader.getFDSelect() != null) {
+ if (hasFDSelect) {
writeFDSelect();
}
+ int fdArrayOffset = -1;
+ if (hasFDSelect && !isCharStringBeforeFD()) {
+ fdArrayOffset = writeFDArray(subsetFDFonts, fontNameSIDs);
+ }
//Char Strings Index
int charStringOffset = currentPos;
writeIndex(subsetCharStringsIndex);
+ if (hasFDSelect && isCharStringBeforeFD()) {
+ fdArrayOffset = writeFDArray(subsetFDFonts, fontNameSIDs);
+ }
- if (cffReader.getFDSelect() == null) {
+ if (hasFDSelect) {
+ updateCIDOffsets(topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset,
+ charStringOffset, encodingOffset);
+ } else {
//Keep offset to modify later with the local subroutine index offset
int privateDictOffset = currentPos;
writePrivateDict();
@@ -224,13 +236,22 @@ public class OTFSubSetFile extends OTFSubSetWriter {
//Update the offsets
updateOffsets(topDictOffset, charsetOffset, charStringOffset, privateDictOffset,
localIndexOffset, encodingOffset);
- } else {
- List<Integer> privateDictOffsets = writeCIDDictsAndSubrs(subsetFDFonts);
- int fdArrayOffset = writeFDArray(subsetFDFonts, privateDictOffsets, fontNameSIDs);
+ }
+ }
- updateCIDOffsets(topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset,
- charStringOffset, encodingOffset);
+ private int writeFDArray(List<Integer> subsetFDFonts, List<Integer> fontNameSIDs) throws IOException {
+ List<Integer> privateDictOffsets = writeCIDDictsAndSubrs(subsetFDFonts);
+ return writeFDArray(subsetFDFonts, privateDictOffsets, fontNameSIDs);
+ }
+
+ private boolean isCharStringBeforeFD() {
+ LinkedHashMap<String, DICTEntry> entries = cffReader.getTopDictEntries();
+ int len = entries.get("CharStrings").getOperandLength();
+ if (entries.containsKey("FDArray")) {
+ int len2 = entries.get("FDArray").getOperandLength();
+ return len < len2;
}
+ return true;
}
protected List<Integer> storeFDStrings(List<Integer> uniqueNewRefs) throws IOException {
diff --git a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
index 8804dd1bc..b2d12ec90 100644
--- a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
@@ -583,4 +583,64 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase {
return offset;
}
}
+
+ @Test
+ public void testOrderOfEntries() throws IOException {
+ OTFSubSetFileEntryOrder otfSubSetFile = getFont(3, 2);
+ assertTrue(otfSubSetFile.fdArrayOffset < otfSubSetFile.charStringOffset);
+
+ otfSubSetFile = getFont(2, 3);
+ assertTrue(otfSubSetFile.fdArrayOffset > otfSubSetFile.charStringOffset);
+ }
+
+ private OTFSubSetFileEntryOrder getFont(int csLen, int fdLen) throws IOException {
+ glyphs.clear();
+ OTFSubSetFileEntryOrder otfSubSetFile = new OTFSubSetFileEntryOrder(csLen, fdLen);
+ otfSubSetFile.readFont(sourceSansReader, "StandardOpenType", null, glyphs);
+ return otfSubSetFile;
+ }
+
+ static class OTFSubSetFileEntryOrder extends OTFSubSetFile {
+ int fdArrayOffset;
+ int charStringOffset;
+ int csLen;
+ int fdLen;
+
+ public OTFSubSetFileEntryOrder(int csLen, int fdLen) throws IOException {
+ super();
+ this.csLen = csLen;
+ this.fdLen = fdLen;
+ }
+
+ protected void createCFF() throws IOException {
+ cffReader = mock(CFFDataReader.class);
+ when(cffReader.getHeader()).thenReturn(new byte[0]);
+ when(cffReader.getTopDictIndex()).thenReturn(cffReader.new CFFIndexData() {
+ public byte[] getByteData() throws IOException {
+ return new byte[]{0, 0, 1};
+ }
+ });
+ when(cffReader.getFDSelect()).thenReturn(cffReader.new Format3FDSelect());
+
+ LinkedHashMap<String, DICTEntry> topDict = new LinkedHashMap<String, DICTEntry>();
+ DICTEntry entry = new DICTEntry();
+ entry.setOperands(Arrays.<Number>asList(0));
+ topDict.put("charset", entry);
+ entry.setOperandLength(csLen);
+ topDict.put("CharStrings", entry);
+ entry = new DICTEntry();
+ entry.setOperandLength(fdLen);
+ topDict.put("FDArray", entry);
+ when(cffReader.getTopDictEntries()).thenReturn(topDict);
+ super.createCFF();
+ }
+
+ protected void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
+ int charsetOffset, int charStringOffset, int encodingOffset) {
+ super.updateCIDOffsets(
+ topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset, charStringOffset, encodingOffset);
+ this.fdArrayOffset = fdArrayOffset;
+ this.charStringOffset = charStringOffset;
+ }
+ }
}