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.