svn commit: r1808238 - in /xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox: MergeCFFFonts.java OTFSubSetFile.java

[email protected]
Newsgroups gmane.text.xml.fop.cvs
Message-ID <[email protected]>
Author: ssteiner
Date: Wed Sep 13 14:06:05 2017
New Revision: 1808238

URL: http://svn.apache.org/viewvc?rev=1808238&view=rev
Log:
Cleanup offset code

Modified:
    xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java
    xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/OTFSubSetFile.java

Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java?rev=1808238&r1=1808237&r2=1808238&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java Wed Sep 13 14:06:05 2017
@@ -234,14 +234,10 @@ public class MergeCFFFonts extends OTFSu
         //Name Index
         writeIndex(Arrays.asList(fileFont.getName().getBytes("UTF-8")));
 
-        //Keep offset of the topDICT so it can be updated once all data has been written
-        int topDictOffset = currentPos;
+        Offsets offsets = new Offsets();
+
         //Top DICT Index and Data
-        byte[] topDictIndex = cffReader.getTopDictIndex().getByteData();
-        int offSize = topDictIndex[2];
-        writeBytes(topDictIndex, 0, 3 + (offSize * 2));
-        int topDictDataOffset = currentPos;
-        writeTopDICT();
+        offsets.topDictData = currentPos + writeTopDICT();
         createCharStringData();
 
         //String index
@@ -250,26 +246,25 @@ public class MergeCFFFonts extends OTFSu
         Map<String, CFFDataReader.DICTEntry> topDICT = cffReader.getTopDictEntries();
         final CFFDataReader.DICTEntry charString = topDICT.get("CharStrings");
         final CFFDataReader.DICTEntry encodingEntry = topDICT.get("Encoding");
-
-        int encodingOffset;
+        boolean hasFDSelect = cffReader.getFDSelect() != null;
         if (encodingEntry != null && charString.getOffset() > encodingEntry.getOffset()) {
             charsetOffset = currentPos;
             if (!fallbackIndex) {
                 charsetOffset += 2;
             }
-            writeCharsetTable(cffReader.getFDSelect() != null, !fallbackIndex);
-            encodingOffset = currentPos;
+            writeCharsetTable(hasFDSelect, !fallbackIndex);
+            offsets.encoding = currentPos;
             writeEncoding();
         } else {
             writeCard16(0);
-            encodingOffset = currentPos;
+            offsets.encoding = currentPos;
             writeEncoding();
             charsetOffset = currentPos;
-            writeCharsetTable(cffReader.getFDSelect() != null, false);
+            writeCharsetTable(hasFDSelect, false);
         }
 
-        int fdSelectOffset = currentPos;
-        if (cffReader.getFDSelect() != null) {
+        offsets.fdSelect = currentPos;
+        if (hasFDSelect) {
             writeByte(0);
             for (int i = 0; i < subsetCharStringsIndex.size(); i++) {
                 writeByte(0);
@@ -277,37 +272,31 @@ public class MergeCFFFonts extends OTFSu
         }
 
         //Keep offset to modify later with the local subroutine index offset
-        int privateDictOffset = currentPos;
+        offsets.privateDict = currentPos;
         writePrivateDict();
 
         //Char Strings Index
-        int charStringOffset = currentPos;
+        offsets.charString = currentPos;
         writeIndex(subsetCharStringsIndex);
 
         //Local subroutine index
-        int localIndexOffset = currentPos;
+        offsets.localIndex = currentPos;
         if (!subsetLocalIndexSubr.isEmpty()) {
             writeIndex(subsetLocalIndexSubr);
         }
 
-        if (cffReader.getFDSelect() != null) {
-            int fdArrayOffset = currentPos;
-            writeCard16(1);
-            writeByte(1); //Offset size
-            writeByte(1); //First offset
-            int count = 1;
+        if (hasFDSelect) {
+            offsets.fdArray = currentPos;
+            int fdByteData = currentPos + cffReader.getFDFonts().size() + 4;
+            List<byte[]> index = new ArrayList<byte[]>();
+            List<Integer> privateDictOffsets = new ArrayList<Integer>();
             for (CFFDataReader.FontDict fdFont : cffReader.getFDFonts()) {
-                count += fdFont.getByteData().length;
-                writeByte(count);
+                index.add(fdFont.getByteData());
             }
-            int fdByteData = currentPos;
+            writeIndex(index, 1);
             for (CFFDataReader.FontDict fdFont : cffReader.getFDFonts()) {
-                writeBytes(fdFont.getByteData());
-            }
-            List<Integer> privateDictOffsets = new ArrayList<Integer>();
-            for (CFFDataReader.FontDict curFDFont : cffReader.getFDFonts()) {
                 privateDictOffsets.add(currentPos);
-                writeBytes(curFDFont.getPrivateDictData());
+                writeBytes(fdFont.getPrivateDictData());
                 writeIndex(new ArrayList<byte[]>());
             }
             currentPos = fdByteData;
@@ -325,12 +314,10 @@ public class MergeCFFFonts extends OTFSu
                 i++;
             }
 
-            updateCIDOffsets(topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset, charStringOffset,
-                    encodingOffset);
+            updateCIDOffsets(offsets);
         } else {
             //Update the offsets
-            updateOffsets(topDictOffset, charsetOffset, charStringOffset, privateDictOffset, localIndexOffset,
-                    encodingOffset);
+            updateOffsets(offsets);
         }
     }
 
@@ -469,12 +456,11 @@ public class MergeCFFFonts extends OTFSu
     }
 
     @Override
