aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2010-11-15 15:31:38 +0000
committerJeremias Maerki <jeremias@apache.org>2010-11-15 15:31:38 +0000
commitf133bab5a846c87a88eb697fee4b659122c46bdb (patch)
tree4c87cd315122da809d06271563c1059f59fa6d82
parenta46140eafd2005fac84de4a359ee484aadb3f968 (diff)
downloadxmlgraphics-fop-f133bab5a846c87a88eb697fee4b659122c46bdb.tar.gz
xmlgraphics-fop-f133bab5a846c87a88eb697fee4b659122c46bdb.zip
Added full support for single-byte encodings when TTF fonts are embedded in PostScript.
Deprecated MultiByteFont.setBFEntries() in favor of CustomFont.setCMap(). Added some TODO related to BFEntry and TTFCmapEntry essentially being the same class. Maybe we should rename BFEntry. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1035307 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/fonts/BFEntry.java3
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java24
-rw-r--r--src/java/org/apache/fop/fonts/FontReader.java7
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java29
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteFont.java16
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java4
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFile.java42
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java26
-rw-r--r--src/java/org/apache/fop/render/ps/PSFontUtils.java74
9 files changed, 138 insertions, 87 deletions
diff --git a/src/java/org/apache/fop/fonts/BFEntry.java b/src/java/org/apache/fop/fonts/BFEntry.java
index 4e0b169fd..c8311a9d2 100644
--- a/src/java/org/apache/fop/fonts/BFEntry.java
+++ b/src/java/org/apache/fop/fonts/BFEntry.java
@@ -24,6 +24,9 @@ package org.apache.fop.fonts;
*/
public class BFEntry {
+ //TODO Think about renaming this class to CMapRange or something.
+ //TODO Copy equals() and hashCode() from TTFCmapEntry
+
private int unicodeStart;
private int unicodeEnd;
private int glyphStartIndex;
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
index 4cf24ae16..c3687a94e 100644
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -59,6 +59,9 @@ public abstract class CustomFont extends Typeface
private boolean useKerning = true;
+ /** the character map, mapping Unicode ranges to glyph indices. */
+ protected BFEntry[] cmap;
+
/** {@inheritDoc} */
public String getFontName() {
return fontName;
@@ -454,4 +457,25 @@ public abstract class CustomFont extends Typeface
}
}
+ /**
+ * Sets the identity character map for this font. It maps all available Unicode characters
+ * to their glyph indices inside the font.
+ * @param cmap the identity character map
+ */
+ public void setCMap(BFEntry[] cmap) {
+ this.cmap = new BFEntry[cmap.length];
+ System.arraycopy(cmap, 0, this.cmap, 0, cmap.length);
+ }
+
+ /**
+ * Returns the identity character map for this font. It maps all available Unicode characters
+ * to their glyph indices inside the font.
+ * @return the identity character map
+ */
+ public BFEntry[] getCMap() {
+ BFEntry[] copy = new BFEntry[cmap.length];
+ System.arraycopy(this.cmap, 0, copy, 0, this.cmap.length);
+ return copy;
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/FontReader.java b/src/java/org/apache/fop/fonts/FontReader.java
index 16da99baa..34da35f85 100644
--- a/src/java/org/apache/fop/fonts/FontReader.java
+++ b/src/java/org/apache/fop/fonts/FontReader.java
@@ -143,12 +143,14 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void startDocument() {
}
/**
* {@inheritDoc}
*/
+ @Override
public void setDocumentLocator(Locator locator) {
this.locator = locator;
}
@@ -156,6 +158,7 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("font-metrics")) {
@@ -224,6 +227,7 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
String content = text.toString().trim();
if ("font-name".equals(localName)) {
@@ -292,7 +296,7 @@ public class FontReader extends DefaultHandler {
multiFont.setWidthArray(wds);
} else if ("bfranges".equals(localName)) {
- multiFont.setBFEntries((BFEntry[])bfranges.toArray(new BFEntry[0]));
+ multiFont.setCMap((BFEntry[])bfranges.toArray(new BFEntry[0]));
}
text.setLength(0); //Reset text buffer (see characters())
}
@@ -300,6 +304,7 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void characters(char[] ch, int start, int length) {
text.append(ch, start, length);
}
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index b3b5d8639..e285fa068 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -41,9 +41,6 @@ public class MultiByteFont extends CIDFont {
private CIDSubset subset = new CIDSubset();
- /** A map from Unicode indices to glyph indices */
- private BFEntry[] bfentries = null;
-
/**
* Default constructor
*/
@@ -74,26 +71,31 @@ public class MultiByteFont extends CIDFont {
}
/** {@inheritDoc} */
+ @Override
public int getDefaultWidth() {
return defaultWidth;
}
/** {@inheritDoc} */
+ @Override
public String getRegistry() {
return "Adobe";
}
/** {@inheritDoc} */
+ @Override
public String getOrdering() {
return "UCS";
}
/** {@inheritDoc} */
+ @Override
public int getSupplement() {
return 0;
}
/** {@inheritDoc} */
+ @Override
public CIDFontType getCIDType() {
return cidType;
}
@@ -111,6 +113,7 @@ public class MultiByteFont extends CIDFont {
}
/** {@inheritDoc} */
+ @Override
public String getEmbedFontName() {
if (isEmbeddable()) {
return getPrefixedFontName();
@@ -125,11 +128,13 @@ public class MultiByteFont extends CIDFont {
}
/** {@inheritDoc} */
+ @Override
public CIDSubset getCIDSubset() {
return this.subset;
}
/** {@inheritDoc} */
+ @Override
public String getEncodingName() {
return encoding;
}
@@ -158,22 +163,23 @@ public class MultiByteFont extends CIDFont {
* @return the glyph index (or 0 if the glyph is not available)
*/
private int findGlyphIndex(char c) {
- int idx = (int)c;
+ int idx = c;
int retIdx = SingleByteEncoding.NOT_FOUND_CODE_POINT;
- for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
- if (bfentries[i].getUnicodeStart() <= idx
- && bfentries[i].getUnicodeEnd() >= idx) {
+ for (int i = 0; (i < cmap.length) && retIdx == 0; i++) {
+ if (cmap[i].getUnicodeStart() <= idx
+ && cmap[i].getUnicodeEnd() >= idx) {
- retIdx = bfentries[i].getGlyphStartIndex()
+ retIdx = cmap[i].getGlyphStartIndex()
+ idx
- - bfentries[i].getUnicodeStart();
+ - cmap[i].getUnicodeStart();
}
}
return retIdx;
}
/** {@inheritDoc} */
+ @Override
public char mapChar(char c) {
notifyMapOperation();
int glyphIndex = findGlyphIndex(c);
@@ -188,6 +194,7 @@ public class MultiByteFont extends CIDFont {
}
/** {@inheritDoc} */
+ @Override
public boolean hasChar(char c) {
return (findGlyphIndex(c) != SingleByteEncoding.NOT_FOUND_CODE_POINT);
}
@@ -196,9 +203,11 @@ public class MultiByteFont extends CIDFont {
* Sets the array of BFEntry instances which constitutes the Unicode to glyph index map for
* a font. ("BF" means "base font")
* @param entries the Unicode to glyph index map
+ * @deprecated use {@link #setCMap(BFEntry[])} instead
*/
+ @Deprecated
public void setBFEntries(BFEntry[] entries) {
- this.bfentries = entries;
+ setCMap(entries);
}
/**
diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java
index a09c81670..7f103b134 100644
--- a/src/java/org/apache/fop/fonts/SingleByteFont.java
+++ b/src/java/org/apache/fop/fonts/SingleByteFont.java
@@ -46,8 +46,6 @@ public class SingleByteFont extends CustomFont {
//Map<Character, UnencodedCharacter>
private List additionalEncodings;
- private List cmaps;
-
private PostScriptVersion ttPostScriptVersion;
/**
@@ -64,6 +62,7 @@ public class SingleByteFont extends CustomFont {
}
/** {@inheritDoc} */
+ @Override
public String getEncodingName() {
return this.mapping.getName();
}
@@ -104,6 +103,7 @@ public class SingleByteFont extends CustomFont {
}
/** {@inheritDoc} */
+ @Override
public char mapChar(char c) {
notifyMapOperation();
char d = mapping.mapChar(c);
@@ -155,6 +155,7 @@ public class SingleByteFont extends CustomFont {
}
/** {@inheritDoc} */
+ @Override
public boolean hasChar(char c) {
char d = mapping.mapChar(c);
if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
@@ -334,6 +335,7 @@ public class SingleByteFont extends CustomFont {
}
/** {@inheritDoc} */
+ @Override
public String toString() {
return getCharacter().toString();
}
@@ -360,15 +362,5 @@ public class SingleByteFont extends CustomFont {
return ttPostScriptVersion;
}
- /** TODO remove */
- public void setCMaps(List cmaps) {
- this.cmaps = cmaps;
- }
-
- /** TODO remove */
- public List getCMaps() {
- return cmaps;
- }
-
}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java b/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java
index 897d5e2de..a63f76def 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java
@@ -25,6 +25,8 @@ package org.apache.fop.fonts.truetype;
*/
public class TTFCmapEntry {
+ //TODO this class is redundant: BFEntry does the same but doesn't have an intuitive name
+
private int unicodeStart;
private int unicodeEnd;
private int glyphStartIndex;
@@ -44,6 +46,7 @@ public class TTFCmapEntry {
/**
* {@inheritDoc}
*/
+ @Override
public int hashCode() {
int hc = super.hashCode();
hc ^= ( hc * 11 ) + unicodeStart;
@@ -55,6 +58,7 @@ public class TTFCmapEntry {
/**
* {@inheritDoc}
*/
+ @Override
public boolean equals(Object o) {
if (o instanceof TTFCmapEntry) {
TTFCmapEntry ce = (TTFCmapEntry)o;
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
index 6f3bb9f49..c288b2586 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
@@ -143,7 +143,7 @@ public class TTFFile {
protected Map dirTabs;
private Map kerningTab; // for CIDs
private Map ansiKerningTab; // For winAnsiEncoding
- private List cmaps;
+ private List<TTFCmapEntry> cmaps;
private List unicodeMapping;
private int upem; // unitsPerEm from "head" table
@@ -597,7 +597,7 @@ public class TTFFile {
ansiIndex = new java.util.HashMap();
for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
Integer ansi = new Integer(i);
- Integer uni = new Integer((int)Glyphs.WINANSI_ENCODING[i]);
+ Integer uni = new Integer(Glyphs.WINANSI_ENCODING[i]);
List v = (List)ansiIndex.get(uni);
if (v == null) {
@@ -669,7 +669,7 @@ public class TTFFile {
}
private void createCMaps() {
- cmaps = new java.util.ArrayList();
+ this.cmaps = new java.util.ArrayList<TTFCmapEntry>();
TTFCmapEntry tce = new TTFCmapEntry();
Iterator e = unicodeMapping.listIterator();
@@ -750,7 +750,7 @@ public class TTFFile {
* @return int The CapHeight
*/
public int getCapHeight() {
- return (int)convertTTFUnit2PDFUnit(capHeight);
+ return convertTTFUnit2PDFUnit(capHeight);
}
/**
@@ -758,7 +758,7 @@ public class TTFFile {
* @return int The XHeight
*/
public int getXHeight() {
- return (int)convertTTFUnit2PDFUnit(xHeight);
+ return convertTTFUnit2PDFUnit(xHeight);
}
/**
@@ -817,10 +817,10 @@ public class TTFFile {
*/
public int[] getFontBBox() {
final int[] fbb = new int[4];
- fbb[0] = (int)convertTTFUnit2PDFUnit(fontBBox1);
- fbb[1] = (int)convertTTFUnit2PDFUnit(fontBBox2);
- fbb[2] = (int)convertTTFUnit2PDFUnit(fontBBox3);
- fbb[3] = (int)convertTTFUnit2PDFUnit(fontBBox4);
+ fbb[0] = convertTTFUnit2PDFUnit(fontBBox1);
+ fbb[1] = convertTTFUnit2PDFUnit(fontBBox2);
+ fbb[2] = convertTTFUnit2PDFUnit(fontBBox3);
+ fbb[3] = convertTTFUnit2PDFUnit(fontBBox4);
return fbb;
}
@@ -830,7 +830,7 @@ public class TTFFile {
* @return int The LowerCaseAscent
*/
public int getLowerCaseAscent() {
- return (int)convertTTFUnit2PDFUnit(ascender);
+ return convertTTFUnit2PDFUnit(ascender);
}
/**
@@ -838,7 +838,7 @@ public class TTFFile {
* @return int The LowerCaseDescent
*/
public int getLowerCaseDescent() {
- return (int)convertTTFUnit2PDFUnit(descender);
+ return convertTTFUnit2PDFUnit(descender);
}
/**
@@ -865,7 +865,7 @@ public class TTFFile {
public int[] getWidths() {
int[] wx = new int[mtxTab.length];
for (int i = 0; i < wx.length; i++) {
- wx[i] = (int)convertTTFUnit2PDFUnit(mtxTab[i].getWx());
+ wx[i] = convertTTFUnit2PDFUnit(mtxTab[i].getWx());
}
return wx;
@@ -877,7 +877,7 @@ public class TTFFile {
* @return int Standard width
*/
public int getCharWidth(int idx) {
- return (int)convertTTFUnit2PDFUnit(ansiWidth[idx]);
+ return convertTTFUnit2PDFUnit(ansiWidth[idx]);
}
/**
@@ -1557,7 +1557,7 @@ public class TTFFile {
if (adjTab == null) {
adjTab = new java.util.HashMap();
}
- adjTab.put(u2, new Integer((int)convertTTFUnit2PDFUnit(kpx)));
+ adjTab.put(u2, new Integer(convertTTFUnit2PDFUnit(kpx)));
kerningTab.put(iObj, adjTab);
}
}
@@ -1608,7 +1608,7 @@ public class TTFFile {
* Return a List with TTFCmapEntry.
* @return A list of TTFCmapEntry objects
*/
- public List getCMaps() {
+ public List<TTFCmapEntry> getCMaps() {
return cmaps;
}
@@ -1753,8 +1753,8 @@ public class TTFFile {
System.out.println("Family name: " + familyNames);
System.out.println("Subfamily name: " + subFamilyName);
System.out.println("Notice: " + notice);
- System.out.println("xHeight: " + (int)convertTTFUnit2PDFUnit(xHeight));
- System.out.println("capheight: " + (int)convertTTFUnit2PDFUnit(capHeight));
+ System.out.println("xHeight: " + convertTTFUnit2PDFUnit(xHeight));
+ System.out.println("capheight: " + convertTTFUnit2PDFUnit(capHeight));
int italic = (int)(italicAngle >> 16);
System.out.println("Italic: " + italic);
@@ -1767,10 +1767,10 @@ public class TTFFile {
System.out.println();
System.out.println("Ascender: " + convertTTFUnit2PDFUnit(ascender));
System.out.println("Descender: " + convertTTFUnit2PDFUnit(descender));
- System.out.println("FontBBox: [" + (int)convertTTFUnit2PDFUnit(fontBBox1)
- + " " + (int)convertTTFUnit2PDFUnit(fontBBox2) + " "
- + (int)convertTTFUnit2PDFUnit(fontBBox3) + " "
- + (int)convertTTFUnit2PDFUnit(fontBBox4) + "]");
+ System.out.println("FontBBox: [" + convertTTFUnit2PDFUnit(fontBBox1)
+ + " " + convertTTFUnit2PDFUnit(fontBBox2) + " "
+ + convertTTFUnit2PDFUnit(fontBBox3) + " "
+ + convertTTFUnit2PDFUnit(fontBBox4) + "]");
}
private String formatUnitsForDebug(int units) {
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
index cf24ea352..011f444cd 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
@@ -80,6 +80,7 @@ public class TTFFontLoader extends FontLoader {
}
/** {@inheritDoc} */
+ @Override
protected void read() throws IOException {
read(this.subFontName);
}
@@ -147,26 +148,15 @@ public class TTFFontLoader extends FontLoader {
multiFont.setCIDType(CIDFontType.CIDTYPE2);
int[] wx = ttf.getWidths();
multiFont.setWidthArray(wx);
- List entries = ttf.getCMaps();
- BFEntry[] bfentries = new BFEntry[entries.size()];
- int pos = 0;
- Iterator iter = ttf.getCMaps().listIterator();
- while (iter.hasNext()) {
- TTFCmapEntry ce = (TTFCmapEntry)iter.next();
- bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),
- ce.getGlyphStartIndex());
- pos++;
- }
- multiFont.setBFEntries(bfentries);
} else {
singleFont.setFontType(FontType.TRUETYPE);
singleFont.setEncoding(ttf.getCharSetName());
returnFont.setFirstChar(ttf.getFirstChar());
returnFont.setLastChar(ttf.getLastChar());
- singleFont.setCMaps(ttf.getCMaps());
singleFont.setTrueTypePostScriptVersion(ttf.getPostScriptVersion());
copyWidthsSingleByte(ttf);
}
+ returnFont.setCMap(getCMap(ttf));
if (useKerning) {
copyKerning(ttf, isCid);
@@ -176,6 +166,18 @@ public class TTFFontLoader extends FontLoader {
}
}
+ private BFEntry[] getCMap(TTFFile ttf) {
+ List<TTFCmapEntry> entries = ttf.getCMaps();
+ BFEntry[] bfentries = new BFEntry[entries.size()];
+ int pos = 0;
+ for (TTFCmapEntry ce : ttf.getCMaps()) {
+ bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),
+ ce.getGlyphStartIndex());
+ pos++;
+ }
+ return bfentries;
+ }
+
private void copyWidthsSingleByte(TTFFile ttf) {
int[] wx = ttf.getWidths();
for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) {
diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java
index 1f6129dc0..3cdfdfd4d 100644
--- a/src/java/org/apache/fop/render/ps/PSFontUtils.java
+++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java
@@ -23,11 +23,8 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
-import java.util.Collections;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
@@ -42,6 +39,7 @@ import org.apache.xmlgraphics.ps.PSResource;
import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream;
+import org.apache.fop.fonts.BFEntry;
import org.apache.fop.fonts.Base14Font;
import org.apache.fop.fonts.CIDFontType;
import org.apache.fop.fonts.CIDSubset;
@@ -55,7 +53,6 @@ import org.apache.fop.fonts.SingleByteEncoding;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.fonts.truetype.FontFileReader;
-import org.apache.fop.fonts.truetype.TTFCmapEntry;
import org.apache.fop.fonts.truetype.TTFSubSetFile;
import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
import org.apache.fop.util.HexEncoder;
@@ -152,7 +149,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
&& sbf.getTrueTypePostScriptVersion() != PostScriptVersion.V2) {
derivedFontRes = defineDerivedTrueTypeFont(gen, eventProducer,
tf.getEmbedFontName(), tf.getEmbedFontName() + postFix, encoding,
- sbf.getCMaps());
+ sbf.getCMap());
} else {
derivedFontRes = defineDerivedFont(gen, tf.getEmbedFontName(),
tf.getEmbedFontName() + postFix, encoding.getName());
@@ -298,12 +295,12 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
/* See Adobe Technical Note #5012, "The Type 42 Font Format Specification" */
gen.commentln("%!PS-TrueTypeFont-65536-65536-1"); // TODO TrueType & font versions
gen.writeln("11 dict begin");
- createType42DictionaryEntries(gen, font, fontStream, font.getCMaps());
+ createType42DictionaryEntries(gen, font, fontStream, font.getCMap());
gen.writeln("FontName currentdict end definefont pop");
}
private static void createType42DictionaryEntries(PSGenerator gen, CustomFont font,
- InputStream fontStream, List cmaps) throws IOException {
+ InputStream fontStream, BFEntry[] cmap) throws IOException {
gen.write("/FontName /");
gen.write(font.getEmbedFontName());
gen.writeln(" def");
@@ -313,12 +310,13 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
gen.writeln("/FontType 42 def");
gen.writeln("/Encoding 256 array");
gen.writeln("0 1 255{1 index exch/.notdef put}for");
- Set<String> glyphs = null;
+ boolean buildCharStrings;
if (font.getFontType() == FontType.TYPE0) {
//"/Encoding" is required but ignored for CID fonts
//so we keep it minimal to save space
+ buildCharStrings = false;
} else {
- glyphs = new java.util.HashSet<String>();
+ buildCharStrings = true;
for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) {
gen.write("dup ");
gen.write(i);
@@ -327,7 +325,6 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
if (glyphName.equals("")) {
gen.write(Glyphs.NOTDEF);
} else {
- glyphs.add(glyphName); //TODO don't just register the WinAnsi subset!
gen.write(glyphName);
}
gen.writeln(" put");
@@ -357,33 +354,48 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
}
gen.writeln("]def");
gen.write("/CharStrings ");
- gen.write(glyphs != null ? glyphs.size() + 1 : 1);
+ if (buildCharStrings) {
+ int charCount = 1; //1 for .notdef
+ for (BFEntry entry : cmap) {
+ charCount += entry.getUnicodeEnd() - entry.getUnicodeStart() + 1;
+ }
+ gen.write(charCount);
+ } else {
+ gen.write(1);
+ }
gen.writeln(" dict dup begin");
gen.write("/");
gen.write(Glyphs.NOTDEF);
gen.writeln(" 0 def"); // .notdef always has to be at index 0
- if (glyphs != null) {
- //Only performed in singly-byte mode
- for (String glyphName : glyphs) {
- gen.write("/");
- gen.write(glyphName);
- gen.write(" ");
- gen.write(getGlyphIndex(glyphName, cmaps));
- gen.writeln(" def");
+ if (buildCharStrings) {
+ //Only performed in singly-byte mode, ignored for CID fonts
+
+ for (BFEntry entry : cmap) {
+ int glyphIndex = entry.getGlyphStartIndex();
+ for (int ch = entry.getUnicodeStart(); ch <= entry.getUnicodeEnd(); ch++) {
+ char ch16 = (char)ch; //TODO Handle Unicode characters beyond 16bit
+ String glyphName = Glyphs.charToGlyphName(ch16);
+
+ if ("".equals(glyphName)) {
+ glyphName = "u" + Integer.toHexString(ch).toUpperCase();
+ }
+ gen.write("/");
+ gen.write(glyphName);
+ gen.write(" ");
+ gen.write(glyphIndex);
+ gen.writeln(" def");
+
+ glyphIndex++;
+ }
}
}
gen.writeln("end readonly def");
}
- private static int getGlyphIndex(String glyphName, List cmaps) {
- return getGlyphIndex(Glyphs.getUnicodeSequenceForGlyphName(glyphName).charAt(0), cmaps);
- }
-
- private static int getGlyphIndex(char c, List cmaps) {
- for (Iterator iter = cmaps.iterator(); iter.hasNext();) {
- TTFCmapEntry cmap = (TTFCmapEntry) iter.next();
- if (cmap.getUnicodeStart() <= c && c <= cmap.getUnicodeEnd()) {
- return cmap.getGlyphStartIndex() + c - cmap.getUnicodeStart();
+ private static int getGlyphIndex(char c, BFEntry[] cmap) {
+ for (BFEntry entry : cmap) {
+ if (entry.getUnicodeStart() <= c && c <= entry.getUnicodeEnd()) {
+ return entry.getGlyphStartIndex() + c - entry.getUnicodeStart();
}
}
return 0;
@@ -481,7 +493,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
gen.writeln("] def");
InputStream subsetInput = new java.io.ByteArrayInputStream(subsetFont);
- createType42DictionaryEntries(gen, font, subsetInput, Collections.EMPTY_LIST);
+ createType42DictionaryEntries(gen, font, subsetInput, new BFEntry[0]);
gen.writeln("CIDFontName currentdict end /CIDFont defineresource pop");
gen.writeln("end");
gen.writeln("%%EndResource");
@@ -659,7 +671,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
private static PSResource defineDerivedTrueTypeFont(PSGenerator gen,
PSEventProducer eventProducer, String baseFontName, String fontName,
- SingleByteEncoding encoding, List cmaps) throws IOException {
+ SingleByteEncoding encoding, BFEntry[] cmap) throws IOException {
checkPostScriptLevel3(gen, eventProducer);
PSResource res = new PSResource(PSResource.TYPE_FONT, fontName);
gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res);
@@ -682,7 +694,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
if (glyphName.equals(".notdef")) {
gen.write(0);
} else {
- gen.write(getGlyphIndex(unicodeCharMap[i], cmaps));
+ gen.write(getGlyphIndex(unicodeCharMap[i], cmap));
}
gen.writeln(" def");
}