You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by vh...@apache.org on 2010/06/29 17:46:41 UTC

svn commit: r959012 - in /xmlgraphics/fop/branches/Temp_TrueTypeInPostScript: lib/ src/java/org/apache/fop/fonts/ src/java/org/apache/fop/render/ps/ test/java/org/apache/fop/ test/java/org/apache/fop/render/ps/

Author: vhennebert
Date: Tue Jun 29 15:46:41 2010
New Revision: 959012

URL: http://svn.apache.org/viewvc?rev=959012&view=rev
Log:
Added support for CID-keyed TrueType fonts in PostScript output

Added:
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java   (with props)
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java   (with props)
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java   (with props)
Modified:
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/lib/xmlgraphics-commons-1.4svn.jar
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/fonts/CIDFontType.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/FontResourceCache.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.xml
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontUtils.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSPainter.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSTextPainter.java
    xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/UtilityCodeTestSuite.java

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/lib/xmlgraphics-commons-1.4svn.jar
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/lib/xmlgraphics-commons-1.4svn.jar?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
Binary files - no diff available.

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/fonts/CIDFontType.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/fonts/CIDFontType.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/fonts/CIDFontType.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/fonts/CIDFontType.java Tue Jun 29 15:46:41 2010
@@ -34,7 +34,7 @@ public class CIDFontType extends ValuedE
     /**
      * CID Font Type 2 (based on TrueType format)
      */
-    public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 1);
+    public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 2);
 
 
     /**

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/FontResourceCache.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/FontResourceCache.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/FontResourceCache.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/FontResourceCache.java Tue Jun 29 15:46:41 2010
@@ -42,19 +42,20 @@ class FontResourceCache {
     }
 
     /**
-     * Returns the PSResource for the given font key.
+     * Returns the PSFontResource for the given font key.
      * @param key the font key ("F*")
-     * @return the matching PSResource
+     * @return the matching PSFontResource instance
      */
-    public PSResource getPSResourceForFontKey(String key) {
-        PSResource res = null;
+    public PSFontResource getFontResourceForFontKey(String key) {
+        PSFontResource res = null;
         if (this.fontResources != null) {
-            res = (PSResource)this.fontResources.get(key);
+            res = (PSFontResource)this.fontResources.get(key);
         } else {
             this.fontResources = new java.util.HashMap();
         }
         if (res == null) {
-            res = new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key));
+            res = PSFontResource.createFontResource(
+                    new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key)));
             this.fontResources.put(key, res);
         }
         return res;

