Browse Source

Cleanup offset code

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1808231 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-2_3
Simon Steiner 6 years ago
parent
commit
a0e71e557d

+ 52
- 54
fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java View File

writeBytes(cffReader.getHeader()); writeBytes(cffReader.getHeader());


//Name Index //Name Index
writeIndex(Arrays.asList(embedFontName.getBytes()));
writeIndex(Arrays.asList(embedFontName.getBytes("UTF-8")));

Offsets offsets = new Offsets();


//Keep offset of the topDICT so it can be updated once all data has been written
int topDictOffset = currentPos;
//Top DICT Index and Data //Top DICT Index and Data
int topDictDataOffset = topDictOffset + writeTopDICT();
offsets.topDictData = currentPos + writeTopDICT();


boolean hasFDSelect = cffReader.getFDSelect() != null; boolean hasFDSelect = cffReader.getFDSelect() != null;


writeIndex(subsetGlobalIndexSubr); writeIndex(subsetGlobalIndexSubr);


//Encoding //Encoding
int encodingOffset = currentPos;
offsets.encoding = currentPos;


//Charset table //Charset table
int charsetOffset = currentPos;
offsets.charset = currentPos;
writeCharsetTable(hasFDSelect); writeCharsetTable(hasFDSelect);


//FDSelect table //FDSelect table
int fdSelectOffset = currentPos;
offsets.fdSelect = currentPos;
if (hasFDSelect) { if (hasFDSelect) {
writeFDSelect(); writeFDSelect();
if (!isCharStringBeforeFD()) {
offsets.fdArray = writeFDArray(subsetFDFonts, fontNameSIDs);
}
} }


int fdArrayOffset = -1;
if (hasFDSelect && !isCharStringBeforeFD()) {
fdArrayOffset = writeFDArray(subsetFDFonts, fontNameSIDs);
}
//Char Strings Index //Char Strings Index
int charStringOffset = currentPos;
offsets.charString = currentPos;
writeIndex(subsetCharStringsIndex); writeIndex(subsetCharStringsIndex);
if (hasFDSelect && isCharStringBeforeFD()) {
fdArrayOffset = writeFDArray(subsetFDFonts, fontNameSIDs);
}

if (hasFDSelect) { if (hasFDSelect) {
updateCIDOffsets(topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset,
charStringOffset, encodingOffset);
if (isCharStringBeforeFD()) {
offsets.fdArray = writeFDArray(subsetFDFonts, fontNameSIDs);
}
updateCIDOffsets(offsets);
} else { } else {
//Keep offset to modify later with the local subroutine index offset //Keep offset to modify later with the local subroutine index offset
int privateDictOffset = currentPos;
offsets.privateDict = currentPos;
writePrivateDict(); writePrivateDict();


//Local subroutine index //Local subroutine index
int localIndexOffset = currentPos;
offsets.localIndex = currentPos;
writeIndex(subsetLocalIndexSubr); writeIndex(subsetLocalIndexSubr);


//Update the offsets //Update the offsets
updateOffsets(topDictOffset, charsetOffset, charStringOffset, privateDictOffset,
localIndexOffset, encodingOffset);
updateOffsets(offsets);
} }
} }


static class Offsets {
Integer topDictData;
Integer encoding;
Integer charset;
Integer fdSelect;
Integer charString;
Integer fdArray;
Integer privateDict;
Integer localIndex;
}

