svn commit: r1808210 - in /xmlgraphics/fop/trunk/fop-core/src: main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java

[email protected]
Newsgroups gmane.text.xml.fop.cvs
Message-ID <[email protected]>
Author: ssteiner
Date: Wed Sep 13 08:32:17 2017
New Revision: 1808210

URL: http://svn.apache.org/viewvc?rev=1808210&view=rev
Log:
FOP-2736: Change font table order depending on offset size

Modified:
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java?rev=1808210&r1=1808209&r2=1808210&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java Wed Sep 13 08:32:17 2017
@@ -174,17 +174,19 @@ public class OTFSubSetFile extends OTFSu
         //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 OTFSu
 
         //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 OTFSu
             //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 {

Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java?rev=1808210&r1=1808209&r2=1808210&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java Wed Sep 13 08:32:17 2017
@@ -583,4 +583,64 @@ public class OTFSubSetFileTestCase exten
             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;
+        }
+    }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.