-    protected void updateFixedOffsets(Map<String, CFFDataReader.DICTEntry> topDICT, int dataTopDictOffset,
-                                      int charsetOffset, int charStringOffset, int encodingOffset) {
+    protected void updateFixedOffsets(Map<String, CFFDataReader.DICTEntry> topDICT, Offsets offsets) {
         //Charset offset in the top dict
         final CFFDataReader.DICTEntry charset = topDICT.get("charset");
         if (charset != null) {
-            int oldCharsetOffset = dataTopDictOffset + charset.getOffset();
+            int oldCharsetOffset = offsets.topDictData + charset.getOffset();
             int oldCharset = Integer.parseInt(String.format("%02x", output[oldCharsetOffset] & 0xff), 16);
             if (oldCharset >= 32 && oldCharset <= 246) {
                 charsetOffset += 139;
@@ -484,30 +470,26 @@ public class MergeCFFFonts extends OTFSu
 
         //Char string index offset in the private dict
         final CFFDataReader.DICTEntry charString = topDICT.get("CharStrings");
-        int oldCharStringOffset = dataTopDictOffset + charString.getOffset();
+        int oldCharStringOffset = offsets.topDictData + charString.getOffset();
         int oldString = Integer.parseInt(String.format("%02x", output[oldCharStringOffset] & 0xff), 16);
         if (oldString >= 32 && oldString <= 246) {
-            charStringOffset += 139;
+            offsets.charString += 139;
         }
         if (!(fileFont.getCharset() instanceof CFFISOAdobeCharset)) {
-            updateOffset(output, oldCharStringOffset, charString.getOperandLength(), charStringOffset);
+            updateOffset(output, oldCharStringOffset, charString.getOperandLength(), offsets.charString);
         }
 
         final CFFDataReader.DICTEntry encodingEntry = topDICT.get("Encoding");
         if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0
                 && encodingEntry.getOperands().get(0).intValue() != 1) {
-            int oldEncodingOffset = dataTopDictOffset + encodingEntry.getOffset();
+            int oldEncodingOffset = offsets.topDictData + encodingEntry.getOffset();
             int oldEnc = Integer.parseInt(String.format("%02x", output[oldEncodingOffset] & 0xff), 16);
             if (oldEnc >= 32 && oldEnc <= 246) {
-                encodingOffset += 139;
+                offsets.encoding += 139;
             } else {
-                encodingOffset--;
+                offsets.encoding--;
             }
-            updateOffset(output, oldEncodingOffset, encodingEntry.getOperandLength(), encodingOffset);
+            updateOffset(output, oldEncodingOffset, encodingEntry.getOperandLength(), offsets.encoding);
         }
     }
-
-    protected void writeCIDCount(CFFDataReader.DICTEntry dictEntry) throws IOException {
-        writeBytes(dictEntry.getByteData());
-    }
 }

Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/OTFSubSetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/OTFSubSetFile.java?rev=1808238&r1=1808237&r2=1808238&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/OTFSubSetFile.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/OTFSubSetFile.java Wed Sep 13 14:06:05 2017
@@ -67,27 +67,31 @@ public abstract class OTFSubSetFile exte
         super();
     }
 
