pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jahew...@apache.org
Subject svn commit: r1645068 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: cos/ pdmodel/edit/ pdmodel/font/
Date Fri, 12 Dec 2014 20:54:41 GMT
Author: jahewson
Date: Fri Dec 12 20:54:40 2014
New Revision: 1645068

URL: http://svn.apache.org/r1645068
Log:
PDFBOX-922: Encode content stream text using PDFont

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java Fri Dec 12 20:54:40
2014
@@ -118,6 +118,8 @@ public final class COSName extends COSBa
     public static final COSName CIDSYSTEMINFO = new COSName("CIDSystemInfo");
     public static final COSName CLR_F = new COSName("ClrF");
     public static final COSName CLR_FF = new COSName("ClrFf");
+    public static final COSName CMAP = new COSName("CMap");
+    public static final COSName CMAPNAME = new COSName("CMapName");
     public static final COSName CMYK = new COSName("CMYK");
     public static final COSName COLOR_BURN = new COSName("ColorBurn");
     public static final COSName COLOR_DODGE = new COSName("ColorDodge");

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java
(original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java
Fri Dec 12 20:54:40 2014
@@ -23,12 +23,12 @@ import java.awt.geom.PathIterator;
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.nio.charset.Charset;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 
+import java.util.Stack;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.pdfbox.cos.COSArray;
@@ -60,7 +60,6 @@ import org.apache.pdfbox.util.Charsets;
  * are finished with this object.
  *
  * @author Ben Litchfield
- * 
  */
 public class PDPageContentStream implements Closeable
 {
@@ -77,6 +76,8 @@ public class PDPageContentStream impleme
     private static final byte[] MOVE_TEXT_POSITION = toAscii("Td\n");
     private static final byte[] SET_TEXT_MATRIX = toAscii("Tm\n");
     private static final byte[] SHOW_TEXT = toAscii("Tj\n");
+    private static final byte[] SET_LEADING = toAscii("TL\n");
+    private static final byte[] NEW_LINE = toAscii("T*\n");
 
     private static final byte[] SAVE_GRAPHICS_STATE = toAscii("q\n");
     private static final byte[] RESTORE_GRAPHICS_STATE = toAscii("Q\n");
@@ -129,6 +130,7 @@ public class PDPageContentStream impleme
     private OutputStream output;
     private PDResources resources;
     private boolean inTextMode = false;
+    private final Stack<PDFont> fontStack = new Stack<PDFont>();
 
     private PDColorSpace currentStrokingColorSpace = PDDeviceGray.INSTANCE;
     private PDColorSpace currentNonStrokingColorSpace = PDDeviceGray.INSTANCE;
@@ -310,6 +312,15 @@ public class PDPageContentStream impleme
      */
     public void setFont(PDFont font, float fontSize) throws IOException
     {
+        if (fontStack.isEmpty())
+        {
+            fontStack.add(font);
+        }
+        else
+        {
+            fontStack.setElementAt(font, fontStack.size() - 1);
+        }
+
         appendCOSName(resources.add(font));
         appendRawCommands(SPACE);
         appendRawCommands(fontSize);
@@ -619,14 +630,48 @@ public class PDPageContentStream impleme
     {
         if (!inTextMode)
         {
-            throw new IOException("Error: must call beginText() before drawString");
+            throw new IllegalStateException("Must call beginText() before drawString()");
+        }
+
+        if (fontStack.isEmpty())
+        {
+            throw new IllegalStateException("Must call setFont() before drawString()");
         }
-        COSWriter.writeString(text.getBytes(Charset.forName("ISO-8859-1")), output); // todo:
use font's encoding
+
+        PDFont font = fontStack.peek();
+        COSWriter.writeString(font.encode(text), output);
         appendRawCommands(SPACE);
         appendRawCommands(SHOW_TEXT);
     }
 
     /**
+     * Sets the text leading.
+     *
+     * @param leading The leading in unscaled text units.
+     * @throws IOException If there is an error writing to the stream.
+     */
+    public void setLeading(double leading) throws IOException
+    {
+        appendRawCommands(leading);
+        appendRawCommands(SPACE);
+        appendRawCommands(SET_LEADING);
+    }
+
+    /**
+     * Move to the start of the next line of text. Requires the leading to have been set.
+     *
+     * @throws IOException If there is an error writing to the stream.
+     */
+    public void newLine() throws IOException
+    {
+        if (!inTextMode)
+        {
+            throw new IllegalStateException("Must call beginText() before newLine()");
+        }
+        appendRawCommands(NEW_LINE);
+    }
+
+    /**
      * Set the stroking color space.  This will add the colorspace to the PDResources
      * if necessary.
      *
@@ -1467,6 +1512,7 @@ public class PDPageContentStream impleme
      */
     public void saveGraphicsState() throws IOException
     {
+        fontStack.push(fontStack.peek());
         appendRawCommands(SAVE_GRAPHICS_STATE);
     }
 
@@ -1476,6 +1522,7 @@ public class PDPageContentStream impleme
      */
     public void restoreGraphicsState() throws IOException
     {
+        fontStack.pop();
         appendRawCommands(RESTORE_GRAPHICS_STATE);
     }
 
@@ -1487,7 +1534,7 @@ public class PDPageContentStream impleme
      */
     public void appendRawCommands(String commands) throws IOException
     {
-        appendRawCommands(commands.getBytes("ISO-8859-1"));
+        appendRawCommands(commands.getBytes(Charsets.US_ASCII));
     }
 
     /**

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java Fri Dec
12 20:54:40 2014
@@ -34,7 +34,7 @@ import org.apache.pdfbox.util.Vector;
  * A CIDFont. A CIDFont is a PDF object that contains information about a CIDFont program.
Although
  * its Type value is Font, a CIDFont is not actually a font.
  *
- * <p>It is not usually necessary to use this class directly, prefer
+ * <p>It is not usually necessary to use this class directly, prefer {@link PDType0Font}.
  *
  * @author Ben Litchfield
  */
@@ -389,4 +389,16 @@ public abstract class PDCIDFont implemen
      * @return GID
      */
     public abstract int codeToGID(int code) throws IOException;
+
+    /**
+     * Encodes the given Unicode code point for use in a PDF content stream.
+     * Content streams use a multi-byte encoding with 1 to 4 bytes.
+     *
+     * <p>This method is called when embedding text in PDFs and when filling in fields.
+     *
+     * @param unicode Unicode code point.
+     * @return Array of 1 to 4 PDF content stream bytes.
+     * @throws IOException If the text could not be encoded.
+     */
+    protected abstract byte[] encode(int unicode) throws IOException;
 }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java Fri
Dec 12 20:54:40 2014
@@ -258,6 +258,14 @@ public class PDCIDFontType0 extends PDCI
     }
 
     @Override
+    public byte[] encode(int unicode)
+    {
+        // todo: we can use a known character collection CMap for a CIDFont
+        //       and an Encoding for Type 1-equivalent
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public float getWidthFromFont(int code) throws IOException
     {
         int cid = codeToCID(code);

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java Fri
Dec 12 20:54:40 2014
@@ -19,6 +19,8 @@ package org.apache.pdfbox.pdmodel.font;
 import java.io.IOException;
 import java.io.InputStream;
 
+import java.util.HashMap;
+import java.util.Map;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fontbox.cmap.CMap;
@@ -50,9 +52,11 @@ public class PDCIDFontType2 extends PDCI
 
     private final TrueTypeFont ttf;
     private final int[] cid2gid;
+    private final Map<Integer, Integer> gid2cid;
     private final boolean hasIdentityCid2Gid;
     private final boolean isEmbedded;
     private final boolean isDamaged;
+    private final CmapSubtable cmap;
     private Matrix fontMatrix;
 
     /**
@@ -141,8 +145,10 @@ public class PDCIDFontType2 extends PDCI
             }
         }
         ttf = ttfFont;
+        cmap = getUnicodeCmap(ttf.getCmap());
 
         cid2gid = readCIDToGIDMap();
+        gid2cid = invert(cid2gid);
         COSBase map = dict.getDictionaryObject(COSName.CID_TO_GID_MAP);
         hasIdentityCid2Gid = map instanceof COSName && ((COSName) map).getName().equals("Identity");
     }
@@ -164,36 +170,44 @@ public class PDCIDFontType2 extends PDCI
         return ttf.getFontBBox();
     }
 
-    private int[] readCIDToGIDMap()
+    private int[] readCIDToGIDMap() throws IOException
     {
         int[] cid2gid = null;
         COSBase map = dict.getDictionaryObject(COSName.CID_TO_GID_MAP);
         if (map instanceof COSStream)
         {
             COSStream stream = (COSStream) map;
-            try
-            {
-                InputStream is = stream.getUnfilteredStream();
-                byte[] mapAsBytes = IOUtils.toByteArray(is);
-                IOUtils.closeQuietly(is);
-                int numberOfInts = mapAsBytes.length / 2;
-                cid2gid = new int[numberOfInts];
-                int offset = 0;
-                for (int index = 0; index < numberOfInts; index++)
-                {
-                    int gid = (mapAsBytes[offset] & 0xff) << 8 | mapAsBytes[offset
+ 1] & 0xff;
-                    cid2gid[index] = gid;
-                    offset += 2;
-                }
-            }
-            catch (IOException exception)
-            {
-                LOG.error("Can't read the CIDToGIDMap", exception);
+
+            InputStream is = stream.getUnfilteredStream();
+            byte[] mapAsBytes = IOUtils.toByteArray(is);
+            IOUtils.closeQuietly(is);
+            int numberOfInts = mapAsBytes.length / 2;
+            cid2gid = new int[numberOfInts];
+            int offset = 0;
+            for (int index = 0; index < numberOfInts; index++)
+            {
+                int gid = (mapAsBytes[offset] & 0xff) << 8 | mapAsBytes[offset
+ 1] & 0xff;
+                cid2gid[index] = gid;
+                offset += 2;
             }
         }
         return cid2gid;
     }
 
+    private Map<Integer, Integer> invert(int[] cid2gid)
+    {
+        if (cid2gid == null)
+        {
+            return null;
+        }
+        Map<Integer, Integer> inverse = new HashMap<Integer, Integer>();
+        for (int i = 0; i < cid2gid.length; i++)
+        {
+            inverse.put(cid2gid[i], i);
+        }
+        return inverse;
+    }
+
     @Override
     public int codeToCID(int code)
     {
@@ -223,7 +237,6 @@ public class PDCIDFontType2 extends PDCI
             // font's 'cmap' table. The means by which this is accomplished are implementation-
             // dependent.
 
-            CmapSubtable cmap = getUnicodeCmap(ttf.getCmap());
             String unicode;
 
             if (cid2gid != null || hasIdentityCid2Gid)
@@ -371,6 +384,32 @@ public class PDCIDFontType2 extends PDCI
     }
 
     @Override
+    public byte[] encode(int unicode)
+    {
+        int gid = cmap.getGlyphId(unicode);
+
+        if (gid == 0)
+        {
+            throw new IllegalArgumentException(
+                    String.format("No glyph for U+%04X in font %s", unicode, getName()));
+        }
+
+        // inverted CIDToGIDMap
+        int cid;
+        if (cid2gid != null)
+        {
+            cid = gid2cid.get(gid);
+        }
+        else
+        {
+            cid = gid;
+        }
+
+        // CID is always 2-bytes (16-bit) for TrueType
+        return new byte[] { (byte)(cid >> 8 & 0xff), (byte)(cid & 0xff) };
+    }
+
+    @Override
     public boolean isEmbedded()
     {
         return isEmbedded;

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java Fri Dec 12
20:54:40 2014
@@ -16,6 +16,7 @@
  */
 package org.apache.pdfbox.pdmodel.font;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
@@ -251,6 +252,41 @@ public abstract class PDFont implements
     public abstract float getHeight(int code) throws IOException;
 
     /**
+     * Encodes the given string for use in a PDF content stream.
+     *
+     * @param text Any Unicode text.
+     * @return Array of PDF content stream bytes.
+     * @throws IOException If the text could not be encoded.
+     */
+    public final byte[] encode(String text) throws IOException
+    {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        for (int offset = 0; offset < text.length(); )
+        {
+            int codePoint = text.codePointAt(offset);
+
+            // multi-byte encoding with 1 to 4 bytes
+            byte[] bytes = encode(codePoint);
+            out.write(bytes);
+
+            offset += Character.charCount(codePoint);
+        }
+        return out.toByteArray();
+    }
+
+    /**
+     * Encodes the given Unicode code point for use in a PDF content stream.
+     * Content streams use a multi-byte encoding with 1 to 4 bytes.
+     *
+     * <p>This method is called when embedding text in PDFs and when filling in fields.
+     *
+     * @param unicode Unicode code point.
+     * @return Array of 1 to 4 PDF content stream bytes.
+     * @throws IOException If the text could not be encoded.
+     */
+    protected abstract byte[] encode(int unicode) throws IOException;
+
+    /**
      * Returns the width of the given Unicode string.
      *
      * @param text The text to get the width of.

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java Fri
Dec 12 20:54:40 2014
@@ -59,6 +59,18 @@ public abstract class PDSimpleFont exten
     PDSimpleFont(String baseFont)
     {
         super(baseFont);
+
+        this.encoding = WinAnsiEncoding.INSTANCE;
+
+        // assign the glyph list based on the font
+        if ("ZapfDingbats".equals(baseFont))
+        {
+            glyphList = GlyphList.getZapfDingbats();
+        }
+        else
+        {
+            glyphList = GlyphList.getAdobeGlyphList();
+        }
     }
 
     /**

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java Fri
Dec 12 20:54:40 2014
@@ -247,6 +247,24 @@ public class PDTrueTypeFont extends PDSi
     }
 
     @Override
+    protected byte[] encode(int unicode) throws IOException
+    {
+        if (unicode > 0xff)
+        {
+            throw new IllegalArgumentException("This font type only supports 8-bit code points");
+        }
+
+        int gid = codeToGID(unicode);
+        if (gid == 0)
+        {
+            throw new IllegalArgumentException(
+                    String.format("No glyph for U+%04X in font %s", unicode, getName()));
+        }
+
+        return new byte[] { (byte)unicode };
+    }
+
+    @Override
     public boolean isEmbedded()
     {
         return isEmbedded;

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java Fri
Dec 12 20:54:40 2014
@@ -201,6 +201,12 @@ public class PDType0Font extends PDFont
     }
 
     @Override
+    protected byte[] encode(int unicode) throws IOException
+    {
+        return descendantFont.encode(unicode);
+    }
+
+    @Override
     public float getAverageFontWidth()
     {
         return descendantFont.getAverageFontWidth();

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java Fri
Dec 12 20:54:40 2014
@@ -244,6 +244,12 @@ public class PDType1CFont extends PDSimp
     }
 
     @Override
+    protected byte[] encode(int unicode) throws IOException
+    {
+        throw new UnsupportedOperationException("Not implemented: Type1C");
+    }
+
+    @Override
     public float getStringWidth(String string) throws IOException
     {
         float width = 0;

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java Fri
Dec 12 20:54:40 2014
@@ -34,6 +34,7 @@ import org.apache.pdfbox.cos.COSDictiona
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.pdmodel.font.encoding.Encoding;
+import org.apache.pdfbox.pdmodel.font.encoding.MacOSRomanEncoding;
 import org.apache.pdfbox.pdmodel.font.encoding.StandardEncoding;
 import org.apache.pdfbox.pdmodel.font.encoding.Type1Encoding;
 import org.apache.pdfbox.pdmodel.font.encoding.WinAnsiEncoding;
@@ -87,6 +88,8 @@ public class PDType1Font extends PDSimpl
     private final boolean isDamaged;
     private Matrix fontMatrix;
 
+    private Map<String, Integer> invertedEncoding; // for writing
+
     /**
      * Creates a Type 1 standard 14 font for embedding.
      *
@@ -274,6 +277,49 @@ public class PDType1Font extends PDSimpl
     }
 
     @Override
+    protected byte[] encode(int unicode) throws IOException
+    {
+        if (unicode > 0xff)
+        {
+            throw new IllegalArgumentException("This font type only supports 8-bit code points");
+        }
+
+        String name = getGlyphList().codePointToName(unicode);
+        Map<String, Integer> inverted = getInvertedEncoding();
+
+        if (name.equals(".notdef"))
+        {
+            throw new IllegalArgumentException(
+                    String.format("No glyph for U+%04X in font %s", unicode, getName()));
+        }
+
+        int code = inverted.get(name);
+        return new byte[] { (byte)code };
+    }
+
+    /**
+     * Inverts the font's Encoding. Any duplicate (Name -> Code) mappings will be lost.
+     */
+    private Map<String, Integer> getInvertedEncoding()
+    {
+        if (invertedEncoding != null)
+        {
+            return invertedEncoding;
+        }
+
+        invertedEncoding = new HashMap<String, Integer>();
+        Map<Integer, String> codeToName = MacOSRomanEncoding.INSTANCE.getCodeToNameMap();
+        for (Map.Entry<Integer, String> entry : codeToName.entrySet())
+        {
+            if (!invertedEncoding.containsKey(entry.getValue()))
+            {
+                invertedEncoding.put(entry.getValue(), entry.getKey());
+            }
+        }
+        return invertedEncoding;
+    }
+
+    @Override
     public float getWidthFromFont(int code) throws IOException
     {
         String name = codeToName(code);

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java?rev=1645068&r1=1645067&r2=1645068&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java Fri
Dec 12 20:54:40 2014
@@ -155,6 +155,12 @@ public class PDType3Font extends PDSimpl
     }
 
     @Override
+    protected byte[] encode(int unicode) throws IOException
+    {
+        throw new UnsupportedOperationException("Not implemented: Type3");
+    }
+
+    @Override
     public int readCode(InputStream in) throws IOException
     {
         return in.read();



Mime
View raw message