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: fop-commits-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-commits-h...@xmlgraphics.apache.org