-    protected void writeTopDICT() throws IOException {
+    protected int writeTopDICT() throws IOException {
         Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
         List<String> topDictStringEntries = Arrays.asList("version", "Notice", "Copyright",
                 "FullName", "FamilyName", "Weight", "PostScript");
+        ByteArrayOutputStream dict = new ByteArrayOutputStream();
         for (Map.Entry<String, DICTEntry> dictEntry : topDICT.entrySet()) {
             String dictKey = dictEntry.getKey();
             DICTEntry entry = dictEntry.getValue();
             //If the value is an SID, update the reference but keep the size the same
             if (dictKey.equals("ROS")) {
-                writeROSEntry(entry);
+                dict.write(writeROSEntry(entry));
             } else if (dictKey.equals("CIDCount")) {
-                writeCIDCount(entry);
+                dict.write(writeCIDCount(entry));
             } else if (topDictStringEntries.contains(dictKey)) {
-                writeTopDictStringEntry(entry);
+                dict.write(writeTopDictStringEntry(entry));
             } else {
-                writeBytes(entry.getByteData());
+                dict.write(entry.getByteData());
             }
         }
+        byte[] topDictIndex = cffReader.getTopDictIndex().getByteData();
+        int offSize = topDictIndex[2];
+        return writeIndex(Arrays.asList(dict.toByteArray()), offSize) - dict.size();
     }
 
-    private void writeROSEntry(DICTEntry dictEntry) throws IOException {
+    private byte[] writeROSEntry(DICTEntry dictEntry) throws IOException {
         int sidA = dictEntry.getOperands().get(0).intValue();
         if (sidA > 390) {
             stringIndexData.add(cffReader.getStringIndex().getValue(sidA - NUM_STANDARD_STRINGS));
@@ -105,12 +109,14 @@ public abstract class OTFSubSetFile exte
                 dictEntry.getOperandLengths().get(1), sidBStringIndex);
         updateOffset(cidEntryByteData, dictEntry.getOperandLengths().get(0)
                 + dictEntry.getOperandLengths().get(1), dictEntry.getOperandLengths().get(2), 139);
-        writeBytes(cidEntryByteData);
+        return cidEntryByteData;
     }
 
-    protected abstract void writeCIDCount(DICTEntry dictEntry) throws IOException;
+    protected byte[] writeCIDCount(DICTEntry dictEntry) throws IOException {
+        return dictEntry.getByteData();
+    }
 
-    private void writeTopDictStringEntry(DICTEntry dictEntry) throws IOException {
+    private byte[] writeTopDictStringEntry(DICTEntry dictEntry) throws IOException {
         int sid = dictEntry.getOperands().get(0).intValue();
         if (sid > 391) {
             stringIndexData.add(cffReader.getStringIndex().getValue(sid - 391));
@@ -118,7 +124,7 @@ public abstract class OTFSubSetFile exte
 
         byte[] newDictEntry = createNewRef(stringIndexData.size() + 390, dictEntry.getOperator(),
                 dictEntry.getOperandLength());
-        writeBytes(newDictEntry);
+        return newDictEntry;
     }
 
     public static byte[] createNewRef(int newRef, int[] operatorCode, int forceLength) {
@@ -164,24 +170,21 @@ public abstract class OTFSubSetFile exte
     }
 
     protected int writeIndex(List<byte[]> dataArray) {
+        int totLength = 1;
+        for (byte[] aDataArray1 : dataArray) {
+            totLength += aDataArray1.length;
+        }
+        int offSize = getOffSize(totLength);
+        return writeIndex(dataArray, offSize);
+    }
+
+    protected int writeIndex(List<byte[]> dataArray, int offSize) {
         int hdrTotal = 3;
         //2 byte number of items
         this.writeCard16(dataArray.size());
         //Offset Size: 1 byte = 256, 2 bytes = 65536 etc.
-        int totLength = 0;
-        for (byte[] aDataArray1 : dataArray) {
-            totLength += aDataArray1.length;
-        }
-        int offSize = 1;
-        if (totLength <= (1 << 8)) {
-            offSize = 1;
-        } else if (totLength <= (1 << 16)) {
-            offSize = 2;
-        } else if (totLength <= (1 << 24)) {
-            offSize = 3;
-        } else {
-            offSize = 4;
-        }
+        //Offsets in the offset array are relative to the byte that precedes the object data.
+        //Therefore the first element of the offset array is always 1.
         this.writeByte(offSize);
         //Count the first offset 1
         hdrTotal += offSize;
@@ -228,6 +231,20 @@ public abstract class OTFSubSetFile exte
         return hdrTotal + total;
     }
 
+    private int getOffSize(int totLength) {
+        int offSize = 1;
+        if (totLength < (1 << 8)) {
+            offSize = 1;
+        } else if (totLength < (1 << 16)) {
+            offSize = 2;
+        } else if (totLength < (1 << 24)) {
+            offSize = 3;
+        } else {
+            offSize = 4;
+        }
+        return offSize;
+    }
+
     protected void writePrivateDict() throws IOException {
         Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
 
@@ -237,8 +254,7 @@ public abstract class OTFSubSetFile exte
         }
     }
 
-    protected void updateOffsets(int topDictOffset, int charsetOffset, int charStringOffset,
-                                 int privateDictOffset, int localIndexOffset, int encodingOffset) throws IOException {
+    protected void updateOffsets(Offsets offsets) throws IOException {
         Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
         Map<String, DICTEntry> privateDICT = null;
 
@@ -247,53 +263,57 @@ public abstract class OTFSubSetFile exte
             privateDICT = cffReader.getPrivateDict(privateEntry);
         }
 
-        int dataPos = 3 + (cffReader.getTopDictIndex().getOffSize()
-                * cffReader.getTopDictIndex().getOffsets().length);
-        int dataTopDictOffset = topDictOffset + dataPos;
-
-        updateFixedOffsets(topDICT, dataTopDictOffset, charsetOffset, charStringOffset, encodingOffset);
+        updateFixedOffsets(topDICT, offsets);
 
         if (privateDICT != null) {
             //Private index offset in the top dict
-            int oldPrivateOffset = dataTopDictOffset + privateEntry.getOffset();
+            int oldPrivateOffset = offsets.topDictData + privateEntry.getOffset();
             updateOffset(output, oldPrivateOffset + privateEntry.getOperandLengths().get(0),
-                    privateEntry.getOperandLengths().get(1), privateDictOffset);
+                    privateEntry.getOperandLengths().get(1), offsets.privateDict);
 
             //Update the local subroutine index offset in the private dict
             DICTEntry subroutines = privateDICT.get("Subrs");
             if (subroutines != null) {
-                int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
+                int oldLocalSubrOffset = offsets.privateDict + subroutines.getOffset();
                 //Value needs to be converted to -139 etc.
                 int encodeValue = 0;
                 if (subroutines.getOperandLength() == 1) {
                     encodeValue = 139;
                 }
                 updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
-                        (localIndexOffset - privateDictOffset) + encodeValue);
+                        (offsets.localIndex - offsets.privateDict) + encodeValue);
             }
         }
     }
 
