You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ss...@apache.org on 2015/12/02 15:16:54 UTC
svn commit: r1717631 - in /xmlgraphics/fop-pdf-images/trunk:
src/java/org/apache/fop/render/pdf/pdfbox/
test/java/org/apache/fop/render/pdf/
Author: ssteiner
Date: Wed Dec 2 14:16:54 2015
New Revision: 1717631
URL: http://svn.apache.org/viewvc?rev=1717631&view=rev
Log:
FOP-2546: ArrayIndexOutOfBoundsException merging fonts
Modified:
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java
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/MergeTTFonts.java
xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java?rev=1717631&r1=1717630&r2=1717631&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java Wed Dec 2 14:16:54 2015
@@ -37,7 +37,6 @@ import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.encoding.DictionaryEncoding;
import org.apache.pdfbox.encoding.Encoding;
import org.apache.pdfbox.encoding.EncodingManager;
import org.apache.pdfbox.pdmodel.common.PDStream;
@@ -61,7 +60,7 @@ public class FOPPDFSingleByteFont extend
protected Map<String, Integer> charMapGlobal = new LinkedHashMap<String, Integer>();
private Map<Integer, Integer> newWidth = new HashMap<Integer, Integer>();
private Map<String, byte[]> charStringsDict;
- private MergeTTFonts.Cmap newCmap = new MergeTTFonts.Cmap();
+ private List<MergeTTFonts.Cmap> newCmap = new ArrayList<MergeTTFonts.Cmap>();
private Map<Integer, String> encodingMap = new TreeMap<Integer, String>();
private int encodingSkip;
private MergeTTFonts mergeTTFonts = new MergeTTFonts();
@@ -183,18 +182,27 @@ public class FOPPDFSingleByteFont extend
TrueTypeFont ttfont = ((PDTrueTypeFont) font).getTTFFont();
CMAPEncodingEntry[] cmapList = ttfont.getCMAP().getCmaps();
for (CMAPEncodingEntry c : cmapList) {
- newCmap.platformId = c.getPlatformId();
- newCmap.platformEncodingId = c.getPlatformEncodingId();
+ MergeTTFonts.Cmap tempCmap = getNewCmap(c.getPlatformId(), c.getPlatformEncodingId());
for (int i = 0; i < 256 * 256; i++) {
if (c.getGlyphId(i) != 0) {
- newCmap.glyphIdToCharacterCode.put(i, c.getGlyphId(i));
+ tempCmap.glyphIdToCharacterCode.put(i, c.getGlyphId(i));
}
}
+ newCmap.add(tempCmap);
}
FOPPDFMultiByteFont.mergeMaxp(ttfont, mergeTTFonts.maxp);
}
}
+ private MergeTTFonts.Cmap getNewCmap(int platformID, int platformEncodingID) {
+ for (MergeTTFonts.Cmap cmap : newCmap) {
+ if (cmap.platformId == platformID && cmap.platformEncodingId == platformEncodingID) {
+ return cmap;
+ }
+ }
+ return new MergeTTFonts.Cmap(platformID, platformEncodingID);
+ }
+
@Override
public boolean hasChar(char c) {
return charMapGlobal.containsKey(String.valueOf(c));
@@ -329,10 +337,7 @@ public class FOPPDFSingleByteFont extend
return c.lookup(i, size);
}
Encoding enc = (Encoding)cmap;
- if (enc instanceof DictionaryEncoding) {
- return enc.getName(i);
- }
- return enc.getCharacter(i);
+ return enc.getName(i);
}
public String getEncodingName() {
@@ -360,7 +365,7 @@ public class FOPPDFSingleByteFont extend
for (int i = fontForEnc.getFirstChar(); i <= fontForEnc.getLastChar(); i++) {
if (codeToName.keySet().contains(i)) {
String s = codeToName.get(i);
- if (!added.contains(s)) {
+ if (!added.contains(s) || (added.contains(s) && !encodingMap.containsKey(i))) {
if (!encodingMap.containsKey(i)) {
encodingMap.put(i, s);
} else {
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=1717631&r1=1717630&r2=1717631&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 Dec 2 14:16:54 2015
@@ -49,9 +49,7 @@ public class MergeCFFFonts extends OTFSu
private List<Integer> chars = new ArrayList<Integer>();
private List<String> added = new ArrayList<String>();
private Map<Integer, Integer> range = new LinkedHashMap<Integer, Integer>();
- private Set<String> stringsForRange = new HashSet<String>();
private int noOfFonts;
- private CFFEncoding encoding = null;
public MergeCFFFonts() throws IOException {
gidToSID = new LinkedHashMap<Integer, Integer>();
@@ -63,23 +61,24 @@ public class MergeCFFFonts extends OTFSu
FontFileReader fontFile = new FontFileReader(stream);
CFFParser p = new CFFParser();
CFFFont ff = p.parse(fontFile.getAllBytes()).get(0);
- if (used.containsAll(ff.getCharStringsDict().keySet())) {
+
+ if (used.containsAll(getStrings(ff).keySet())) {
return;
}
fontFileSize += fontFile.getFileSize();
this.fontFile = fontFile;
- used.addAll(ff.getCharStringsDict().keySet());
+ used.addAll(getStrings(ff).keySet());
if (fileFont == null) {
fileFont = ff;
}
LinkedHashMap<Integer, Integer> sg = new LinkedHashMap<Integer, Integer>();
- for (int i = 0; i < ff.getCharset().getEntries().size() + 1; i++) {
+ for (int i = 0; i < ff.getCharStringsDict().size() + 1; i++) {
sg.put(i, i);
}
subsetGlyphsList.add(sg);
cffReader = new CFFDataReader(fontFile);
- for (CFFCharset.Entry e : ff.getCharset().getEntries()) {
- int sid = e.getSID();
+
+ for (int sid : getSids(ff.getCharset())) {
if (sid >= NUM_STANDARD_STRINGS) {
int index = sid - NUM_STANDARD_STRINGS;
if (index <= cffReader.getStringIndex().getNumObjects()) {
@@ -91,36 +90,18 @@ public class MergeCFFFonts extends OTFSu
}
}
- encoding = ff.getEncoding();
+ CFFEncoding encoding = ff.getEncoding();
if (!(encoding instanceof CFFStandardEncoding)) {
for (CFFEncoding.Entry e : encoding.getEntries()) {
int c = e.getCode();
- if (!chars.contains(c)) {
+ if (!chars.contains(c) && c != 0) {
chars.add(c);
}
}
}
+ setupMapping(ff.getCharset(), sg);
- int subsetGlyphIndex = 0;
- for (CFFCharset.Entry e : ff.getCharset().getEntries()) {
- int sid = e.getSID();
- int gid = sg.get(subsetGlyphIndex);
-
- //Check whether the SID falls into the standard string set
- if (sid < NUM_STANDARD_STRINGS) {
- gidToSID.put(sg.get(gid), sid);
- } else {
- int index = sid - NUM_STANDARD_STRINGS;
- if (index <= cffReader.getStringIndex().getNumObjects()) {
- gidToSID.put(sg.get(gid), stringIndexData.size() + NUM_STANDARD_STRINGS - 1);
- } else {
- gidToSID.put(sg.get(gid), index);
- }
- }
- subsetGlyphIndex++;
- }
-
- for (Map.Entry<String, byte[]> s : ff.getCharStringsDict().entrySet()) {
+ for (Map.Entry<String, byte[]> s : getStrings(ff).entrySet()) {
if (!added.contains(s.getKey())) {
subsetCharStringsIndex.add(s.getValue());
added.add(s.getKey());
@@ -131,16 +112,49 @@ public class MergeCFFFonts extends OTFSu
String cClass = cSet.getClass().getName();
if (cClass.equals("org.apache.fontbox.cff.CFFParser$Format1Charset")
|| cClass.equals("org.apache.fontbox.cff.CFFParser$Format0Charset")) {
- for (CFFCharset.Entry m : cSet.getEntries()) {
- if (!stringsForRange.contains(m.getName())) {
- range.put(m.getSID(), 0);
- stringsForRange.add(m.getName());
- }
+ for (int sid : getSids(cSet)) {
+ range.put(sid, 0);
}
}
noOfFonts++;
}
+ private void setupMapping(CFFCharset charset, LinkedHashMap<Integer, Integer> sg) {
+ int subsetGlyphIndex = 0;
+ for (int sid : getSids(charset)) {
+ if (sg.containsKey(subsetGlyphIndex)) {
+ int gid = sg.get(subsetGlyphIndex);
+
+ //Check whether the SID falls into the standard string set
+ if (sid < NUM_STANDARD_STRINGS) {
+ gidToSID.put(sg.get(gid), sid);
+ } else {
+ int index = sid - NUM_STANDARD_STRINGS;
+ if (index <= cffReader.getStringIndex().getNumObjects()) {
+ gidToSID.put(sg.get(gid), stringIndexData.size() + NUM_STANDARD_STRINGS - 1);
+ } else {
+ gidToSID.put(sg.get(gid), index);
+ }
+ }
+ subsetGlyphIndex++;
+ }
+ }
+ }
+
+ public static List<Integer> getSids(CFFCharset cSet) {
+ List<Integer> sids = new ArrayList<Integer>();
+ for (CFFCharset.Entry x : cSet.getEntries()) {
+ if (x.getSID() != 0) {
+ sids.add(x.getSID());
+ }
+ }
+ return sids;
+ }
+
+ public static Map<String, byte[]> getStrings(CFFFont ff) throws IOException {
+ return ff.getCharStringsDict();
+ }
+
public void writeFont() throws IOException {
output = new byte[fontFileSize * 2];
if (noOfFonts == 1) {
@@ -260,26 +274,6 @@ public class MergeCFFFonts extends OTFSu
}
protected void writeEncoding() throws IOException {
- if (encoding instanceof CFFStandardEncoding) {
- LinkedHashMap<String, CFFDataReader.DICTEntry> topDICT = cffReader.getTopDictEntries();
- final CFFDataReader.DICTEntry encodingEntry = topDICT.get("Encoding");
- if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0
- && encodingEntry.getOperands().get(0).intValue() != 1) {
- int len = encoding.getEntries().size();
- if (len != gidToSID.size() - 1) {
- return;
- }
- writeByte(0);
- writeByte(len);
- for (Map.Entry<Integer, Integer> gid : gidToSID.entrySet()) {
- if (gid.getKey() == 0) {
- continue;
- }
- int code = encoding.getCode(gid.getValue());
- writeByte(code);
- }
- }
- }
if (!chars.isEmpty()) {
writeCard16(chars.size());
for (int i : chars) {
@@ -289,6 +283,7 @@ public class MergeCFFFonts extends OTFSu
}
protected void writeStringIndex() throws IOException {
+ int stringIndexSize = stringIndexData.size();
for (String s : strings) {
stringIndexData.add(s.getBytes("US-ASCII"));
}
@@ -296,8 +291,10 @@ public class MergeCFFFonts extends OTFSu
//Write the String Index
if (!stringIndexData.isEmpty()) {
if (!strings.isEmpty() && !new String(stringIndexData.get(0), "UTF-8").equals(strings.get(0))) {
- //Move copyright string to end
- stringIndexData.add(stringIndexData.remove(0));
+ //Keep strings in order as they are referenced from the TopDICT
+ for (int i = 0; i < stringIndexSize; i++) {
+ stringIndexData.add(stringIndexData.remove(0));
+ }
} else {
String notice = (String)fileFont.getProperty("Notice");
if (notice != null && !(fileFont instanceof CFFFontROS)) {
Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java?rev=1717631&r1=1717630&r2=1717631&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java Wed Dec 2 14:16:54 2015
@@ -17,6 +17,7 @@
package org.apache.fop.render.pdf.pdfbox;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -107,6 +108,9 @@ public class MergeTTFonts extends TTFSub
byte[] glyphData = gly.getValue().data;
int glyphLength = glyphData.length;
int i = gly.getKey();
+ if (i >= origIndexesLen) {
+ continue;
+ }
int endOffset1 = endOffset;
// Copy glyph
writeBytes(glyphData);
@@ -261,7 +265,7 @@ public class MergeTTFonts extends TTFSub
}
}
- public void writeFont(Cmap cmap) throws IOException {
+ public void writeFont(List<Cmap> cmap) throws IOException {
output = new byte[size * 2];
createDirectory(); // Create the TrueType header and directory
int sgsize = added.size();
@@ -270,11 +274,7 @@ public class MergeTTFonts extends TTFSub
// copyTable(fontFile, OFTableName.CMAP);
}
createHmtx(); // Create hmtx table
- if (cid || locaFormat == 1) {
- createLoca(sgsize); // create empty loca table
- } else {
- createLoca(numberOfGlyphs / 2); // create empty loca table
- }
+ createLoca(sgsize); // create empty loca table
createHead(fontFile);
createOS2(fontFile); // copy the OS/2 table
if (!cid) {
@@ -287,23 +287,10 @@ public class MergeTTFonts extends TTFSub
} else {
writeMaxp();
}
- boolean optionalTableFound;
- optionalTableFound = createCvt(fontFile); // copy the cvt table
- if (!optionalTableFound) {
- // cvt is optional (used in TrueType fonts only)
- log.debug("TrueType: ctv table not present. Skipped.");
- }
- optionalTableFound = createFpgm(fontFile); // copy fpgm table
- if (!optionalTableFound) {
- // fpgm is optional (used in TrueType fonts only)
- log.debug("TrueType: fpgm table not present. Skipped.");
- }
+ createCvt(fontFile); // copy the cvt table
+ createFpgm(fontFile); // copy fpgm table
createPost(fontFile); // copy the post table
- optionalTableFound = createPrep(fontFile); // copy prep table
- if (!optionalTableFound) {
- // prep is optional (used in TrueType fonts only)
- log.debug("TrueType: prep table not present. Skipped.");
- }
+ createPrep(fontFile); // copy prep table
createName(fontFile); // copy the name table
createGlyf(); //create glyf table and update loca table
pad4();
@@ -334,35 +321,40 @@ public class MergeTTFonts extends TTFSub
realSize += currentPos - startPos;
}
- private void writeCMAP(Cmap cmap) {
+ private void writeCMAP(List<Cmap> cmaps) {
int checksum = currentPos;
pad4();
int cmapPos = currentPos;
writeUShort(0); //version
- writeUShort(1); //number of tables
-
- Map<Integer, Integer> glyphIdToCharacterCode = cmap.glyphIdToCharacterCode;
- writeUShort(cmap.platformId); //platformid
- writeUShort(cmap.platformEncodingId); //platformEncodingId
- writeULong(currentPos, currentPos - cmapPos + 12); //subTableOffset
- currentPos += 12;
+ writeUShort(cmaps.size()); //number of tables
- writeUShort(12); //subtableFormat
- writeUShort(0);
- writeULong(currentPos, (glyphIdToCharacterCode.size() * 12) + 16);
- currentPos += 4;
- writeULong(currentPos, 0);
- currentPos += 4;
- writeULong(currentPos, glyphIdToCharacterCode.size());
- currentPos += 4;
+ int tablesSize = 8 * cmaps.size();
+ for (int i = 0; i < cmaps.size(); i++) {
+ Cmap cmap = cmaps.get(i);
+ writeUShort(cmap.platformId); //platformid
+ writeUShort(cmap.platformEncodingId); //platformEncodingId
+ writeULong(currentPos, 4 + tablesSize + getCmapOffset(cmaps, i)); //subTableOffset
+ currentPos += 4;
+ }
- for (Map.Entry<Integer, Integer> g : glyphIdToCharacterCode.entrySet()) {
- writeULong(currentPos, g.getKey());
+ for (Cmap cmap : cmaps) {
+ writeUShort(12); //subtableFormat
+ writeUShort(0);
+ writeULong(currentPos, (cmap.glyphIdToCharacterCode.size() * 12) + 16);
currentPos += 4;
- writeULong(currentPos, g.getKey());
+ writeULong(currentPos, 0);
currentPos += 4;
- writeULong(currentPos, g.getValue());
+ writeULong(currentPos, cmap.glyphIdToCharacterCode.size());
currentPos += 4;
+
+ for (Map.Entry<Integer, Integer> g : cmap.glyphIdToCharacterCode.entrySet()) {
+ writeULong(currentPos, g.getKey());
+ currentPos += 4;
+ writeULong(currentPos, g.getKey());
+ currentPos += 4;
+ writeULong(currentPos, g.getValue());
+ currentPos += 4;
+ }
}
// writeUShort(6); //subtableFormat
@@ -396,6 +388,15 @@ public class MergeTTFonts extends TTFSub
realSize += currentPos - cmapPos;
}
+ private int getCmapOffset(List<Cmap> cmaps, int index) {
+ int result = 0;
+ for (int i = 0; i < index; i++) {
+ Cmap curCmap = cmaps.get(i);
+ result += (curCmap.glyphIdToCharacterCode.size() * 12) + 16;
+ }
+ return result;
+ }
+
/**
* Get index from starting at lowest glyph position
* @param glyphs map
@@ -421,5 +422,10 @@ public class MergeTTFonts extends TTFSub
int platformId;
int platformEncodingId;
Map<Integer, Integer> glyphIdToCharacterCode = new TreeMap<Integer, Integer>();
+
+ public Cmap(int platformID, int platformEncodingID) {
+ this.platformId = platformID;
+ this.platformEncodingId = platformEncodingID;
+ }
}
}
Modified: xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java?rev=1717631&r1=1717630&r2=1717631&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java Wed Dec 2 14:16:54 2015
@@ -284,7 +284,7 @@ public class PDFBoxAdapterTestCase {
Assert.assertEquals(name, "TimesNewRomanPSMT_TrueType");
Assert.assertEquals(mbfont.getFontName(), "TimesNewRomanPSMT_TrueType");
byte[] is = IOUtils.toByteArray(mbfont.getInputStream());
- Assert.assertEquals(is.length, 34264);
+ Assert.assertEquals(is.length, 41352);
doc.close();
doc2.close();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org