private int writeFDArray(List<Integer> subsetFDFonts, List<Integer> fontNameSIDs) throws IOException { private int writeFDArray(List<Integer> subsetFDFonts, List<Integer> fontNameSIDs) throws IOException {
List<Integer> privateDictOffsets = writeCIDDictsAndSubrs(subsetFDFonts); List<Integer> privateDictOffsets = writeCIDDictsAndSubrs(subsetFDFonts);
return writeFDArray(subsetFDFonts, privateDictOffsets, fontNameSIDs); return writeFDArray(subsetFDFonts, privateDictOffsets, fontNameSIDs);
int sidAStringIndex = stringIndexData.size() + 390; int sidAStringIndex = stringIndexData.size() + 390;
int sidB = dictEntry.getOperands().get(1).intValue(); int sidB = dictEntry.getOperands().get(1).intValue();
if (sidB > 390) { if (sidB > 390) {
stringIndexData.add("Identity".getBytes());
stringIndexData.add("Identity".getBytes("UTF-8"));
} }
int sidBStringIndex = stringIndexData.size() + 390; int sidBStringIndex = stringIndexData.size() + 390;
byte[] cidEntryByteData = dictEntry.getByteData(); byte[] cidEntryByteData = dictEntry.getByteData();
if (index < cffReader.getStringIndex().getNumObjects()) { if (index < cffReader.getStringIndex().getNumObjects()) {
if (mbFont != null) { if (mbFont != null) {
mbFont.mapUsedGlyphName(subsetGlyph.getValue(), mbFont.mapUsedGlyphName(subsetGlyph.getValue(),
new String(cffReader.getStringIndex().getValue(index)));
new String(cffReader.getStringIndex().getValue(index), "UTF-8"));
} }
gidToSID.put(subsetGlyph.getValue(), stringIndexData.size() + 391); gidToSID.put(subsetGlyph.getValue(), stringIndexData.size() + 391);
stringIndexData.add(cffReader.getStringIndex().getValue(index)); stringIndexData.add(cffReader.getStringIndex().getValue(index));
List<FontDict> fdFonts = cffReader.getFDFonts(); List<FontDict> fdFonts = cffReader.getFDFonts();
for (int i = 0; i < uniqueNewRefs.size(); i++) { for (int i = 0; i < uniqueNewRefs.size(); i++) {
FontDict curFDFont = fdFonts.get(uniqueNewRefs.get(i)); FontDict curFDFont = fdFonts.get(uniqueNewRefs.get(i));
Map<String, DICTEntry> fdPrivateDict = cffReader.parseDictData(
curFDFont.getPrivateDictData());
byte[] fdPrivateDictByteData = curFDFont.getPrivateDictData();
Map<String, DICTEntry> fdPrivateDict = cffReader.parseDictData(fdPrivateDictByteData);
int privateDictOffset = currentPos; int privateDictOffset = currentPos;
privateDictOffsets.add(privateDictOffset); privateDictOffsets.add(privateDictOffset);
byte[] fdPrivateDictByteData = curFDFont.getPrivateDictData();
if (fdPrivateDict.get("Subrs") != null) { if (fdPrivateDict.get("Subrs") != null) {
updateOffset(fdPrivateDictByteData, fdPrivateDict.get("Subrs").getOffset(), updateOffset(fdPrivateDictByteData, fdPrivateDict.get("Subrs").getOffset(),
fdPrivateDict.get("Subrs").getOperandLength(), fdPrivateDict.get("Subrs").getOperandLength(),
} }
} }


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> topDICT = cffReader.getTopDictEntries();
Map<String, DICTEntry> privateDICT = null; Map<String, DICTEntry> privateDICT = null;


privateDICT = cffReader.getPrivateDict(privateEntry); 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) { if (privateDICT != null) {
//Private index offset in the top dict //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), 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 //Update the local subroutine index offset in the private dict
DICTEntry subroutines = privateDICT.get("Subrs"); DICTEntry subroutines = privateDICT.get("Subrs");
if (subroutines != null) { if (subroutines != null) {
int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
int oldLocalSubrOffset = offsets.privateDict + subroutines.getOffset();
updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(), updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
(localIndexOffset - privateDictOffset));
(offsets.localIndex - offsets.privateDict));
} }
} }
} }


protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, int dataTopDictOffset,
int charsetOffset, int charStringOffset, int encodingOffset) {
protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets) {
//Charset offset in the top dict //Charset offset in the top dict
DICTEntry charset = topDICT.get("charset"); DICTEntry charset = topDICT.get("charset");
int oldCharsetOffset = dataTopDictOffset + charset.getOffset();
updateOffset(output, oldCharsetOffset, charset.getOperandLength(), charsetOffset);
int oldCharsetOffset = offsets.topDictData + charset.getOffset();
updateOffset(output, oldCharsetOffset, charset.getOperandLength(), offsets.charset);


//Char string index offset in the private dict //Char string index offset in the private dict
DICTEntry charString = topDICT.get("CharStrings"); DICTEntry charString = topDICT.get("CharStrings");
int oldCharStringOffset = dataTopDictOffset + charString.getOffset();
updateOffset(output, oldCharStringOffset, charString.getOperandLength(), charStringOffset);
int oldCharStringOffset = offsets.topDictData + charString.getOffset();
updateOffset(output, oldCharStringOffset, charString.getOperandLength(), offsets.charString);


DICTEntry encodingEntry = topDICT.get("Encoding"); DICTEntry encodingEntry = topDICT.get("Encoding");
if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0 if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0
&& encodingEntry.getOperands().get(0).intValue() != 1) { && encodingEntry.getOperands().get(0).intValue() != 1) {
int oldEncodingOffset = dataTopDictOffset + encodingEntry.getOffset();
updateOffset(output, oldEncodingOffset, encodingEntry.getOperandLength(), encodingOffset);
int oldEncodingOffset = offsets.topDictData + encodingEntry.getOffset();
updateOffset(output, oldEncodingOffset, encodingEntry.getOperandLength(), offsets.encoding);
} }
} }


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(); Map<String, DICTEntry> topDict = cffReader.getTopDictEntries();


