diff options
author | Jeremias Maerki <jeremias@apache.org> | 2010-11-15 15:31:38 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2010-11-15 15:31:38 +0000 |
commit | f133bab5a846c87a88eb697fee4b659122c46bdb (patch) | |
tree | 4c87cd315122da809d06271563c1059f59fa6d82 | |
parent | a46140eafd2005fac84de4a359ee484aadb3f968 (diff) | |
download | xmlgraphics-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.java | 3 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/CustomFont.java | 24 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/FontReader.java | 7 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/MultiByteFont.java | 29 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/SingleByteFont.java | 16 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/truetype/TTFFile.java | 42 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java | 26 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/ps/PSFontUtils.java | 74 |
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"); } |