Index: findbugs-exclude.xml
===================================================================
--- findbugs-exclude.xml (revision 1570221)
+++ findbugs-exclude.xml (working copy)
@@ -5994,4 +5994,11 @@
+
+
+
+
+
+
+
Index: src/java/org/apache/fop/fonts/CustomFont.java
===================================================================
--- src/java/org/apache/fop/fonts/CustomFont.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/CustomFont.java (working copy)
@@ -22,9 +22,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -74,6 +76,8 @@
private Map> kerning;
private boolean useKerning = true;
+ /** the character map, mapping Unicode ranges to glyph indices. */
+ protected List cmap = new ArrayList();
private boolean useAdvanced = true;
/**
@@ -82,9 +86,8 @@
public CustomFont(InternalResourceResolver resourceResolver) {
this.resourceResolver = resourceResolver;
}
- /** the character map, mapping Unicode ranges to glyph indices. */
- protected CMapSegment[] cmap;
+
/** {@inheritDoc} */
public String getFontName() {
return fontName;
@@ -503,8 +506,10 @@
* @param cmap the character map
*/
public void setCMap(CMapSegment[] cmap) {
- this.cmap = new CMapSegment[cmap.length];
- System.arraycopy(cmap, 0, this.cmap, 0, cmap.length);
+ this.cmap.clear();
+ for (CMapSegment c : cmap) {
+ this.cmap.add(c);
+ }
}
/**
@@ -513,9 +518,7 @@
* @return the character map
*/
public CMapSegment[] getCMap() {
- CMapSegment[] copy = new CMapSegment[cmap.length];
- System.arraycopy(this.cmap, 0, copy, 0, this.cmap.length);
- return copy;
+ return cmap.toArray(new CMapSegment[cmap.size()]);
}
public int getUnderlinePosition(int size) {
Index: src/java/org/apache/fop/fonts/FontType.java
===================================================================
--- src/java/org/apache/fop/fonts/FontType.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/FontType.java (working copy)
@@ -49,6 +49,8 @@
*/
public static final FontType TRUETYPE = new FontType("TrueType", 5);
+ public static final FontType TYPE1C = new FontType("Type1C", 6);
+
private final String name;
private final int value;
Index: src/java/org/apache/fop/fonts/MultiByteFont.java
===================================================================
--- src/java/org/apache/fop/fonts/MultiByteFont.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/MultiByteFont.java (working copy)
@@ -20,6 +20,7 @@
package org.apache.fop.fonts;
import java.awt.Rectangle;
+import java.io.InputStream;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.util.BitSet;
@@ -53,7 +54,7 @@
private int defaultWidth;
private CIDFontType cidType = CIDFontType.CIDTYPE2;
- private final CIDSet cidSet;
+ protected final CIDSet cidSet;
/* advanced typographic support */
private GlyphDefinitionTable gdef;
@@ -222,13 +223,13 @@
if (idx < NUM_MOST_LIKELY_GLYPHS && mostLikelyGlyphs[idx] != 0) {
return mostLikelyGlyphs[idx];
}
- for (int i = 0; (i < cmap.length) && retIdx == 0; i++) {
- if (cmap[i].getUnicodeStart() <= idx
- && cmap[i].getUnicodeEnd() >= idx) {
-
- retIdx = cmap[i].getGlyphStartIndex()
+ for (CMapSegment i : cmap) {
+ if (retIdx == 0
+ && i.getUnicodeStart() <= idx
+ && i.getUnicodeEnd() >= idx) {
+ retIdx = i.getGlyphStartIndex()
+ idx
- - cmap[i].getUnicodeStart();
+ - i.getUnicodeStart();
if (idx < NUM_MOST_LIKELY_GLYPHS) {
mostLikelyGlyphs[idx] = retIdx;
}
@@ -241,14 +242,9 @@
* Add a private use mapping {PU,GI} to the existing character map.
* N.B. Does not insert in order, merely appends to end of existing map.
*/
- private synchronized void addPrivateUseMapping(int pu, int gi) {
+ protected synchronized void addPrivateUseMapping(int pu, int gi) {
assert findGlyphIndex(pu) == SingleByteEncoding.NOT_FOUND_CODE_POINT;
- CMapSegment[] oldCmap = cmap;
- int cmapLength = oldCmap.length;
- CMapSegment[] newCmap = new CMapSegment [ cmapLength + 1 ];
- System.arraycopy(oldCmap, 0, newCmap, 0, cmapLength);
- newCmap [ cmapLength ] = new CMapSegment(pu, pu, gi);
- cmap = newCmap;
+ cmap.add(new CMapSegment(pu, pu, gi));
}
/**
@@ -306,8 +302,7 @@
// [TBD] - needs optimization, i.e., change from linear search to binary search
private int findCharacterFromGlyphIndex(int gi, boolean augment) {
int cc = 0;
- for (int i = 0, n = cmap.length; i < n; i++) {
- CMapSegment segment = cmap [ i ];
+ for (CMapSegment segment : cmap) {
int s = segment.getGlyphStartIndex();
int e = s + (segment.getUnicodeEnd() - segment.getUnicodeStart());
if ((gi >= s) && (gi <= e)) {
@@ -330,10 +325,10 @@
bitset.set(0);
bitset.set(1);
bitset.set(2);
- for (int i = 0; i < cmap.length; i++) {
- int start = cmap[i].getUnicodeStart();
- int end = cmap[i].getUnicodeEnd();
- int glyphIndex = cmap[i].getGlyphStartIndex();
+ for (CMapSegment i : cmap) {
+ int start = i.getUnicodeStart();
+ int end = i.getUnicodeEnd();
+ int glyphIndex = i.getGlyphStartIndex();
while (start++ < end + 1) {
bitset.set(glyphIndex++);
}
@@ -344,10 +339,10 @@
protected char[] getChars() {
// the width array is set when the font is built
char[] chars = new char[width.length];
- for (int i = 0; i < cmap.length; i++) {
- int start = cmap[i].getUnicodeStart();
- int end = cmap[i].getUnicodeEnd();
- int glyphIndex = cmap[i].getGlyphStartIndex();
+ for (CMapSegment i : cmap) {
+ int start = i.getUnicodeStart();
+ int end = i.getUnicodeEnd();
+ int glyphIndex = i.getGlyphStartIndex();
while (start < end + 1) {
chars[glyphIndex++] = (char) start++;
}
@@ -642,5 +637,12 @@
return cb;
}
+ public Map getWidthsMap() {
+ return null;
+ }
+
+ public InputStream getCmapStream() {
+ return null;
+ }
}
Index: src/java/org/apache/fop/fonts/SingleByteFont.java
===================================================================
--- src/java/org/apache/fop/fonts/SingleByteFont.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/SingleByteFont.java (working copy)
@@ -43,10 +43,10 @@
/** logger */
private static Log log = LogFactory.getLog(SingleByteFont.class);
- private SingleByteEncoding mapping;
+ protected SingleByteEncoding mapping;
private boolean useNativeEncoding = false;
- private int[] width = null;
+ protected int[] width = null;
private Rectangle[] boundingBoxes;
@@ -456,6 +456,5 @@
assert getFontType() == FontType.TRUETYPE;
return ttPostScriptVersion;
}
-
}
Index: src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java
===================================================================
--- src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java (working copy)
@@ -24,7 +24,7 @@
/**
* This class represents a TrueType Mtx Entry.
*/
-class OFMtxEntry {
+public class OFMtxEntry {
private int wx;
private int lsb;
@@ -55,7 +55,7 @@
* @return int[]
*/
public int[] getBoundingBox() {
- return boundingBox;
+ return boundingBox.clone();
}
/**
@@ -63,7 +63,7 @@
* @param boundingBox The boundingBox to set
*/
public void setBoundingBox(int[] boundingBox) {
- this.boundingBox = boundingBox;
+ this.boundingBox = boundingBox.clone();
}
/**
Index: src/java/org/apache/fop/fonts/truetype/OTFFile.java
===================================================================
--- src/java/org/apache/fop/fonts/truetype/OTFFile.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/truetype/OTFFile.java (working copy)
@@ -34,7 +34,7 @@
public class OTFFile extends OpenFont {
- protected CFFFont fileFont;
+ protected List fileFonts = new ArrayList();
public OTFFile() throws IOException {
checkForFontbox();
@@ -51,9 +51,9 @@
@Override
protected void updateBBoxAndOffset() throws IOException {
- List gidMappings = getGIDMappings(fileFont);
- Map sidNames = constructNameMap(gidMappings);
UnicodeMapping[] mappings = unicodeMappings.toArray(new UnicodeMapping[0]);
+ List gidMappings = getGIDMappings(fileFonts.get(0));
+ Map sidNames = constructNameMap(fileFonts.get(0).getMappings());
for (int i = 0; i < mappings.length; i++) {
int glyphIdx = mappings[i].getGlyphIndex();
Mapping m = gidMappings.get(glyphIdx);
@@ -81,11 +81,11 @@
return gidMappings;
}
- private Map constructNameMap(Collection mappings) {
+ private Map constructNameMap(Collection mappings) {
Map sidNames = new HashMap();
- Iterator it = mappings.iterator();
+ Iterator it = mappings.iterator();
while (it.hasNext()) {
- Mapping mapping = it.next();
+ CFFFont.Mapping mapping = it.next();
sidNames.put(mapping.getSID(), mapping.getName());
}
return sidNames;
@@ -127,16 +127,16 @@
fontFile = in;
fontFile.seekSet(0);
CFFParser parser = new CFFParser();
- fileFont = parser.parse(in.getAllBytes()).get(0);
+ fileFonts = parser.parse(in.getAllBytes());
}
protected void readName() throws IOException {
- Object familyName = fileFont.getProperty("FamilyName");
+ Object familyName = fileFonts.get(0).getProperty("FamilyName");
if (familyName != null && !familyName.equals("")) {
familyNames.add(familyName.toString());
fullName = familyName.toString();
} else {
- fullName = fileFont.getName();
+ fullName = fileFonts.get(0).getName();
familyNames.add(fullName);
}
}
@@ -147,7 +147,7 @@
* @return The byte data found in the CFF table
*/
public static byte[] getCFFData(FontFileReader fontFile) throws IOException {
- byte[] cff = new byte[0];
+ byte[] cff = fontFile.getAllBytes();
CFFDataInput input = new CFFDataInput(fontFile.getAllBytes());
input.readBytes(4); //OTTO
short numTables = input.readShort();
Index: src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
===================================================================
--- src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java (working copy)
@@ -49,23 +49,23 @@
*/
public class OTFSubSetFile extends OTFFile {
- private byte[] output;
- private int currentPos = 0;
+ protected byte[] output;
+ protected int currentPos = 0;
private int realSize = 0;
/** A map containing each glyph to be included in the subset
* with their existing and new GID's **/
- private LinkedHashMap subsetGlyphs;
+ protected LinkedHashMap subsetGlyphs = new LinkedHashMap();
/** A map of the new GID to SID used to construct the charset table **/
- private LinkedHashMap gidToSID;
+ protected LinkedHashMap gidToSID;
- private CFFIndexData localIndexSubr;
- private CFFIndexData globalIndexSubr;
+ protected CFFIndexData localIndexSubr;
+ protected CFFIndexData globalIndexSubr;
/** List of subroutines to write to the local / global indexes in the subset font **/
- private List subsetLocalIndexSubr;
- private List subsetGlobalIndexSubr;
+ protected List subsetLocalIndexSubr;
+ protected List subsetGlobalIndexSubr;
/** For fonts which have an FDSelect or ROS flag in Top Dict, this is used to store the
* local subroutine indexes for each group as opposed to the above subsetLocalIndexSubr */
@@ -76,30 +76,30 @@
private LinkedHashMap subsetFDSelect;
/** A list of unique subroutines from the global / local subroutine indexes */
- private List localUniques;
- private List globalUniques;
+ protected List localUniques;
+ protected List globalUniques;
/** A store of the number of subroutines each global / local subroutine will store **/
- private int subsetLocalSubrCount;
- private int subsetGlobalSubrCount;
+ protected int subsetLocalSubrCount;
+ protected int subsetGlobalSubrCount;
/** A list of char string data for each glyph to be stored in the subset font **/
- private List subsetCharStringsIndex;
+ protected List subsetCharStringsIndex;
/** The embedded name to change in the name table **/
- private String embeddedName;
+ protected String embeddedName;
/** An array used to hold the string index data for the subset font **/
- private List stringIndexData = new ArrayList();
+ protected List stringIndexData = new ArrayList();
/** The CFF reader object used to read data and offsets from the original font file */
- private CFFDataReader cffReader = null;
+ protected CFFDataReader cffReader = null;
/** The class used to represent this font **/
private MultiByteFont mbFont;
/** The number of standard strings in CFF **/
- private static final int NUM_STANDARD_STRINGS = 391;
+ public static final int NUM_STANDARD_STRINGS = 391;
/** The operator used to identify a local subroutine reference */
private static final int LOCAL_SUBROUTINE = 10;
/** The operator used to identify a global subroutine reference */
@@ -162,7 +162,7 @@
return result;
}
- private void createCFF() throws IOException {
+ protected void createCFF() throws IOException {
//Header
writeBytes(cffReader.getHeader());
@@ -201,7 +201,7 @@
//Encoding
int encodingOffset = currentPos;
- writeEncoding(fileFont.getEncoding());
+ writeEncoding(fileFonts.get(0).getEncoding());
//Charset table
int charsetOffset = currentPos;
@@ -238,7 +238,7 @@
}
}
- private List storeFDStrings(List uniqueNewRefs) throws IOException {
+ protected List storeFDStrings(List uniqueNewRefs) throws IOException {
ArrayList fontNameSIDs = new ArrayList();
List fdFonts = cffReader.getFDFonts();
for (int i = 0; i < uniqueNewRefs.size(); i++) {
@@ -252,14 +252,14 @@
return fontNameSIDs;
}
- private void writeBytes(byte[] out) {
+ protected void writeBytes(byte[] out) {
for (int i = 0; i < out.length; i++) {
output[currentPos++] = out[i];
realSize++;
}
}
- private void writeBytes(byte[] out, int offset, int length) {
+ protected void writeBytes(byte[] out, int offset, int length) {
for (int i = offset; i < offset + length; i++) {
output[currentPos++] = out[i];
realSize++;
@@ -280,7 +280,7 @@
}
}
- private void writeTopDICT() throws IOException {
+ protected void writeTopDICT() throws IOException {
LinkedHashMap topDICT = cffReader.getTopDictEntries();
List topDictStringEntries = Arrays.asList("version", "Notice", "Copyright",
"FullName", "FamilyName", "Weight", "PostScript");
@@ -375,7 +375,7 @@
writeIndex(stringIndexData);
}
- private void createCharStringDataCID() throws IOException {
+ protected void createCharStringDataCID() throws IOException {
CFFIndexData charStringsIndex = cffReader.getCharStringIndex();
FDSelect fontDictionary = cffReader.getFDSelect();
@@ -459,14 +459,14 @@
}
}
- private void writeFDSelect() {
+ protected void writeFDSelect() {
writeByte(0); //Format
for (Integer gid : subsetFDSelect.keySet()) {
writeByte(subsetFDSelect.get(gid).getNewFDIndex());
}
}
- private List getUsedFDFonts() {
+ protected List getUsedFDFonts() {
List uniqueNewRefs = new ArrayList();
for (int gid : subsetFDSelect.keySet()) {
int fdIndex = subsetFDSelect.get(gid).getOldFDIndex();
@@ -477,7 +477,7 @@
return uniqueNewRefs;
}
- private List writeCIDDictsAndSubrs(List uniqueNewRefs)
+ protected List writeCIDDictsAndSubrs(List uniqueNewRefs)
throws IOException {
List privateDictOffsets = new ArrayList();
List fdFonts = cffReader.getFDFonts();
@@ -499,7 +499,7 @@
return privateDictOffsets;
}
- private int writeFDArray(List uniqueNewRefs, List privateDictOffsets,
+ protected int writeFDArray(List uniqueNewRefs, List privateDictOffsets,
List fontNameSIDs)
throws IOException {
int offset = currentPos;
@@ -796,7 +796,7 @@
return c;
}
- private int writeIndex(List dataArray) {
+ protected int writeIndex(List dataArray) {
int hdrTotal = 3;
//2 byte number of items
this.writeCard16(dataArray.size());
@@ -939,7 +939,7 @@
}
}
- private void writePrivateDict() throws IOException {
+ protected void writePrivateDict() throws IOException {
Map topDICT = cffReader.getTopDictEntries();
DICTEntry privateEntry = topDICT.get("Private");
@@ -948,7 +948,7 @@
}
}
- private void updateOffsets(int topDictOffset, int charsetOffset, int charStringOffset,
+ protected void updateOffsets(int topDictOffset, int charsetOffset, int charStringOffset,
int privateDictOffset, int localIndexOffset, int encodingOffset)
throws IOException {
Map topDICT = cffReader.getTopDictEntries();
@@ -973,18 +973,20 @@
//Update the local subroutine index offset in the private dict
DICTEntry subroutines = privateDICT.get("Subrs");
- int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
- //Value needs to be converted to -139 etc.
- int encodeValue = 0;
- if (subroutines.getOperandLength() == 1) {
- encodeValue = 139;
+ if (subroutines != null) {
+ int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
+ //Value needs to be converted to -139 etc.
+ int encodeValue = 0;
+ if (subroutines.getOperandLength() == 1) {
+ encodeValue = 139;
+ }
+ output = updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
+ (localIndexOffset - privateDictOffset) + encodeValue);
}
- output = updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
- (localIndexOffset - privateDictOffset) + encodeValue);
}
}
- private void updateFixedOffsets(Map topDICT, int dataTopDictOffset,
+ protected void updateFixedOffsets(Map topDICT, int dataTopDictOffset,
int charsetOffset, int charStringOffset, int encodingOffset) {
//Charset offset in the top dict
DICTEntry charset = topDICT.get("charset");
@@ -1004,7 +1006,7 @@
}
}
- private void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
+ protected void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
int charsetOffset, int charStringOffset, int encodingOffset) {
LinkedHashMap topDict = cffReader.getTopDictEntries();
@@ -1023,7 +1025,7 @@
updateFixedOffsets(topDict, topDictDataOffset, charsetOffset, charStringOffset, encodingOffset);
}
- private byte[] updateOffset(byte[] out, int position, int length, int replacement) {
+ protected byte[] updateOffset(byte[] out, int position, int length, int replacement) {
switch (length) {
case 1:
out[position] = (byte)(replacement & 0xFF);
@@ -1061,7 +1063,7 @@
* Appends a byte to the output array,
* updates currentPost but not realSize
*/
- private void writeByte(int b) {
+ protected void writeByte(int b) {
output[currentPos++] = (byte)b;
realSize++;
}
@@ -1070,7 +1072,7 @@
* Appends a USHORT to the output array,
* updates currentPost but not realSize
*/
- private void writeCard16(int s) {
+ protected void writeCard16(int s) {
byte b1 = (byte)((s >> 8) & 0xff);
byte b2 = (byte)(s & 0xff);
writeByte(b1);
Index: src/java/org/apache/fop/fonts/truetype/OpenFont.java
===================================================================
--- src/java/org/apache/fop/fonts/truetype/OpenFont.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/truetype/OpenFont.java (working copy)
@@ -187,6 +187,7 @@
protected String notice = "";
protected final Set familyNames = new HashSet();
protected String subFamilyName = "";
+ protected boolean cid = true;
private long italicAngle = 0;
private long isFixedPitch = 0;
@@ -393,7 +394,9 @@
unicodeMappings = new ArrayList();
- seekTab(fontFile, OFTableName.CMAP, 2);
+ if (!seekTab(fontFile, OFTableName.CMAP, 2)) {
+ return true;
+ }
int numCMap = fontFile.readTTFUShort(); // Number of cmap subtables
long cmapUniOffset = 0;
long symbolMapOffset = 0;
@@ -796,7 +799,9 @@
int unicodeStart;
int glyphStart;
int unicodeEnd;
-
+ if (unicodeMappings.isEmpty()) {
+ return;
+ }
Iterator e = unicodeMappings.iterator();
UnicodeMapping um = e.next();
UnicodeMapping lastMapping = um;
@@ -1229,7 +1234,7 @@
}
}
- if (nhmtx < mtxSize) {
+ if (cid && nhmtx < mtxSize) {
// Fill in the missing widths
int lastWidth = mtxTab[nhmtx - 1].getWx();
for (int i = nhmtx; i < mtxSize; i++) {
Index: src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
===================================================================
--- src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java (revision 1570221)
+++ src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java (working copy)
@@ -35,21 +35,21 @@
*/
public class TTFSubSetFile extends TTFFile {
- private byte[] output = null;
- private int realSize = 0;
- private int currentPos = 0;
+ protected byte[] output = null;
+ protected int realSize = 0;
+ protected int currentPos = 0;
/*
* Offsets in name table to be filled out by table.
* The offsets are to the checkSum field
*/
- private Map offsets = new HashMap();
+ protected Map offsets = new HashMap();
private int checkSumAdjustmentOffset = 0;
- private int locaOffset = 0;
+ protected int locaOffset = 0;
/** Stores the glyph offsets so that we can end strings at glyph boundaries */
- private int[] glyphOffsets;
+ protected int[] glyphOffsets;
/**
* Default Constructor
@@ -67,7 +67,7 @@
}
/** The dir tab entries in the new subset font. */
- private Map newDirTabs
+ protected Map newDirTabs
= new HashMap();
private int determineTableCount() {
@@ -86,6 +86,9 @@
if (hasPrep()) {
numTables++;
}
+ if (!cid) {
+ numTables++; //cmap
+ }
}
return numTables;
}
@@ -93,7 +96,7 @@
/**
* Create the directory table
*/
- private void createDirectory() {
+ protected void createDirectory() {
int numTables = determineTableCount();
// Create the TrueType header
writeByte((byte)0);
@@ -118,7 +121,9 @@
realSize += 2;
// Create space for the table entries (these must be in ASCII alphabetical order[A-Z] then[a-z])
writeTableName(OFTableName.OS2);
-
+ if (!cid) {
+ writeTableName(OFTableName.CMAP);
+ }
if (hasCvt()) {
writeTableName(OFTableName.CVT);
}
@@ -162,7 +167,7 @@
/**
* Create an empty loca table without updating checksum
*/
- private void createLoca(int size) throws IOException {
+ protected void createLoca(int size) throws IOException {
pad4();
locaOffset = currentPos;
int dirTableOffset = offsets.get(OFTableName.LOCA);
@@ -177,8 +182,7 @@
if (entry != null) {
pad4();
seekTab(in, tableName, 0);
- System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
- 0, output, currentPos, (int)entry.getLength());
+ writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
updateCheckSum(currentPos, (int) entry.getLength(), tableName);
currentPos += (int) entry.getLength();
@@ -192,28 +196,28 @@
/**
* Copy the cvt table as is from original font to subset font
*/
- private boolean createCvt(FontFileReader in) throws IOException {
+ protected boolean createCvt(FontFileReader in) throws IOException {
return copyTable(in, OFTableName.CVT);
}
/**
* Copy the fpgm table as is from original font to subset font
*/
- private boolean createFpgm(FontFileReader in) throws IOException {
+ protected boolean createFpgm(FontFileReader in) throws IOException {
return copyTable(in, OFTableName.FPGM);
}
/**
* Copy the name table as is from the original.
*/
- private boolean createName(FontFileReader in) throws IOException {
+ protected boolean createName(FontFileReader in) throws IOException {
return copyTable(in, OFTableName.NAME);
}
/**
* Copy the OS/2 table as is from the original.
*/
- private boolean createOS2(FontFileReader in) throws IOException {
+ protected boolean createOS2(FontFileReader in) throws IOException {
return copyTable(in, OFTableName.OS2);
}
@@ -221,14 +225,13 @@
* Copy the maxp table as is from original font to subset font
* and set num glyphs to size
*/
- private void createMaxp(FontFileReader in, int size) throws IOException {
+ protected void createMaxp(FontFileReader in, int size) throws IOException {
OFTableName maxp = OFTableName.MAXP;
OFDirTabEntry entry = dirTabs.get(maxp);
if (entry != null) {
pad4();
seekTab(in, maxp, 0);
- System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
- 0, output, currentPos, (int)entry.getLength());
+ writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
writeUShort(currentPos + 4, size);
updateCheckSum(currentPos, (int)entry.getLength(), maxp);
@@ -239,7 +242,7 @@
}
}
- private void createPost(FontFileReader in) throws IOException {
+ protected void createPost(FontFileReader in) throws IOException {
OFTableName post = OFTableName.POST;
OFDirTabEntry entry = dirTabs.get(post);
if (entry != null) {
@@ -252,12 +255,12 @@
0, newPostTable, 0, newTableSize);
// set the post table to Format 3.0
newPostTable[1] = 0x03;
- System.arraycopy(newPostTable, 0, output, currentPos, newTableSize);
+ writeBytes(newPostTable);
updateCheckSum(currentPos, newTableSize, post);
currentPos += newTableSize;
realSize += newTableSize;
} else {
- throw new IOException("Can't find post table");
+// throw new IOException("Can't find post table");
}
}
@@ -265,7 +268,7 @@
/**
* Copy the prep table as is from original font to subset font
*/
- private boolean createPrep(FontFileReader in) throws IOException {
+ protected boolean createPrep(FontFileReader in) throws IOException {
return copyTable(in, OFTableName.PREP);
}
@@ -274,13 +277,12 @@
* Copy the hhea table as is from original font to subset font
* and fill in size of hmtx table
*/
- private void createHhea(FontFileReader in, int size) throws IOException {
+ protected void createHhea(FontFileReader in, int size) throws IOException {
OFDirTabEntry entry = dirTabs.get(OFTableName.HHEA);
if (entry != null) {
pad4();
seekTab(in, OFTableName.HHEA, 0);
- System.arraycopy(in.getBytes((int) entry.getOffset(), (int) entry.getLength()), 0,
- output, currentPos, (int) entry.getLength());
+ writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
writeUShort((int) entry.getLength() + currentPos - 2, size);
updateCheckSum(currentPos, (int) entry.getLength(), OFTableName.HHEA);
@@ -298,14 +300,13 @@
* checkSumAdjustment to 0, store offset to checkSumAdjustment
* in checkSumAdjustmentOffset
*/
- private void createHead(FontFileReader in) throws IOException {
+ protected void createHead(FontFileReader in) throws IOException {
OFTableName head = OFTableName.HEAD;
OFDirTabEntry entry = dirTabs.get(head);
if (entry != null) {
pad4();
seekTab(in, head, 0);
- System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
- 0, output, currentPos, (int)entry.getLength());
+ writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
checkSumAdjustmentOffset = currentPos + 8;
output[currentPos + 8] = 0; // Set checkSumAdjustment to 0
@@ -313,8 +314,9 @@
output[currentPos + 10] = 0;
output[currentPos + 11] = 0;
output[currentPos + 50] = 0; // long locaformat
- output[currentPos + 51] = 1; // long locaformat
-
+ if (cid) {
+ output[currentPos + 51] = 1; // long locaformat
+ }
updateCheckSum(currentPos, (int)entry.getLength(), head);
currentPos += (int)entry.getLength();
realSize += (int)entry.getLength();
@@ -361,10 +363,7 @@
glyphLength);
int endOffset1 = endOffset;
// Copy glyph
- System.arraycopy(
- glyphData, 0,
- output, currentPos,
- glyphLength);
+ writeBytes(glyphData);
// Update loca table
@@ -402,12 +401,14 @@
}
}
- private int[] buildSubsetIndexToOrigIndexMap(Map glyphs) {
+ protected int[] buildSubsetIndexToOrigIndexMap(Map glyphs) {
int[] origIndexes = new int[glyphs.size()];
for (Map.Entry glyph : glyphs.entrySet()) {
int origIndex = glyph.getKey();
int subsetIndex = glyph.getValue();
- origIndexes[subsetIndex] = origIndex;
+ if (origIndexes.length > subsetIndex) {
+ origIndexes[subsetIndex] = origIndex;
+ }
}
return origIndexes;
}
@@ -418,8 +419,8 @@
* Integer key and Integer value that maps the original
* metric (key) to the subset metric (value)
*/
- private void createHmtx(FontFileReader in,
- Map glyphs) throws IOException {
+ protected void createHmtx(FontFileReader in,
+ Map glyphs) throws IOException {
OFTableName hmtx = OFTableName.HMTX;
OFDirTabEntry entry = dirTabs.get(hmtx);
@@ -560,7 +561,7 @@
ttfOut.endFontStream();
}
- private void scanGlyphs(FontFileReader in, Map subsetGlyphs)
+ protected void scanGlyphs(FontFileReader in, Map subsetGlyphs)
throws IOException {
OFDirTabEntry glyfTableInfo = dirTabs.get(OFTableName.GLYF);
if (glyfTableInfo == null) {
@@ -580,7 +581,7 @@
int length = 0;
try {
byte[] buf = str.getBytes("ISO-8859-1");
- System.arraycopy(buf, 0, output, currentPos, buf.length);
+ writeBytes(buf);
length = buf.length;
currentPos += length;
} catch (java.io.UnsupportedEncodingException e) {
@@ -598,11 +599,20 @@
output[currentPos++] = b;
}
+ protected void writeBytes(byte[] b) {
+ if (b.length + currentPos > output.length) {
+ byte[] newoutput = new byte[output.length * 2];
+ System.arraycopy(output, 0, newoutput, 0, output.length);
+ output = newoutput;
+ }
+ System.arraycopy(b, 0, output, currentPos, b.length);
+ }
+
/**
* Appends a USHORT to the output array,
* updates currentPost but not realSize
*/
- private void writeUShort(int s) {
+ protected void writeUShort(int s) {
byte b1 = (byte)((s >> 8) & 0xff);
byte b2 = (byte)(s & 0xff);
writeByte(b1);
@@ -613,7 +623,7 @@
* Appends a USHORT to the output array,
* at the given position without changing currentPos
*/
- private void writeUShort(int pos, int s) {
+ protected void writeUShort(int pos, int s) {
byte b1 = (byte)((s >> 8) & 0xff);
byte b2 = (byte)(s & 0xff);
output[pos] = b1;
@@ -625,7 +635,7 @@
* Appends a ULONG to the output array,
* at the given position without changing currentPos
*/
- private void writeULong(int pos, int s) {
+ protected void writeULong(int pos, int s) {
byte b1 = (byte)((s >> 24) & 0xff);
byte b2 = (byte)((s >> 16) & 0xff);
byte b3 = (byte)((s >> 8) & 0xff);
@@ -640,7 +650,7 @@
* Create a padding in the fontfile to align
* on a 4-byte boundary
*/
- private void pad4() {
+ protected void pad4() {
int padSize = getPadSize(currentPos);
if (padSize < 4) {
for (int i = 0; i < padSize; i++) {
@@ -663,7 +673,7 @@
}
- private void updateCheckSum(int tableStart, int tableSize, OFTableName tableName) {
+ protected void updateCheckSum(int tableStart, int tableSize, OFTableName tableName) {
int checksum = getCheckSum(output, tableStart, tableSize);
int offset = offsets.get(tableName);
int padSize = getPadSize(tableStart + tableSize);
@@ -673,7 +683,7 @@
writeULong(offset + 8, tableSize);
}
- private static int getCheckSum(byte[] data, int start, int size) {
+ protected static int getCheckSum(byte[] data, int start, int size) {
// All the tables here are aligned on four byte boundaries
// Add remainder to size if it's not a multiple of 4
int remainder = size % 4;
@@ -687,14 +697,16 @@
long l = 0;
for (int j = 0; j < 4; j++) {
l <<= 8;
- l |= data[start + i + j] & 0xff;
+ if (data.length > (start + i + j)) {
+ l |= data[start + i + j] & 0xff;
+ }
}
sum += l;
}
return (int) sum;
}
- private void createCheckSumAdjustment() {
+ protected void createCheckSumAdjustment() {
long sum = getCheckSum(output, 0, realSize);
int checksum = (int)(0xb1b0afba - sum);
writeULong(checkSumAdjustmentOffset, checksum);
Index: src/java/org/apache/fop/pdf/PDFCFFStream.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFCFFStream.java (revision 0)
+++ src/java/org/apache/fop/pdf/PDFCFFStream.java (working copy)
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Special PDFStream for embeddable CFF fonts.
+ */
+public class PDFCFFStream extends AbstractPDFFontStream {
+ private byte[] cffData;
+ private String type;
+
+ public PDFCFFStream(String type) {
+ this.type = type;
+ }
+
+ protected int getSizeHint() throws IOException {
+ if (this.cffData != null) {
+ return cffData.length;
+ } else {
+ return 0; //no hint available
+ }
+ }
+
+ protected void outputRawStreamData(OutputStream out) throws IOException {
+ out.write(this.cffData);
+ }
+
+ protected void populateStreamDict(Object lengthEntry) {
+ put("Subtype", new PDFName(type));
+ super.populateStreamDict(lengthEntry);
+ }
+
+ public void setData(byte[] data) throws IOException {
+ cffData = data;
+ }
+}
Property changes on: src/java/org/apache/fop/pdf/PDFCFFStream.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: src/java/org/apache/fop/pdf/PDFDocument.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFDocument.java (revision 1570221)
+++ src/java/org/apache/fop/pdf/PDFDocument.java (working copy)
@@ -167,6 +167,8 @@
private boolean accessibilityEnabled;
+ private boolean mergeFontsEnabled;
+
/**
* Creates an empty PDF document.
*
@@ -1082,6 +1084,14 @@
return trailerDictionary;
}
+ public boolean isMergeFontsEnabled() {
+ return mergeFontsEnabled;
+ }
+
+ public void setMergeFontsEnabled(boolean mergeFontsEnabled) {
+ this.mergeFontsEnabled = mergeFontsEnabled;
+ }
+
private interface TrailerOutputHelper {
void outputStructureTreeElements(OutputStream stream) throws IOException;
Index: src/java/org/apache/fop/pdf/PDFFactory.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFFactory.java (revision 1570221)
+++ src/java/org/apache/fop/pdf/PDFFactory.java (working copy)
@@ -1340,9 +1340,15 @@
PDFFont font = null;
font = PDFFont.createFont(fontname, fonttype, subsetFontName, null);
- getDocument().registerObject(font);
+ if (descriptor instanceof RefPDFFont) {
+ font.setObjectNumber(((RefPDFFont)descriptor).getRef().getObjectNumber());
+ font.setDocument(getDocument());
+ getDocument().addObject(font);
+ } else {
+ getDocument().registerObject(font);
+ }
- if (fonttype == FontType.TYPE0) {
+ if ((fonttype == FontType.TYPE0) && pdfdesc instanceof PDFCIDFontDescriptor) {
font.setEncoding(encoding);
CIDFont cidMetrics;
if (metrics instanceof LazyFont) {
@@ -1357,8 +1363,19 @@
cidMetrics.getDefaultWidth(), getFontWidths(cidMetrics), sysInfo,
(PDFCIDFontDescriptor) pdfdesc);
getDocument().registerObject(cidFont);
- PDFCMap cmap = new PDFToUnicodeCMap(cidMetrics.getCIDSet().getChars(), "fop-ucs-H",
+
+ PDFCMap cmap;
+ if (cidMetrics instanceof MultiByteFont && ((MultiByteFont) cidMetrics).getCmapStream() != null) {
+ cmap = new PDFCMap("fop-ucs-H", null);
+ try {
+ cmap.setData(IOUtils.toByteArray(((MultiByteFont) cidMetrics).getCmapStream()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ cmap = new PDFToUnicodeCMap(cidMetrics.getCIDSet().getChars(), "fop-ucs-H",
new PDFCIDSystemInfo("Adobe", "Identity", 0), false);
+ }
getDocument().registerObject(cmap);
((PDFFontType0)font).setCMAP(cmap);
((PDFFontType0)font).setDescendantFonts(cidFont);
@@ -1389,6 +1406,29 @@
font.setEncoding(mapping.getName());
//No ToUnicode CMap necessary if PDF 1.4, chapter 5.9 (page 368) is to be
//believed.
+ } else if (mapping.getName().equals("FOPPDFEncoding")) {
+ String[] charNameMap = mapping.getCharNameMap();
+ char[] intmap = mapping.getUnicodeCharMap();
+ PDFArray differences = new PDFArray();
+ int len = intmap.length;
+ if (charNameMap.length < len) {
+ len = charNameMap.length;
+ }
+ int last = 0;
+ for (int i = 0; i < len; i++) {
+ if (intmap[i] - 1 != last) {
+ differences.add(intmap[i]);
+ }
+ last = intmap[i];
+ differences.add(new PDFName(charNameMap[i]));
+ }
+ PDFEncoding pdfEncoding = new PDFEncoding(singleByteFont.getEncodingName());
+ getDocument().registerObject(pdfEncoding);
+ pdfEncoding.setDifferences(differences);
+ font.setEncoding(pdfEncoding);
+ if (mapping.getUnicodeCharMap() != null) {
+ generateToUnicodeCmap(nonBase14, mapping);
+ }
} else {
Object pdfEncoding = createPDFEncoding(mapping,
singleByteFont.getFontName());
@@ -1452,8 +1492,30 @@
private PDFWArray getFontWidths(CIDFont cidFont) {
// Create widths for reencoded chars
PDFWArray warray = new PDFWArray();
- int[] widths = cidFont.getCIDSet().getWidths();
- warray.addEntry(0, widths);
+ if (cidFont instanceof MultiByteFont && ((MultiByteFont)cidFont).getWidthsMap() != null) {
+ Map map = ((MultiByteFont)cidFont).getWidthsMap();
+ for (Map.Entry cid : map.entrySet()) {
+ warray.addEntry(cid.getKey(), new int[] {cid.getValue()});
+ }
+// List l = new ArrayList(map.keySet());
+// for (int i=0; i cids = new ArrayList();
+// cids.add(map.get(cid));
+// while (i