DICTEntry fdArrayEntry = topDict.get("FDArray"); DICTEntry fdArrayEntry = topDict.get("FDArray");
if (fdArrayEntry != null) { 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"); DICTEntry fdSelect = topDict.get("FDSelect");
if (fdSelect != null) { 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) { protected void updateOffset(byte[] out, int position, int length, int replacement) {

+ 9
- 14
fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java View File

super.createCFF(); super.createCFF();
} }


protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, int dataTopDictOffset,
int charsetOffset, int charStringOffset, int encodingOffset) {
this.charsetOffset = charsetOffset;
super.updateFixedOffsets(topDICT, dataTopDictOffset, charsetOffset, charStringOffset, encodingOffset);
protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, Offsets offsets) {
this.charsetOffset = offsets.charset;
super.updateFixedOffsets(topDICT, offsets);
} }
} }


@Test @Test
public void testOrderOfEntries() throws IOException { public void testOrderOfEntries() throws IOException {
OTFSubSetFileEntryOrder otfSubSetFile = getFont(3, 2); OTFSubSetFileEntryOrder otfSubSetFile = getFont(3, 2);
assertTrue(otfSubSetFile.fdArrayOffset < otfSubSetFile.charStringOffset);
assertTrue(otfSubSetFile.offsets.fdArray < otfSubSetFile.offsets.charString);


otfSubSetFile = getFont(2, 3); otfSubSetFile = getFont(2, 3);
assertTrue(otfSubSetFile.fdArrayOffset > otfSubSetFile.charStringOffset);
assertTrue(otfSubSetFile.offsets.fdArray > otfSubSetFile.offsets.charString);
} }


private OTFSubSetFileEntryOrder getFont(int csLen, int fdLen) throws IOException { private OTFSubSetFileEntryOrder getFont(int csLen, int fdLen) throws IOException {
} }


static class OTFSubSetFileEntryOrder extends OTFSubSetFile { static class OTFSubSetFileEntryOrder extends OTFSubSetFile {
int fdArrayOffset;
int charStringOffset;
Offsets offsets;
int csLen; int csLen;
int fdLen; int fdLen;


super.createCFF(); super.createCFF();
} }


protected void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
int charsetOffset, int charStringOffset, int encodingOffset) {
super.updateCIDOffsets(
topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset, charStringOffset, encodingOffset);
this.fdArrayOffset = fdArrayOffset;
this.charStringOffset = charStringOffset;
protected void updateCIDOffsets(Offsets offsets) {
super.updateCIDOffsets(offsets);
this.offsets = offsets;
} }
} }
} }

Loading…
Cancel
Save