svn commit: r1811797 - in /xmlgraphics/fop/trunk/fop-core/src: main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.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 Oct 11 07:49:03 2017
New Revision: 1811797

URL: http://svn.apache.org/viewvc?rev=1811797&view=rev
Log:
FOP-2750: Use streams for OTF subsetting

Modified:
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.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=1811797&r1=1811796&r2=1811797&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 Oct 11 07:49:03 2017
@@ -19,8 +19,10 @@
 
 package org.apache.fop.fonts.truetype;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -128,16 +130,11 @@ public class OTFSubSetFile extends OTFSu
         this.mbFont = mbFont;
         fontFile = in;
 
-        currentPos = 0;
-        realSize = 0;
-
         this.embeddedName = embeddedName;
 
         //Sort by the new GID and store in a LinkedHashMap
         subsetGlyphs = sortByValue(usedGlyphs);
 
-        output = new byte[in.getFileSize()];
-
         initializeFont(in);
 
         cffReader = new CFFDataReader(fontFile);
@@ -710,7 +707,13 @@ public class OTFSubSetFile extends OTFSu
             return 1 + (hstemCount + vstemCount  - 1) / 8;
         }
 
-        public int exec(int b0, byte[] data, int dataPos) {
+        private int exec(int b0, byte[] input, int curPos) throws IOException {
+            ByteArrayInputStream bis = new ByteArrayInputStream(input);
+            bis.skip(curPos + 1);
+            return exec(b0, bis);
+        }
+
+        public int exec(int b0, InputStream data) throws IOException {
             int posDelta = 0;
             if ((b0 >= 0 && b0 <= 27) || (b0 >= 29 && b0 <= 31)) {
                 if (b0 == 12) {
@@ -739,7 +742,7 @@ public class OTFSubSetFile extends OTFSu
                     lastOp = b0;
                 }
             } else if (b0 == 28 || (b0 >= 32 && b0 <= 255)) {
-                BytesNumber operand = readNumber(b0, data, dataPos);
+                BytesNumber operand = readNumber(b0, data);
                 pushOperand(operand);
                 posDelta = operand.getNumBytes() - 1;
             } else {
@@ -748,24 +751,24 @@ public class OTFSubSetFile extends OTFSu
             return posDelta;
         }
 
-        private BytesNumber readNumber(int b0, byte[] input, int curPos) {
+        private BytesNumber readNumber(int b0, InputStream input) throws IOException {
             if (b0 == 28) {
-                int b1 = input[curPos + 1] & 0xff;
-                int b2 = input[curPos + 2] & 0xff;
+                int b1 = input.read();
+                int b2 = input.read();
                 return new BytesNumber((int) (short) (b1 << 8 | b2), 3);
             } else if (b0 >= 32 && b0 <= 246) {
                 return new BytesNumber(b0 - 139, 1);
             } else if (b0 >= 247 && b0 <= 250) {
-                int b1 = input[curPos + 1] & 0xff;
+                int b1 = input.read();
                 return new BytesNumber((b0 - 247) * 256 + b1 + 108, 2);
             } else if (b0 >= 251 && b0 <= 254) {
-                int b1 = input[curPos + 1] & 0xff;
+                int b1 = input.read();
                 return new BytesNumber(-(b0 - 251) * 256 - b1 - 108, 2);
             } else if (b0 == 255) {
-                int b1 = input[curPos + 1] & 0xff;
-                int b2 = input[curPos + 2] & 0xff;
-                int b3 = input[curPos + 3] & 0xff;
-                int b4 = input[curPos + 4] & 0xff;
+                int b1 = input.read();
+                int b2 = input.read();
+                int b3 = input.read();
+                int b4 = input.read();
                 return new BytesNumber((b1 << 24 | b2 << 16 | b3 << 8 | b4), 5);
             } else {
                 throw new IllegalArgumentException();
@@ -778,33 +781,28 @@ public class OTFSubSetFile extends OTFSu
         for (int dataPos = 0; dataPos < data.length; dataPos++) {
             int b0 = data[dataPos] & 0xff;
             if (b0 == LOCAL_SUBROUTINE && hasLocalSubroutines) {
-                int subrNumber = getSubrNumber(localIndexSubr.getNumObjects(), type2Parser.popOperand().getNumber());
-                if (!localUniques.contains(subrNumber) && subrNumber < localIndexSubr.getNumObjects()) {
-                    localUniques.add(subrNumber);
-                }
-                if (subrNumber < localIndexSubr.getNumObjects()) {
-                    byte[] subr = localIndexSubr.getValue(subrNumber);
-                    preScanForSubsetIndexSize(subr);
-                } else {
-                    throw new IllegalArgumentException("callsubr out of range");
-                }
+                preScanForSubsetIndexSize(localIndexSubr, localUniques);
             } else if (b0 == GLOBAL_SUBROUTINE && hasGlobalSubroutines) {
-                int subrNumber = getSubrNumber(globalIndexSubr.getNumObjects(), type2Parser.popOperand().getNumber());
-                if (!globalUniques.contains(subrNumber) && subrNumber < globalIndexSubr.getNumObjects()) {
-                    globalUniques.add(subrNumber);
-                }
-                if (subrNumber < globalIndexSubr.getNumObjects()) {
-                    byte[] subr = globalIndexSubr.getValue(subrNumber);
-                    preScanForSubsetIndexSize(subr);
-                } else {
-                    throw new IllegalArgumentException("callgsubr out of range");
-                }
+                preScanForSubsetIndexSize(globalIndexSubr, globalUniques);
             } else  {
                 dataPos += type2Parser.exec(b0, data, dataPos);
             }
         }
     }
 
+    private void preScanForSubsetIndexSize(CFFIndexData indexSubr, List<Integer> uniques) throws IOException {
+        int subrNumber = getSubrNumber(indexSubr.getNumObjects(), type2Parser.popOperand().getNumber());
+        if (!uniques.contains(subrNumber) && subrNumber < indexSubr.getNumObjects()) {
+            uniques.add(subrNumber);
+        }
+        if (subrNumber < indexSubr.getNumObjects()) {
+            byte[] subr = indexSubr.getValue(subrNumber);
+            preScanForSubsetIndexSize(subr);
+        } else {
+            throw new IllegalArgumentException("callgsubr out of range");
+        }
+    }
+
     private int getSubrNumber(int numSubroutines, int operand) {
         int bias = getBias(numSubroutines);
         return bias + operand;
@@ -1111,57 +1109,64 @@ public class OTFSubSetFile extends OTFSu
         if (privateDICT != null) {
             //Private index offset in the top dict
             int oldPrivateOffset = offsets.topDictData + privateEntry.getOffset();
-            updateOffset(output, oldPrivateOffset + privateEntry.getOperandLengths().get(0),
+            updateOffset(oldPrivateOffset + privateEntry.getOperandLengths().get(0),
                     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 = offsets.privateDict + subroutines.getOffset();
-                updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
+                updateOffset(oldLocalSubrOffset, subroutines.getOperandLength(),
                         (offsets.localIndex - offsets.privateDict));
             }
         }
     }
 
-    protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets) {
+    protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets) throws IOException {
         //Charset offset in the top dict
         DICTEntry charset = topDICT.get("charset");
         int oldCharsetOffset = offsets.topDictData + charset.getOffset();
-        updateOffset(output, oldCharsetOffset, charset.getOperandLength(), offsets.charset);
+        updateOffset(oldCharsetOffset, charset.getOperandLength(), offsets.charset);
 
         //Char string index offset in the private dict
         DICTEntry charString = topDICT.get("CharStrings");
         int oldCharStringOffset = offsets.topDictData + charString.getOffset();
-        updateOffset(output, oldCharStringOffset, charString.getOperandLength(), offsets.charString);
+        updateOffset(oldCharStringOffset, charString.getOperandLength(), offsets.charString);
 
         DICTEntry encodingEntry = topDICT.get("Encoding");
         if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0
                 && encodingEntry.getOperands().get(0).intValue() != 1) {
             int oldEncodingOffset = offsets.topDictData + encodingEntry.getOffset();
-            updateOffset(output, oldEncodingOffset, encodingEntry.getOperandLength(), offsets.encoding);
+            updateOffset(oldEncodingOffset, encodingEntry.getOperandLength(), offsets.encoding);
         }
     }
 
-    protected void updateCIDOffsets(Offsets offsets) {
+    protected void updateCIDOffsets(Offsets offsets) throws IOException {
         Map<String, DICTEntry> topDict = cffReader.getTopDictEntries();
 
         DICTEntry fdArrayEntry = topDict.get("FDArray");
         if (fdArrayEntry != null) {
-            updateOffset(output, offsets.topDictData + fdArrayEntry.getOffset() - 1,
+            updateOffset(offsets.topDictData + fdArrayEntry.getOffset() - 1,
                     fdArrayEntry.getOperandLength(), offsets.fdArray);
         }
 
         DICTEntry fdSelect = topDict.get("FDSelect");
         if (fdSelect != null) {
-            updateOffset(output, offsets.topDictData + fdSelect.getOffset() - 1,
+            updateOffset(offsets.topDictData + fdSelect.getOffset() - 1,
                     fdSelect.getOperandLength(), offsets.fdSelect);
         }
 
         updateFixedOffsets(topDict, offsets);
     }
 
-    protected void updateOffset(byte[] out, int position, int length, int replacement) {
+    private void updateOffset(int position, int length, int replacement) throws IOException {
+        byte[] outBytes = output.toByteArray();
+        updateOffset(outBytes, position, length, replacement);
+        output.reset();
+        output.write(outBytes);
+    }
+
+    private void updateOffset(byte[] out, int position, int length, int replacement) {
         switch (length) {
         case 1:
             out[position] = (byte)(replacement + 139);

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java?rev=1811797&r1=1811796&r2=1811797&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java Wed Oct 11 07:49:03 2017
@@ -18,12 +18,12 @@
 /* $Id$ */
 package org.apache.fop.fonts.truetype;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 
 public class OTFSubSetWriter extends OTFFile {
     protected int currentPos;
-    protected int realSize;
-    protected byte[] output;
+    protected ByteArrayOutputStream output = new ByteArrayOutputStream();
 
     public OTFSubSetWriter() throws IOException {
         super();
@@ -43,8 +43,8 @@ public class OTFSubSetWriter extends OTF
      * updates currentPost but not realSize
      */
     protected void writeByte(int b) {
-        output[currentPos++] = (byte)b;
-        realSize++;
+        output.write(b);
+        currentPos++;
     }
 
     /**
@@ -89,21 +89,12 @@ public class OTFSubSetWriter extends OTF
         }
     }
 
-    protected void writeBytes(byte[] out, int offset, int length) {
-        for (int i = offset; i < offset + length; i++) {
-            output[currentPos++] = out[i];
-            realSize++;
-        }
-    }
-
     /**
      * Returns a subset of the fonts (readFont() MUST be called first in order to create the
      * subset).
      * @return byte array
      */
     public byte[] getFontSubset() {
-        byte[] ret = new byte[realSize];
-        System.arraycopy(output, 0, ret, 0, realSize);
-        return ret;
+        return output.toByteArray();
     }
 }

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=1811797&r1=1811796&r2=1811797&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 Oct 11 07:49:03 2017
@@ -508,7 +508,7 @@ public class OTFSubSetFileTestCase exten
             super.createCFF();
         }
 
-        protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets) {
+        protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets) throws IOException {
             this.charsetOffset = offsets.charset;
             super.updateFixedOffsets(topDICT, offsets);
         }
@@ -621,7 +621,7 @@ public class OTFSubSetFileTestCase exten
             super.createCFF();
         }
 
-        protected void updateCIDOffsets(Offsets offsets) {
+        protected void updateCIDOffsets(Offsets offsets) throws IOException {
             super.updateCIDOffsets(offsets);
             this.offsets = offsets;
         }
@@ -658,7 +658,6 @@ public class OTFSubSetFileTestCase exten
     public void testWriteCIDDictsAndSubrs() throws IOException {
         OTFSubSetFile subSetFile = new OTFSubSetFile() {
             public void readFont(FontFileReader in, String embeddedName, MultiByteFont mbFont) throws IOException {
-                output = new byte[128];
                 cffReader = makeCFFDataReader();
                 fdSubrs = new ArrayList<List<byte[]>>();
                 fdSubrs.add(new ArrayList<byte[]>());
@@ -682,7 +681,6 @@ public class OTFSubSetFileTestCase exten
         OTFSubSetFile otfSubSetFile = new OTFSubSetFile() {
             void readFont(FontFileReader in, String embeddedName, MultiByteFont mbFont,
                           Map<Integer, Integer> usedGlyphs) throws IOException {
-                output = new byte[7];
                 cffReader = makeCFFDataReader();
                 LinkedHashMap<String, DICTEntry> topDict = new LinkedHashMap<String, DICTEntry>();
                 DICTEntry entry = new DICTEntry();
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.