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);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]