Added: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java?rev=959012&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java (added)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java Tue Jun 29 15:46:41 2010
@@ -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.render.ps;
+
+/**
+ * A helper class to hex-encoded representations of numbers.
+ */
+final class HexEncoder {
+
+    private HexEncoder() { }
+
+    /**
+     * Returns an hex encoding of the given number as a string of the given length,
+     * left-padded with zeros if necessary.
+     *
+     * @param n a number
+     * @param width required length of the string
+     * @return an hex-encoded representation of the number
+     */
+    static String encode(int n, int width) {
+        char[] digits = new char[width];
+        for (int i = width - 1; i >= 0; i--) {
+            int digit = n & 0xF;
+            digits[i] = (char) (digit < 10 ? '0' + digit : 'A' + digit - 10);
+            n >>= 4;
+        }
+        return new String(digits);
+    }
+
+    /**
+     * Returns an hex encoding of the given character as a four-character string.
+     *
+     * @param c a character
+     * @return an hex-encoded representation of the character
+     */
+    static String encode(char c) {
+        return encode(c, 4);
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/HexEncoder.java
------------------------------------------------------------------------------
    svn:keywords = Revision Id

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSDocumentHandler.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSDocumentHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSDocumentHandler.java Tue Jun 29 15:46:41 2010
@@ -200,7 +200,8 @@ public class PSDocumentHandler extends A
         gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
         PSRenderingUtil.writeSetupCodeList(gen, setupCodeList, "SetupCode");
         if (!psUtil.isOptimizeResources()) {
-            this.fontResources.addAll(PSFontUtils.writeFontDict(gen, fontInfo));
+            this.fontResources.addAll(PSFontUtils.writeFontDict(gen, fontInfo,
+                    PSEventProducer.Provider.get(getUserAgent().getEventBroadcaster())));
         } else {
             gen.commentln("%FOPFontSetup"); //Place-holder, will be replaced in the second pass
         }
@@ -538,8 +539,8 @@ public class PSDocumentHandler extends A
      * @param key the font key ("F*")
      * @return the matching PSResource
      */
-    protected PSResource getPSResourceForFontKey(String key) {
-        return this.fontResources.getPSResourceForFontKey(key);
+    protected PSFontResource getPSResourceForFontKey(String key) {
+        return this.fontResources.getFontResourceForFontKey(key);
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.java Tue Jun 29 15:46:41 2010
@@ -50,4 +50,11 @@ public interface PSEventProducer extends
      */
     void postscriptDictionaryParseError(Object source, String content, Exception e);
 
+    /**
+     * PostScript Level 3 features are being used.
+     *
+     * @param source the event source
+     * @event.severity WARN
+     */
+    void postscriptLevel3Used(Object source);
 }

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.xml?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.xml (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSEventProducer.xml Tue Jun 29 15:46:41 2010
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <catalogue xml:lang="en">
   <message key="postscriptDictionaryParseError">Failed to parse dictionary string. Reason: {e}, content = "{content}"</message>
+  <message key="postscriptLevel3Used">PostScript Level 3 features are needed to handle this document. Please make sure that your printer supports PostScript Level 3.</message>
 </catalogue>

Added: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java?rev=959012&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java (added)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java Tue Jun 29 15:46:41 2010
@@ -0,0 +1,77 @@
+/*
+ * 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.render.ps;
+
+import org.apache.xmlgraphics.ps.PSResource;
+import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
+
+/**
+ * A DSC resource corresponding to a font. This class handles the possible other resources
+ * that a font may depend on. For example, a CID-keyed font depends on a CIDFont resource, a
+ * CMap resource, and the ProcSet CIDInit resource.
+ */
+abstract class PSFontResource {
+
+    static PSFontResource createFontResource(final PSResource fontResource) {
+        return new PSFontResource() {
+
+            String getName() {
+                return fontResource.getName();
+            }
+
+            void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
+                resourceTracker.notifyResourceUsageOnPage(fontResource);
+            }
+        };
+    }
+
+    static PSFontResource createFontResource(final PSResource fontResource,
+            final PSResource procsetCIDInitResource, final PSResource cmapResource,
+            final PSResource cidFontResource) {
+        return new PSFontResource() {
+
+            String getName() {
+                return fontResource.getName();
+            }
+
+            void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
+                resourceTracker.notifyResourceUsageOnPage(fontResource);
+                resourceTracker.notifyResourceUsageOnPage(procsetCIDInitResource);
+                resourceTracker.notifyResourceUsageOnPage(cmapResource);
+                resourceTracker.notifyResourceUsageOnPage(cidFontResource);
+            }
+        };
+    }
+
+    /**
+     * Returns the name of the font resource.
+     *
+     * @return the name of the font
+     */
+    abstract String getName();
+
+    /**
+     * Notifies the given resource tracker of all the resources needed by this font.
+     *
+     * @param resourceTracker
+     */
+    abstract void notifyResourceUsageOnPage(ResourceTracker resourceTracker);
+
+}

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontResource.java
------------------------------------------------------------------------------
    svn:keywords = Revision Id

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontUtils.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontUtils.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSFontUtils.java Tue Jun 29 15:46:41 2010
@@ -23,6 +23,7 @@ import java.io.FileNotFoundException;
 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;
@@ -43,11 +44,13 @@ import org.apache.xmlgraphics.ps.dsc.Res
 import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream;
 
 import org.apache.fop.fonts.Base14Font;
+import org.apache.fop.fonts.CIDSubset;
 import org.apache.fop.fonts.CustomFont;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontType;
 import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.MultiByteFont;
 import org.apache.fop.fonts.SingleByteEncoding;
 import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
@@ -72,7 +75,12 @@ public class PSFontUtils extends org.apa
      */
     public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo)
                 throws IOException {
-        return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true);
+        return writeFontDict(gen, fontInfo, (PSEventProducer) null);
+    }
+
+    public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo,
+            PSEventProducer eventProducer) throws IOException {
+        return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true, eventProducer);
     }
 
     /**
@@ -87,7 +95,7 @@ public class PSFontUtils extends org.apa
      */
     public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts)
                 throws IOException {
-        return writeFontDict(gen, fontInfo, fonts, false);
+        return writeFontDict(gen, fontInfo, fonts, false, null);
     }
 
     /**
@@ -101,7 +109,7 @@ public class PSFontUtils extends org.apa
      * @throws IOException in case of an I/O problem
      */
     private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts,