-    protected abstract void updateFixedOffsets(Map<String, DICTEntry> topDICT, int dataTopDictOffset,
-                                               int charsetOffset, int charStringOffset, int encodingOffset);
+    static class Offsets {
+        Integer topDictData;
+        Integer encoding;
+        Integer fdSelect;
+        Integer charString;
+        Integer fdArray;
+        Integer privateDict;
+        Integer localIndex;
+    }
+
+    protected abstract void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets);
 
-    protected void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
-                                    int charsetOffset, int charStringOffset, int encodingOffset) {
+    protected void updateCIDOffsets(Offsets offsets) {
         Map<String, DICTEntry> topDict = cffReader.getTopDictEntries();
 
         DICTEntry fdArrayEntry = topDict.get("FDArray");
         if (fdArrayEntry != null) {
-            updateOffset(output, topDictDataOffset + fdArrayEntry.getOffset() - 1,
-                    fdArrayEntry.getOperandLength(), fdArrayOffset);
+            updateOffset(output, offsets.topDictData + fdArrayEntry.getOffset() - 1,
+                    fdArrayEntry.getOperandLength(), offsets.fdArray);
         }
 
         DICTEntry fdSelect = topDict.get("FDSelect");
         if (fdSelect != null) {
-            updateOffset(output, topDictDataOffset + fdSelect.getOffset() - 1,
-                    fdSelect.getOperandLength(), fdSelectOffset);
+            updateOffset(output, offsets.topDictData + fdSelect.getOffset() - 1,
+                    fdSelect.getOperandLength(), offsets.fdSelect);
         }
 
-        updateFixedOffsets(topDict, topDictDataOffset, charsetOffset, charStringOffset, encodingOffset);
+        updateFixedOffsets(topDict, offsets);
     }
 
     protected void updateOffset(byte[] out, int position, int length, int replacement) {
@@ -302,6 +322,7 @@ public abstract class OTFSubSetFile exte
                 out[position] = (byte)(replacement & 0xFF);
                 break;
             case 2:
+                assert replacement <= 1131;
                 if (replacement <= 363) {
                     out[position] = (byte)247;
                 } else if (replacement <= 619) {
@@ -314,6 +335,7 @@ public abstract class OTFSubSetFile exte
                 out[position + 1] = (byte)(replacement - 108);
                 break;
             case 3:
+                assert replacement <= 32767;
                 out[position] = (byte)28;
                 out[position + 1] = (byte)((replacement >> 8) & 0xFF);
                 out[position + 2] = (byte)(replacement & 0xFF);
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.