summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2017-10-11 07:49:03 +0000
committerSimon Steiner <ssteiner@apache.org>2017-10-11 07:49:03 +0000
commitc803867f451abf384fdc1bd5f524bfe3c2e47851 (patch)
treedfb22ecbe70f4eabbf2d026fbb6fd60400161360
parentade0e4ebd6ce8f92e9a19878e838a5a75226801d (diff)
downloadxmlgraphics-fop-c803867f451abf384fdc1bd5f524bfe3c2e47851.tar.gz
xmlgraphics-fop-c803867f451abf384fdc1bd5f524bfe3c2e47851.zip
FOP-2750: Use streams for OTF subsetting
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1811797 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java97
-rw-r--r--fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java19
-rw-r--r--fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java6
3 files changed, 58 insertions, 64 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 0487c6127..fd3a9988e 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
@@ -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 OTFSubSetWriter {
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 OTFSubSetWriter {
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 OTFSubSetWriter {
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 OTFSubSetWriter {
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 OTFSubSetWriter {
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 OTFSubSetWriter {
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);
diff --git a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java
index 9cac010b2..92e6f2651 100644
--- a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java
+++ b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetWriter.java
@@ -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 OTFFile {
* 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 OTFFile {
}
}
- 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();
}
}
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 8f15edde0..c872c731e 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
@@ -508,7 +508,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase {
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 extends OTFFileTestCase {
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 extends OTFFileTestCase {
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 extends OTFFileTestCase {
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();