-            boolean encodeAllCharacters) throws IOException {
+            boolean encodeAllCharacters, PSEventProducer eventProducer) throws IOException {
         gen.commentln("%FOPBeginFontDict");
 
         Map fontResources = new java.util.HashMap();
@@ -110,8 +118,8 @@ public class PSFontUtils extends org.apa
             String key = (String)iter.next();
             Typeface tf = getTypeFace(fontInfo, fonts, key);
             PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getFontName());
-            fontResources.put(key, fontRes);
-            embedFont(gen, tf, fontRes);
+            PSFontResource fontResource = embedFont(gen, tf, fontRes, eventProducer);
+            fontResources.put(key, fontResource);
 
             if (tf instanceof SingleByteFont) {
                 SingleByteFont sbf = (SingleByteFont)tf;
@@ -191,29 +199,45 @@ public class PSFontUtils extends org.apa
         return tf;
     }
 
-    /**
-     * Embeds a font in the PostScript file.
-     * @param gen the PostScript generator
-     * @param tf the font
-     * @param fontRes the PSResource associated with the font
-     * @throws IOException In case of an I/O error
-     */
-    public static void embedFont(PSGenerator gen, Typeface tf, PSResource fontRes)
-                throws IOException {
+    private static PSFontResource embedFont(PSGenerator gen, Typeface tf, PSResource fontRes,
+            PSEventProducer eventProducer) throws IOException {
         boolean embeddedFont = false;
         FontType fontType = tf.getFontType();
-        if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE) {
+        PSFontResource fontResource = null;
+        if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE
+                || fontType == FontType.TYPE0) {
             if (tf instanceof CustomFont) {
                 CustomFont cf = (CustomFont)tf;
                 if (isEmbeddable(cf)) {
                     InputStream in = getInputStreamOnFont(gen, cf);
                     if (in != null) {
+                        if (fontType == FontType.TYPE0) {
+                            if (gen.embedIdentityH()) {
+                                /*
+                                 * First CID-keyed font to be embedded; add
+                                 * %%IncludeResource: comment for ProcSet CIDInit.
+                                 */
+                                gen.includeProcsetCIDInitResource();
+                                if (eventProducer != null) {
+                                    eventProducer.postscriptLevel3Used(gen);
+                                }
+                            }
+                            PSResource cidFontResource = embedCIDFont(gen, (MultiByteFont) tf, in);
+                            fontResource = PSFontResource.createFontResource(fontRes,
+                                    gen.getProcsetCIDInitResource(),
+                                    gen.getIdentityHCMapResource(),
+                                    cidFontResource);
+                        }
                         gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE,
                                 fontRes);
                         if (fontType == FontType.TYPE1) {
                             embedType1Font(gen, in);
-                        } else {
+                            fontResource = PSFontResource.createFontResource(fontRes);
+                        } else if (fontType == FontType.TRUETYPE) {
                             embedTrueTypeFont(gen, (SingleByteFont) tf, in);
+                            fontResource = PSFontResource.createFontResource(fontRes);
+                        } else {
+                            embedType0Font(gen, (MultiByteFont) tf, in);
                         }
                         gen.writeDSCComment(DSCConstants.END_RESOURCE);
                         gen.getResourceTracker().registerSuppliedResource(fontRes);
@@ -229,6 +253,7 @@ public class PSFontUtils extends org.apa
         if (!embeddedFont) {
             gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
         }
+        return fontResource;
     }
 
     private static void embedTrueTypeFont(PSGenerator gen,
@@ -236,15 +261,25 @@ public class PSFontUtils extends org.apa
         /* 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());
+        gen.writeln("FontName currentdict end definefont pop");
+    }
+
+    private static void createType42DictionaryEntries(PSGenerator gen, CustomFont font,
+            InputStream fontStream, List cmaps) throws IOException {
         gen.write("/FontName /");
         gen.write(font.getFontName());
         gen.writeln(" def");
+        gen.writeln("/PaintType 0 def");
+        gen.writeln("/FontMatrix [1 0 0 1 0 0] def");
+        writeFontBBox(gen, font);
+        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(Integer.toString(i));
+            gen.write(i);
             gen.write(" /");
             String glyphName = Glyphs.charToGlyphName(Glyphs.WINANSI_ENCODING[i]);
             if (glyphName.equals("")) {
@@ -256,16 +291,6 @@ public class PSFontUtils extends org.apa
             gen.writeln(" put");
         }
         gen.writeln("readonly def");
-        gen.writeln("/PaintType 0 def");
-        gen.writeln("/FontMatrix [1 0 0 1 0 0] def");
-        int[] bbox = font.getFontBBox();
-        gen.write("/FontBBox[");
-        for (int i = 0; i < 4; i++) {
-            gen.write(" ");
-            gen.write(Integer.toString(bbox[i]));
-        }
-        gen.writeln(" ] def");
-        gen.writeln("/FontType 42 def");
         gen.write("/sfnts[");
         /*
          * Store the font file in an array of hex-encoded strings. Strings are limited to
@@ -289,23 +314,21 @@ public class PSFontUtils extends org.apa
         }
         gen.writeln("]def");
         gen.write("/CharStrings ");
-        gen.write(Integer.toString(glyphs.size() + 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
-        List cmaps = font.getCMaps();
         for (Iterator iter = glyphs.iterator(); iter.hasNext();) {
             String glyphName = (String) iter.next();
             gen.write("/");
             gen.write(glyphName);
             gen.write(" ");
-            gen.write(Integer.toString(getGlyphIndex(glyphName, cmaps)));
+            gen.write(getGlyphIndex(glyphName, cmaps));
             gen.writeln(" def");
         }
         gen.writeln("end readonly def");
-        gen.writeln("FontName currentdict end definefont pop");
     }
 
     private static int getGlyphIndex(String glyphName, List cmaps) {
@@ -319,6 +342,96 @@ public class PSFontUtils extends org.apa
         return 0;
     }
 
+    private static void embedType0Font(PSGenerator gen, MultiByteFont font, InputStream fontStream)
+            throws IOException {
+        String psName = font.getFontName();
+        gen.write("/");
+        gen.write(psName);
+        gen.write(" /Identity-H [/");
+        gen.write(psName);
+        gen.writeln("] composefont pop");
+    }
+
+    private static PSResource embedCIDFont(PSGenerator gen,
+            MultiByteFont font, InputStream fontStream) throws IOException {
+        String psName = font.getFontName();
+        gen.write("%%BeginResource: CIDFont ");
+        gen.writeln(psName);
+
+        gen.write("%%Title: (");
+        gen.write(psName);
+        gen.writeln(" Adobe Identity 0)");
+
+        gen.writeln("%%Version: 1"); // TODO use font revision?
+        gen.writeln("/CIDInit /ProcSet findresource begin");
+        gen.writeln("20 dict begin");
+
+        gen.write("/CIDFontName /");
+        gen.write(psName);
+        gen.writeln(" def");
+
+        gen.writeln("/CIDFontVersion 1 def"); // TODO same as %%Version above
+
+        gen.write("/CIDFontType ");
+        gen.write(font.getCIDType().getValue());
+        gen.writeln(" def");
+
+        gen.writeln("/CIDSystemInfo 3 dict dup begin");
+        gen.writeln("  /Registry (Adobe) def");
+        gen.writeln("  /Ordering (Identity) def");
+        gen.writeln("  /Supplement 0 def");
+        gen.writeln("end def");
+
+        // TODO UIDBase (and UIDOffset in CMap) necessary if PostScript Level 1 & 2
+        // interpreters are to be supported
+        // (Level 1: with composite font extensions; Level 2: those that do not offer
+        // native mode support for CID-keyed fonts)
+
+        // TODO XUID (optional but strongly recommended)
+
+        // TODO /FontInfo
+
+        gen.write("/CIDCount ");
+        CIDSubset cidSubset = font.getCIDSubset();
+        int subsetSize = cidSubset.getSubsetSize();
+        gen.write(subsetSize);
+        gen.writeln(" def");
+        gen.writeln("/GDBytes 2 def"); // TODO always 2?
+        gen.writeln("/CIDMap [<");
+        int colCount = 0;
+        int lineCount = 1;
+        for (int cid = 0; cid < subsetSize; cid++) {
+            if (colCount++ == 20) {
+                gen.newLine();
+                colCount = 1;
+                if (lineCount++ == 800) {
+                    gen.writeln("> <");
+                    lineCount = 1;
+                }
+            }
+            String gid = HexEncoder.encode(cidSubset.getGlyphIndexForSubsetIndex(cid), 4);
+            gen.write(gid);
+        }
+        gen.writeln(">] def");
+        createType42DictionaryEntries(gen, font, fontStream, Collections.EMPTY_LIST);
+        gen.writeln("CIDFontName currentdict end /CIDFont defineresource pop");
+        gen.writeln("end");
+        gen.writeln("%%EndResource");
+        PSResource cidFontResource = new PSResource(PSResource.TYPE_CIDFONT, psName);
+        gen.getResourceTracker().registerSuppliedResource(cidFontResource);
+        return cidFontResource;
+    }
+
+    private static void writeFontBBox(PSGenerator gen, CustomFont font) throws IOException {
+        int[] bbox = font.getFontBBox();
+        gen.write("/FontBBox[");
+        for (int i = 0; i < 4; i++) {
+            gen.write(" ");
+            gen.write(bbox[i]);
+        }
+        gen.writeln(" ] def");
+    }
+
     private static boolean isEmbeddable(CustomFont font) {
         return font.isEmbeddable();
     }

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSPainter.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSPainter.java Tue Jun 29 15:46:41 2010
@@ -44,6 +44,7 @@ import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.MultiByteFont;
 import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.render.RenderingContext;
@@ -379,7 +380,7 @@ public class PSPainter extends AbstractI
                     if (currentEncoding != encoding) {
                         if (i > 0) {
                             writeText(text, start, i - start,
-                                    letterSpacing, wordSpacing, dx, font, tf);
+                                    letterSpacing, wordSpacing, dx, font, tf, false);
                         }
                         if (encoding == 0) {
                             useFont(fontKey, sizeMillipoints);
@@ -391,12 +392,11 @@ public class PSPainter extends AbstractI
                     }
                 }
                 writeText(text, start, textLen - start,
-                        letterSpacing, wordSpacing, dx, font, tf);
+                        letterSpacing, wordSpacing, dx, font, tf, false);
             } else {
-                //Simple single-font painting
                 useFont(fontKey, sizeMillipoints);
                 writeText(text, 0, textLen,
-                        letterSpacing, wordSpacing, dx, font, tf);
+                        letterSpacing, wordSpacing, dx, font, tf, tf instanceof MultiByteFont);
             }
         } catch (IOException ioe) {
             throw new IFException("I/O error in drawText()", ioe);
@@ -405,7 +405,7 @@ public class PSPainter extends AbstractI
 
     private void writeText(String text, int start, int len,
             int letterSpacing, int wordSpacing, int[] dx,
-            Font font, Typeface tf) throws IOException {
+            Font font, Typeface tf, boolean multiByte) throws IOException {
         PSGenerator generator = getGenerator();
         int end = start + len;
         int initialSize = len;
@@ -414,6 +414,16 @@ public class PSPainter extends AbstractI
         boolean hasLetterSpacing = (letterSpacing != 0);
         boolean needTJ = false;
 
+        char strOpen;
+        char strClose;
+        if (multiByte) {
+            strOpen = '<';
+            strClose = '>';
+        } else {
+            strOpen = '(';
+            strClose = ')';
+        }
+
         int lineStart = 0;
         StringBuffer accText = new StringBuffer(initialSize);
         StringBuffer sb = new StringBuffer(initialSize);
@@ -439,8 +449,12 @@ public class PSPainter extends AbstractI
             if (dx != null && i < dxl - 1) {
                 glyphAdjust -= dx[i + 1];
             }
-            char codepoint = (char)(ch % 256);
-            PSGenerator.escapeChar(codepoint, accText); //add character to accumulated text
+            if (multiByte) {
+                accText.append(HexEncoder.encode(ch));
+            } else {
+                char codepoint = (char)(ch % 256);
+                PSGenerator.escapeChar(codepoint, accText); //add character to accumulated text
+            }
             if (glyphAdjust != 0) {
                 needTJ = true;
                 if (sb.length() == 0) {
@@ -451,9 +465,10 @@ public class PSPainter extends AbstractI
                         sb.append(PSGenerator.LF);
                         lineStart = sb.length();
                     }
-                    sb.append('(');
+                    sb.append(strOpen);
                     sb.append(accText);
-                    sb.append(") ");
+                    sb.append(strClose);
+                    sb.append(' ');
                     accText.setLength(0); //reset accumulated text
                 }
                 sb.append(Integer.toString(glyphAdjust)).append(' ');
@@ -461,9 +476,9 @@ public class PSPainter extends AbstractI
         }
         if (needTJ) {
             if (accText.length() > 0) {
-                sb.append('(');
+                sb.append(strOpen);
                 sb.append(accText);
-                sb.append(')');
+                sb.append(strClose);
             }
             if (hasLetterSpacing) {
                 sb.append("] " + formatMptAsPt(generator, letterSpacing) + " ATJ");
@@ -471,7 +486,7 @@ public class PSPainter extends AbstractI
                 sb.append("] TJ");
             }
         } else {
-            sb.append('(').append(accText).append(")");
+            sb.append(strOpen).append(accText).append(strClose);
             if (hasLetterSpacing) {
                 StringBuffer spb = new StringBuffer();
                 spb.append(formatMptAsPt(generator, letterSpacing))
@@ -486,10 +501,10 @@ public class PSPainter extends AbstractI
     }
 
     private void useFont(String key, int size) throws IOException {
-        PSResource res = this.documentHandler.getPSResourceForFontKey(key);
+        PSFontResource res = this.documentHandler.getPSResourceForFontKey(key);
         PSGenerator generator = getGenerator();
         generator.useFont("/" + res.getName(), size / 1000f);
-        generator.getResourceTracker().notifyResourceUsageOnPage(res);
+        res.notifyResourceUsageOnPage(generator.getResourceTracker());
     }
 
 

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSTextPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSTextPainter.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSTextPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/render/ps/PSTextPainter.java Tue Jun 29 15:46:41 2010
@@ -35,13 +35,13 @@ import java.text.AttributedCharacterIter
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.batik.gvt.TextNode;
 import org.apache.batik.gvt.font.GVTGlyphVector;
 import org.apache.batik.gvt.text.TextPaintInfo;
 import org.apache.batik.gvt.text.TextSpanLayout;
 
 import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
 import org.apache.xmlgraphics.ps.PSGenerator;
-import org.apache.xmlgraphics.ps.PSResource;
 
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
@@ -240,9 +240,9 @@ public class PSTextPainter extends Nativ
         }
     }
 
-    private PSResource getResourceForFont(Font f, String postfix) {
+    private PSFontResource getResourceForFont(Font f, String postfix) {
         String key = (postfix != null ? f.getFontName() + '_' + postfix : f.getFontName());
-        return this.fontResources.getPSResourceForFontKey(key);
+        return this.fontResources.getFontResourceForFontKey(key);
     }
 
     private void clip(PSGraphics2D ps, Shape shape) throws IOException {
@@ -299,9 +299,9 @@ public class PSTextPainter extends Nativ
         public void selectFont(Font f, char mapped) throws IOException {
             int encoding = mapped / 256;
             String postfix = (encoding == 0 ? null : Integer.toString(encoding));
-            PSResource res = getResourceForFont(f, postfix);
+            PSFontResource res = getResourceForFont(f, postfix);
             gen.useFont("/" + res.getName(), f.getFontSize() / 1000f);
-            gen.getResourceTracker().notifyResourceUsageOnPage(res);
+            res.notifyResourceUsageOnPage(gen.getResourceTracker());
         }
 
         public Font getCurrentFont() {

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/UtilityCodeTestSuite.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/UtilityCodeTestSuite.java?rev=959012&r1=959011&r2=959012&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/UtilityCodeTestSuite.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/UtilityCodeTestSuite.java Tue Jun 29 15:46:41 2010
@@ -24,6 +24,7 @@ import junit.framework.TestSuite;
 
 import org.apache.fop.events.BasicEventTestCase;
 import org.apache.fop.pdf.PDFObjectTestCase;
+import org.apache.fop.render.ps.HexEncoderTestCase;
 import org.apache.fop.traits.BorderPropsTestCase;
 import org.apache.fop.util.ColorUtilTestCase;
 import org.apache.fop.util.ElementListUtilsTestCase;
@@ -51,6 +52,7 @@ public class UtilityCodeTestSuite {
         suite.addTest(new TestSuite(BasicEventTestCase.class));
         suite.addTest(new TestSuite(XMLResourceBundleTestCase.class));
         suite.addTest(new TestSuite(URIResolutionTestCase.class));
+        suite.addTest(new TestSuite(HexEncoderTestCase.class));
         //$JUnit-END$
         return suite;
     }

Added: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java?rev=959012&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java (added)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java Tue Jun 29 15:46:41 2010
@@ -0,0 +1,58 @@
+/*
+ * 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.render.ps;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for the conversion of characters into hex-encoded strings.
+ */
+public class HexEncoderTestCase extends TestCase {
+
+    private static char successor(char d) {
+        if (d == '9') {
+            return 'A';
+        } else if (d == 'F') {
+            return '0';
+        } else {
+            return (char) (d + 1);
+        }
+    }
+
+    private static void increment(char[] digits) {
+        int d = 4;
+        do {
+            d--;
+            digits[d] = successor(digits[d]);
+        } while (digits[d] == '0' && d > 0);
+    }
+
+    /**
+     * Tests that characters are properly encoded into hex strings.
+     */
+    public void testEncodeChar() {
+        char[] digits = new char[] {'0', '0', '0', '0'};
+        for (int c = 0; c <= 0xFFFF; c++) {
+            assertEquals(new String(digits), HexEncoder.encode((char) c));
+            increment(digits);
+        }
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/test/java/org/apache/fop/render/ps/HexEncoderTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Revision Id



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org