diff options
author | Jeremias Maerki <jeremias@apache.org> | 2010-11-03 16:22:50 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2010-11-03 16:22:50 +0000 |
commit | e725976e0051e90b91664cf96dc22d79a4425c16 (patch) | |
tree | b2b90529ccd68daa7bd3e944384ca8c274fa4961 /src | |
parent | 1080c61fb2f07d5995bd1671751f2f4bd11b1f3e (diff) | |
download | xmlgraphics-fop-e725976e0051e90b91664cf96dc22d79a4425c16.tar.gz xmlgraphics-fop-e725976e0051e90b91664cf96dc22d79a4425c16.zip |
TrueType subsetting for CID TTF fonts is now working.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1030518 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/java/org/apache/fop/render/ps/FontResourceCache.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/ps/PSFontUtils.java | 101 |
2 files changed, 61 insertions, 44 deletions
diff --git a/src/java/org/apache/fop/render/ps/FontResourceCache.java b/src/java/org/apache/fop/render/ps/FontResourceCache.java index 24a34e3db..dc88711b3 100644 --- a/src/java/org/apache/fop/render/ps/FontResourceCache.java +++ b/src/java/org/apache/fop/render/ps/FontResourceCache.java @@ -77,9 +77,9 @@ class FontResourceCache { throw new IllegalStateException("Font not available: " + key); } if (postFix == null) { - return tf.getFontName(); + return tf.getEmbedFontName(); } else { - return tf.getFontName() + postFix; + return tf.getEmbedFontName() + postFix; } } diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java index 5272dccac..8ff2a5567 100644 --- a/src/java/org/apache/fop/render/ps/PSFontUtils.java +++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -54,7 +53,9 @@ import org.apache.fop.fonts.MultiByteFont; 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; @@ -130,7 +131,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { while (iter.hasNext()) { String key = (String)iter.next(); Typeface tf = getTypeFace(fontInfo, fonts, key); - PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getFontName()); + PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName()); PSFontResource fontResource = embedFont(gen, tf, fontRes, eventProducer); fontResources.put(key, fontResource); @@ -149,11 +150,11 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { if (tf.getFontType() == FontType.TRUETYPE && sbf.getTrueTypePostScriptVersion() != PostScriptVersion.V2) { derivedFontRes = defineDerivedTrueTypeFont(gen, eventProducer, - tf.getFontName(), tf.getFontName() + postFix, encoding, + tf.getEmbedFontName(), tf.getEmbedFontName() + postFix, encoding, sbf.getCMaps()); } else { - derivedFontRes = defineDerivedFont(gen, tf.getFontName(), - tf.getFontName() + postFix, encoding.getName()); + derivedFontRes = defineDerivedFont(gen, tf.getEmbedFontName(), + tf.getEmbedFontName() + postFix, encoding.getName()); } fontResources.put(key + postFix, PSFontResource.createFontResource(derivedFontRes)); @@ -194,12 +195,12 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { } else { if (tf instanceof Base14Font) { //Our Base 14 fonts don't use the default encoding - redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName()); + redefineFontEncoding(gen, tf.getEmbedFontName(), tf.getEncodingName()); } else if (tf instanceof SingleByteFont) { SingleByteFont sbf = (SingleByteFont)tf; if (!sbf.isUsingNativeEncoding()) { //Font has been configured to use an encoding other than the default one - redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName()); + redefineFontEncoding(gen, tf.getEmbedFontName(), tf.getEncodingName()); } } } @@ -235,7 +236,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { if (in != null) { if (fontType == FontType.TYPE0) { if (gen.embedIdentityH()) { - checkPostScriptVersion(gen, eventProducer); + checkPostScriptLevel3(gen, eventProducer); /* * First CID-keyed font to be embedded; add * %%IncludeResource: comment for ProcSet CIDInit. @@ -257,14 +258,14 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { embedTrueTypeFont(gen, (SingleByteFont) tf, in); fontResource = PSFontResource.createFontResource(fontRes); } else { - embedType0Font(gen, (MultiByteFont) tf, in); + composeType0Font(gen, (MultiByteFont) tf, in); } gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(fontRes); embeddedFont = true; } else { - gen.commentln("%WARNING: Could not embed font: " + cf.getFontName()); - log.warn("Font " + cf.getFontName() + " is marked as supplied in the" + gen.commentln("%WARNING: Could not embed font: " + cf.getEmbedFontName()); + log.warn("Font " + cf.getEmbedFontName() + " is marked as supplied in the" + " PostScript file but could not be embedded!"); } } @@ -277,7 +278,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { return fontResource; } - private static void checkPostScriptVersion(PSGenerator gen, PSEventProducer eventProducer) { + private static void checkPostScriptLevel3(PSGenerator gen, PSEventProducer eventProducer) { if (gen.getPSLevel() < 3) { if (eventProducer != null) { eventProducer.postscriptLevel3Needed(gen); @@ -302,7 +303,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { private static void createType42DictionaryEntries(PSGenerator gen, CustomFont font, InputStream fontStream, List cmaps) throws IOException { gen.write("/FontName /"); - gen.write(font.getFontName()); + gen.write(font.getEmbedFontName()); gen.writeln(" def"); gen.writeln("/PaintType 0 def"); gen.writeln("/FontMatrix [1 0 0 1 0 0] def"); @@ -310,19 +311,25 @@ 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 glyphs = new HashSet(); - for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) { - gen.write("dup "); - gen.write(i); - gen.write(" /"); - String glyphName = Glyphs.charToGlyphName(Glyphs.WINANSI_ENCODING[i]); - if (glyphName.equals("")) { - gen.write(Glyphs.NOTDEF); - } else { - glyphs.add(glyphName); - gen.write(glyphName); + Set glyphs = null; + if (font.getFontType() == FontType.TYPE0) { + //"/Encoding" is required but ignored for CID fonts + //so we keep it minimal to save space + } else { + glyphs = new java.util.HashSet(); + for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) { + gen.write("dup "); + gen.write(i); + gen.write(" /"); + String glyphName = Glyphs.charToGlyphName(Glyphs.WINANSI_ENCODING[i]); + 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"); } - gen.writeln(" put"); } gen.writeln("readonly def"); gen.write("/sfnts["); @@ -348,19 +355,22 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { } gen.writeln("]def"); gen.write("/CharStrings "); - gen.write(glyphs.size() + 1); + gen.write(1); + //gen.write(glyphs.size() + 1); gen.writeln(" dict dup begin"); gen.write("/"); gen.write(Glyphs.NOTDEF); gen.writeln(" 0 def"); // TODO always glyph index 0? // TODO ugly and temporary, until CID is implemented - for (Iterator iter = glyphs.iterator(); iter.hasNext();) { - String glyphName = (String) iter.next(); - gen.write("/"); - gen.write(glyphName); - gen.write(" "); - gen.write(getGlyphIndex(glyphName, cmaps)); - gen.writeln(" def"); + if (glyphs != null) { + for (Iterator iter = glyphs.iterator(); iter.hasNext();) { + String glyphName = (String) iter.next(); + gen.write("/"); + gen.write(glyphName); + gen.write(" "); + gen.write(getGlyphIndex(glyphName, cmaps)); + gen.writeln(" def"); + } } gen.writeln("end readonly def"); } @@ -379,9 +389,9 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { return 0; } - private static void embedType0Font(PSGenerator gen, MultiByteFont font, InputStream fontStream) + private static void composeType0Font(PSGenerator gen, MultiByteFont font, InputStream fontStream) throws IOException { - String psName = font.getFontName(); + String psName = font.getEmbedFontName(); gen.write("/"); gen.write(psName); gen.write(" /Identity-H [/"); @@ -391,7 +401,14 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { private static PSResource embedCIDFont(PSGenerator gen, MultiByteFont font, InputStream fontStream) throws IOException { - String psName = font.getFontName(); + FontFileReader reader = new FontFileReader(fontStream); + + TTFSubSetFile subset = new TTFSubSetFile(); + byte[] subsetFont = subset.readFont(reader, + font.getTTCName(), font.getUsedGlyphs()); + InputStream subsetInput = new java.io.ByteArrayInputStream(subsetFont); + + String psName = font.getEmbedFontName(); gen.write("%%BeginResource: CIDFont "); gen.writeln(psName); @@ -446,11 +463,11 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { lineCount = 1; } } - String gid = HexEncoder.encode(cidSubset.getGlyphIndexForSubsetIndex(cid), 4); + String gid = HexEncoder.encode(cid, 4); gen.write(gid); } gen.writeln(">] def"); - createType42DictionaryEntries(gen, font, fontStream, Collections.EMPTY_LIST); + createType42DictionaryEntries(gen, font, subsetInput, Collections.EMPTY_LIST); gen.writeln("CIDFontName currentdict end /CIDFont defineresource pop"); gen.writeln("end"); gen.writeln("%%EndResource"); @@ -525,7 +542,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { while (iter.hasNext()) { String key = (String)iter.next(); Typeface tf = getTypeFace(fontInfo, fonts, key); - PSResource fontRes = new PSResource("font", tf.getFontName()); + PSResource fontRes = new PSResource("font", tf.getEmbedFontName()); fontResources.put(key, fontRes); FontType fontType = tf.getFontType(); if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE @@ -535,7 +552,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { if (isEmbeddable(cf)) { if (fontType == FontType.TYPE0) { resTracker.registerSuppliedResource( - new PSResource(PSResource.TYPE_CIDFONT, tf.getFontName())); + new PSResource(PSResource.TYPE_CIDFONT, tf.getEmbedFontName())); resTracker.registerSuppliedResource( new PSResource(PSResource.TYPE_CMAP, "Identity-H")); } @@ -549,7 +566,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { PSResource.TYPE_ENCODING, encoding.getName()); resTracker.registerSuppliedResource(encodingRes); PSResource derivedFontRes = new PSResource( - PSResource.TYPE_FONT, tf.getFontName() + "_" + (i + 1)); + PSResource.TYPE_FONT, tf.getEmbedFontName() + "_" + (i + 1)); resTracker.registerSuppliedResource(derivedFontRes); } } @@ -629,7 +646,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 { - checkPostScriptVersion(gen, eventProducer); + checkPostScriptLevel3(gen, eventProducer); PSResource res = new PSResource(PSResource.TYPE_FONT, fontName); gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res); gen.commentln("%XGCDependencies: font " + baseFontName); |