Author: rmeyer
Date: Mon Aug 10 14:15:48 2015
New Revision: 1695082

URL: http://svn.apache.org/r1695082
Log:
FOP-2486: Soft font support for TrueType fonts in PCL

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/fonts/
      - copied from r1695067, 
xmlgraphics/fop/branches/Temp_PCLSoftFonts/src/java/org/apache/fop/render/pcl/fonts/
    xmlgraphics/fop/trunk/test/java/org/apache/fop/render/pcl/fonts/
      - copied from r1695067, 
xmlgraphics/fop/branches/Temp_PCLSoftFonts/test/java/org/apache/fop/render/pcl/fonts/
Modified:
    xmlgraphics/fop/trunk/   (props changed)
    xmlgraphics/fop/trunk/findbugs-exclude.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDFull.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSet.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSubset.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/HardcodedFonts.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLPainter.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java

Propchange: xmlgraphics/fop/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Aug 10 14:15:48 2015
@@ -5,6 +5,7 @@
 /xmlgraphics/fop/branches/Temp_FopFontsForSVG:1508203-1564000
 /xmlgraphics/fop/branches/Temp_ImproveAccessibility:1187234-1242827
 /xmlgraphics/fop/branches/Temp_InlineContainer:1534142-1562399
+/xmlgraphics/fop/branches/Temp_PCLSoftFonts:1685105-1695067
 /xmlgraphics/fop/branches/Temp_PDF_ObjectStreams:1303414-1305418
 /xmlgraphics/fop/branches/Temp_RoundedCorners:1003017-1401566
 /xmlgraphics/fop/branches/Temp_TrueTypeInPostScript:949179-1352964

Modified: xmlgraphics/fop/trunk/findbugs-exclude.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/findbugs-exclude.xml?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/findbugs-exclude.xml (original)
+++ xmlgraphics/fop/trunk/findbugs-exclude.xml Mon Aug 10 14:15:48 2015
@@ -238,6 +238,10 @@
        <Bug pattern="OS_OPEN_STREAM_EXCEPTION_PATH"/>
      </Or>
    </Match> 
+  <Match>
+    <Class name="org.apache.fop.render.pcl.fonts.truetype.PCLTTFTable"/>
+    <Bug pattern="ICAST_INTEGER_MULTIPLY_CAST_TO_LONG"/>
+  </Match>
   <!-- END - APPROVED EXCLUSIONS -->
 
   <!-- START - TEMPORARY (UNAPPROVED) EXCLUSIONS -->

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDFull.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDFull.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDFull.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDFull.java Mon Aug 10 
14:15:48 2015
@@ -57,6 +57,18 @@ public class CIDFull implements CIDSet {
     }
 
     /** {@inheritDoc} */
+    @Override
+    public char getUnicodeFromGID(int glyphIndex) {
+        return ' ';
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getGIDFromChar(char ch) {
+        return ch;
+    }
+
+    /** {@inheritDoc} */
     public char getUnicode(int index) {
         initGlyphIndices();
         if (glyphIndices.get(index)) {
@@ -109,5 +121,4 @@ public class CIDFull implements CIDSet {
     public int[] getWidths() {
         return font.getWidths();
     }
-
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSet.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSet.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSet.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSet.java Mon Aug 10 
14:15:48 2015
@@ -44,6 +44,20 @@ public interface CIDSet {
     char getUnicode(int index);
 
     /**
+     * Gets the unicode character from the original font glyph index
+     * @param glyphIndex The original glyph index of the character in the font
+     * @return The character represented by the passed GID
+     */
+    char getUnicodeFromGID(int glyphIndex);
+
+    /**
+     * Returns the glyph index from the original font from a character
+     * @param ch The character
+     * @return The glyph index in the original font.
+     */
+    int getGIDFromChar(char ch);
+
+    /**
      * Maps a character to a character selector for a font subset. If the 
character isn't in the
      * subset, yet, it is added and a new character selector returned. 
Otherwise, the already
      * allocated character selector is returned from the existing map/subset.

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSubset.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSubset.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSubset.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CIDSubset.java Mon Aug 
10 14:15:48 2015
@@ -53,6 +53,12 @@ public class CIDSubset implements CIDSet
      */
     private Map<Integer, Character> usedCharsIndex = new HashMap<Integer, 
Character>();
 
+    /**
+     * A map between the original character and it's GID in the original font.
+     */
+    private Map<Character, Integer> charToGIDs = new HashMap<Character, 
Integer>();
+
+
     private final MultiByteFont font;
 
     public CIDSubset(MultiByteFont mbf) {
@@ -93,6 +99,7 @@ public class CIDSubset implements CIDSet
             usedGlyphs.put(glyphIndex, selector);
             usedGlyphsIndex.put(selector, glyphIndex);
             usedCharsIndex.put(selector, unicode);
+            charToGIDs.put(unicode, glyphIndex);
             usedGlyphsCount++;
             return selector;
         } else {
@@ -106,6 +113,17 @@ public class CIDSubset implements CIDSet
     }
 
     /** {@inheritDoc} */
+    public char getUnicodeFromGID(int glyphIndex) {
+        int selector = usedGlyphs.get(glyphIndex);
+        return usedCharsIndex.get(selector);
+    }
+
+    /** {@inheritDoc} */
+    public int getGIDFromChar(char ch) {
+        return charToGIDs.get(ch);
+    }
+
+    /** {@inheritDoc} */
     public char[] getChars() {
         char[] charArray = new char[usedGlyphsCount];
         for (int i = 0; i < usedGlyphsCount; i++) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java Mon Aug 
10 14:15:48 2015
@@ -568,4 +568,16 @@ public abstract class CustomFont extends
         this.strikeoutThickness = strikeoutThickness;
     }
 
+    /**
+     * Returns a Map of used Glyphs.
+     * @return Map Map of used Glyphs
+     */
+    public abstract Map<Integer, Integer> getUsedGlyphs();
+
+    /**
+     * Returns the character from it's original glyph index in the font
+     * @param glyphIndex The original index of the character
+     * @return The character
+     */
+    public abstract char getUnicodeFromGID(int glyphIndex);
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java Mon 
Aug 10 14:15:48 2015
@@ -426,6 +426,24 @@ public class MultiByteFont extends CIDFo
     }
 
     /**
+     * Returns the character from it's original glyph index in the font
+     * @param glyphIndex The original index of the character
+     * @return The character
+     */
+    public char getUnicodeFromGID(int glyphIndex) {
+        return cidSet.getUnicodeFromGID(glyphIndex);
+    }
+
+    /**
+     * Gets the original glyph index in the font from a character.
+     * @param ch The character
+     * @return The glyph index in the font
+     */
+    public int getGIDFromChar(char ch) {
+        return cidSet.getGIDFromChar(ch);
+    }
+
+    /**
      * Establishes the glyph definition table.
      * @param gdef the glyph definition table to be used by this font
      */

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java Mon 
Aug 10 14:15:48 2015
@@ -63,6 +63,7 @@ public class SingleByteFont extends Cust
     private LinkedHashMap<Integer, String> usedGlyphNames;
     private Map<Integer, Integer> usedGlyphs;
     private Map<Integer, Character> usedCharsIndex;
+    private Map<Character, Integer> charGIDMappings;
 
     public SingleByteFont(InternalResourceResolver resourceResolver) {
         super(resourceResolver);
@@ -76,6 +77,7 @@ public class SingleByteFont extends Cust
             usedGlyphNames = new LinkedHashMap<Integer, String>();
             usedGlyphs = new HashMap<Integer, Integer>();
             usedCharsIndex = new HashMap<Integer, Character>();
+            charGIDMappings = new HashMap<Character, Integer>();
 
             // The zeroth value is reserved for .notdef
             usedGlyphs.put(0, 0);
@@ -234,6 +236,7 @@ public class SingleByteFont extends Cust
             int selector = usedGlyphsCount;
             usedGlyphs.put(glyphIndex, selector);
             usedCharsIndex.put(selector, unicode);
+            charGIDMappings.put(unicode, glyphIndex);
             usedGlyphsCount++;
             return selector;
         } else {
@@ -519,6 +522,15 @@ public class SingleByteFont extends Cust
         return getUnicode(selector);
     }
 
+    public int getGIDFromChar(char ch) {
+        return charGIDMappings.get(ch);
+    }
+
+    public char getUnicodeFromGID(int glyphIndex) {
+        int selector = usedGlyphs.get(glyphIndex);
+        return usedCharsIndex.get(selector);
+    }
+
     public void mapUsedGlyphName(int gid, String value) {
         usedGlyphNames.put(gid, value);
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java 
Mon Aug 10 14:15:48 2015
@@ -47,7 +47,7 @@ public class GlyfTable {
     /** All the glyphs that are composed, but do not appear in the subset. */
     protected Set<Integer> composedGlyphs = new TreeSet<Integer>();
 
-    protected GlyfTable(FontFileReader in, OFMtxEntry[] metrics, OFDirTabEntry 
dirTableEntry,
+    public GlyfTable(FontFileReader in, OFMtxEntry[] metrics, OFDirTabEntry 
dirTableEntry,
                         Map<Integer, Integer> glyphs) throws IOException {
         mtxTab = metrics;
         tableOffset = dirTableEntry.getOffset();
@@ -202,7 +202,7 @@ public class GlyfTable {
         } while (GlyfFlags.hasMoreComposites(flags));
     }
 
-    private boolean isComposite(int indexInOriginal) throws IOException {
+    public boolean isComposite(int indexInOriginal) throws IOException {
         int numberOfContours = in.readTTFShort(tableOffset + 
mtxTab[indexInOriginal].getOffset());
         return numberOfContours < 0;
     }
@@ -215,7 +215,7 @@ public class GlyfTable {
      * @return the set of glyph indices this glyph composes
      * @throws IOException an I/O error
      */
-    private Set<Integer> retrieveComposedGlyphs(int indexInOriginal)
+    public Set<Integer> retrieveComposedGlyphs(int indexInOriginal)
             throws IOException {
         Set<Integer> composedGlyphs = new HashSet<Integer>();
         long offset = tableOffset + mtxTab[indexInOriginal].getOffset() + 10;

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java 
Mon Aug 10 14:15:48 2015
@@ -30,7 +30,7 @@ import java.util.Arrays;
 public class OFDirTabEntry {
 
     private byte[] tag = new byte[4];
-    private int checksum;
+    private long checksum;
     private long offset;
     private long length;
 
@@ -74,7 +74,7 @@ public class OFDirTabEntry {
      * Returns the checksum.
      * @return int
      */
-    public int getChecksum() {
+    public long getChecksum() {
         return checksum;
     }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java 
Mon Aug 10 14:15:48 2015
@@ -355,7 +355,7 @@ public abstract class OpenFont {
                   long offset) throws IOException {
         OFDirTabEntry dt = dirTabs.get(tableName);
         if (dt == null) {
-            log.error("Dirtab " + tableName.getName() + " not found.");
+            log.info("Dirtab " + tableName.getName() + " not found.");
             return false;
         } else {
             in.seekSet(dt.getOffset() + offset);
@@ -966,6 +966,15 @@ public abstract class OpenFont {
     }
 
     /**
+     * Returns the original bounding box values from the HEAD table
+     * @return An array of bounding box values
+     */
+    public int[] getBBoxRaw() {
+        int[] bbox = {fontBBox1, fontBBox2, fontBBox3, fontBBox4};
+        return bbox;
+    }
+
+    /**
      * Returns the LowerCaseAscent attribute of the font.
      * @return int The LowerCaseAscent
      */
@@ -1048,6 +1057,18 @@ public abstract class OpenFont {
     }
 
     /**
+     * Returns the width of a given character in raw units
+     * @param idx Index of the character
+     * @return int Width in it's raw form stored in the font
+     */
+    public int getCharWidthRaw(int idx) {
+        if (ansiWidth != null) {
+            return ansiWidth[idx];
+        }
+        return -1;
+    }
+
+    /**
      * Returns the kerning table.
      * @return Map The kerning table
      */
@@ -1978,4 +1999,8 @@ public abstract class OpenFont {
             IOUtils.closeQuietly(stream);
         }
     }
+
+    public String getCopyrightNotice() {
+        return notice;
+    }
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java 
Mon Aug 10 14:15:48 2015
@@ -188,6 +188,14 @@ public class TTFFile extends OpenFont {
                     : (fontFile.readTTFUShort() << 1));
     }
 
+    /**
+     * Gets the last location of the glyf table
+     * @return The last location as a long
+     */
+    public long getLastGlyfLocation() {
+        return lastLoca;
+    }
+
     @Override
     protected void initializeFont(FontFileReader in) throws IOException {
         fontFile = in;

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
 Mon Aug 10 14:15:48 2015
@@ -83,7 +83,8 @@ public class ConfiguredFontCollection im
                     font = new CustomFontMetricsMapper(fontMetrics, 
fontSource);
                 } else {
                     FontUris fontUris = new FontUris(fontURI, null);
-                    CustomFont fontMetrics = FontLoader.loadFont(fontUris, 
null, true,
+                    CustomFont fontMetrics = FontLoader.loadFont(fontUris,
+                            configFontInfo.getSubFontName(), true,
                             configFontInfo.getEmbeddingMode(), 
configFontInfo.getEncodingMode(),
                             configFontInfo.getKerning(), 
configFontInfo.getAdvanced(), resourceResolver);
                     font = new CustomFontMetricsMapper(fontMetrics);

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
 Mon Aug 10 14:15:48 2015
@@ -289,4 +289,8 @@ public class CustomFontMetricsMapper ext
         }
     }
 
+    public Typeface getRealFont() {
+        return typeface;
+    }
+
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/HardcodedFonts.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/HardcodedFonts.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/HardcodedFonts.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/HardcodedFonts.java 
Mon Aug 10 14:15:48 2015
@@ -55,7 +55,7 @@ final class HardcodedFonts {
         return selectFont(gen, name, size);
     }
 
-    private static boolean selectFont(PCLGenerator gen, String name, int size) 
throws IOException {
+    protected static boolean selectFont(PCLGenerator gen, String name, int 
size) throws IOException {
         int fontcode = 0;
         if (name.length() > 1 && name.charAt(0) == 'F') {
             try {

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.java 
Mon Aug 10 14:15:48 2015
@@ -53,4 +53,13 @@ public interface PCLEventProducer extend
      */
     void paperTypeUnavailable(Object source, long pageWidth, long pageHeight, 
String fallbackPaper);
 
+    /**
+     * The font type is not supported for PCL output.
+     * @param source The event source
+     * @param fontName The name of the font not supported
+     * @param supportedTypes The types of fonts currently supported
+     * @event.severity ERROR
+     */
+    void fontTypeNotSupported(Object source, String fontName, String 
supportedTypes);
+
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml 
Mon Aug 10 14:15:48 2015
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <catalogue xml:lang="en">
   <message key="paperTypeUnavailable">Paper type ({pageWidth} x {pageHeight} 
mpt) could not be determined. Falling back to: {fallbackPaper}</message>
+  <message key="fontTypeNotSupported">The font '{fontName}' is not supported. 
PCL output currently only supports {supportedTypes}</message>
 </catalogue>

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java 
Mon Aug 10 14:15:48 2015
@@ -141,6 +141,15 @@ public class PCLGenerator {
     }
 
     /**
+     * Writes raw bytes to the output stream
+     * @param bytes The bytes
+     * @throws IOException In case of an I/O error
+     */
+    public void writeBytes(byte[] bytes) throws IOException {
+        out.write(bytes);
+    }
+
+    /**
      * Formats a double value with two decimal positions for PCL output.
      *
      * @param value value to format

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLPainter.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLPainter.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLPainter.java 
Mon Aug 10 14:15:48 2015
@@ -28,7 +28,9 @@ import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 
@@ -42,16 +44,27 @@ import org.apache.xmlgraphics.image.load
 import org.apache.xmlgraphics.java2d.GraphicContext;
 import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
 
+import org.apache.fop.fonts.CIDFontType;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.MultiByteFont;
+import org.apache.fop.fonts.Typeface;
 import org.apache.fop.render.ImageHandlerUtil;
 import org.apache.fop.render.RenderingContext;
 import org.apache.fop.render.intermediate.AbstractIFPainter;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFState;
 import org.apache.fop.render.intermediate.IFUtil;
+import org.apache.fop.render.java2d.CustomFontMetricsMapper;
 import org.apache.fop.render.java2d.FontMetricsMapper;
 import org.apache.fop.render.java2d.Java2DPainter;
+import org.apache.fop.render.pcl.fonts.PCLCharacterWriter;
+import org.apache.fop.render.pcl.fonts.PCLSoftFont;
+import org.apache.fop.render.pcl.fonts.PCLSoftFontManager;
+import org.apache.fop.render.pcl.fonts.PCLSoftFontManager.PCLTextSegment;
+import org.apache.fop.render.pcl.fonts.truetype.PCLTTFCharacterWriter;
 import org.apache.fop.traits.BorderProps;
 import org.apache.fop.traits.RuleStyle;
 import org.apache.fop.util.CharUtilities;
@@ -73,6 +86,8 @@ public class PCLPainter extends Abstract
     private Stack<GraphicContext> graphicContextStack = new 
Stack<GraphicContext>();
     private GraphicContext graphicContext = new GraphicContext();
 
+    private PCLSoftFontManager sfManager = new PCLSoftFontManager();
+
     /**
      * Main constructor.
      * @param parent the parent document handler
@@ -315,16 +330,51 @@ public class PCLPainter extends Abstract
             //TODO Ignored: state.getFontVariant()
             //TODO Opportunity for font caching if font state is more heavily 
used
             String fontKey = getFontKey(triplet);
-            boolean pclFont = getPCLUtil().isAllTextAsBitmaps() ? false
-                        : HardcodedFonts.setFont(gen, fontKey, 
state.getFontSize(), text);
+            Typeface tf = getTypeface(fontKey);
+            boolean drawAsBitmaps = getPCLUtil().isAllTextAsBitmaps();
+            boolean pclFont = HardcodedFonts.setFont(gen, fontKey, 
state.getFontSize(), text);
             if (pclFont) {
                 drawTextNative(x, y, letterSpacing, wordSpacing, dp, text, 
triplet);
             } else {
-                drawTextAsBitmap(x, y, letterSpacing, wordSpacing, dp, text, 
triplet);
-                if (DEBUG) {
-                    state.setTextColor(Color.GRAY);
-                    HardcodedFonts.setFont(gen, "F1", state.getFontSize(), 
text);
-                    drawTextNative(x, y, letterSpacing, wordSpacing, dp, text, 
triplet);
+                // TrueType conversion to a soft font (PCL 5 Technical 
Reference - Chapter 11)
+                if (!drawAsBitmaps && isTrueType(tf)) {
+                    boolean madeSF = false;
+                    if (sfManager.getSoftFont(tf, text) == null) {
+                        madeSF = true;
+                        ByteArrayOutputStream baos = 
sfManager.makeSoftFont(tf);
+                        if (baos != null) {
+                            gen.writeBytes(baos.toByteArray());
+                        }
+                    }
+                    String formattedSize = 
gen.formatDouble2(state.getFontSize() / 1000.0);
+                    gen.writeCommand(String.format("(s%sV", formattedSize));
+                    List<PCLTextSegment> textSegments = 
sfManager.getTextSegments(text, tf);
+                    if (textSegments.isEmpty()) {
+                        textSegments.add(new 
PCLTextSegment(sfManager.getSoftFontID(tf), text));
+                    }
+                    boolean first = true;
+                    for (PCLTextSegment textSegment : textSegments) {
+                        gen.writeCommand(String.format("(%dX", 
textSegment.getFontID()));
+                        PCLSoftFont softFont = 
sfManager.getSoftFontFromID(textSegment.getFontID());
+                        PCLCharacterWriter charWriter = new 
PCLTTFCharacterWriter(softFont);
+                        
gen.writeBytes(sfManager.assignFontID(textSegment.getFontID()));
+                        
gen.writeBytes(charWriter.writeCharacterDefinitions(textSegment.getText()));
+                        if (first) {
+                            drawTextUsingSoftFont(x, y, letterSpacing, 
wordSpacing, dp,
+                                    textSegment.getText(), triplet, softFont);
+                            first = false;
+                        } else {
+                            drawTextUsingSoftFont(-1, -1, letterSpacing, 
wordSpacing, dp,
+                                    textSegment.getText(), triplet, softFont);
+                        }
+                    }
+                } else {
+                    drawTextAsBitmap(x, y, letterSpacing, wordSpacing, dp, 
text, triplet);
+                    if (DEBUG) {
+                        state.setTextColor(Color.GRAY);
+                        HardcodedFonts.setFont(gen, "F1", state.getFontSize(), 
text);
+                        drawTextNative(x, y, letterSpacing, wordSpacing, dp, 
text, triplet);
+                    }
                 }
             }
         } catch (IOException ioe) {
@@ -332,6 +382,29 @@ public class PCLPainter extends Abstract
         }
     }
 
+    private boolean isTrueType(Typeface tf) {
+        if (tf.getFontType().equals(FontType.TRUETYPE)) {
+            return true;
+        } else if (tf instanceof CustomFontMetricsMapper) {
+            Typeface realFont = ((CustomFontMetricsMapper) tf).getRealFont();
+            if (realFont instanceof MultiByteFont) {
+                return ((MultiByteFont) 
realFont).getCIDType().equals(CIDFontType.CIDTYPE2);
+            }
+        }
+        return false;
+    }
+
+    private Typeface getTypeface(String fontName) {
+        if (fontName == null) {
+            throw new NullPointerException("fontName must not be null");
+        }
+        Typeface tf = getFontInfo().getFonts().get(fontName);
+        if (tf instanceof LazyFont) {
+            tf = ((LazyFont)tf).getRealFont();
+        }
+        return tf;
+    }
+
     private void drawTextNative(int x, int y, int letterSpacing, int 
wordSpacing, int[][] dp,
             String text, FontTriplet triplet) throws IOException {
         Color textColor = state.getTextColor();
@@ -414,25 +487,87 @@ public class PCLPainter extends Abstract
 
     }
 
+    private void drawTextUsingSoftFont(int x, int y, int letterSpacing, int 
wordSpacing, int[][] dp,
+            String text, FontTriplet triplet, PCLSoftFont softFont) throws 
IOException {
+        Color textColor = state.getTextColor();
+        if (textColor != null) {
+            gen.setTransparencyMode(true, false);
+            gen.selectGrayscale(textColor);
+        }
+
+        if (x != -1 && y != -1) {
+            setCursorPos(x, y);
+        }
+
+        float fontSize = state.getFontSize() / 1000f;
+        Font font = getFontInfo().getFontInstance(triplet, 
state.getFontSize());
+        int l = text.length();
+        int[] dx = IFUtil.convertDPToDX(dp);
+        int dxl = (dx != null ? dx.length : 0);
+
+        StringBuffer sb = new StringBuffer(Math.max(16, l));
+        if (dx != null && dxl > 0 && dx[0] != 0) {
+            sb.append("\u001B&a+").append(gen.formatDouble2(dx[0] / 
100.0)).append('H');
+        }
+        String current = "";
+        for (int i = 0; i < l; i++) {
+            char orgChar = text.charAt(i);
+            float glyphAdjust = 0;
+            if (!font.hasChar(orgChar)) {
+                if (CharUtilities.isFixedWidthSpace(orgChar)) {
+                    //Fixed width space are rendered as spaces so copy/paste 
works in a reader
+                    char ch = font.mapChar(CharUtilities.SPACE);
+                    int spaceDiff = font.getCharWidth(ch) - 
font.getCharWidth(orgChar);
+                    glyphAdjust = -(10 * spaceDiff / fontSize);
+                }
+            }
+
+            if ((wordSpacing != 0) && 
CharUtilities.isAdjustableSpace(orgChar)) {
+                glyphAdjust += wordSpacing;
+            }
+            current += orgChar;
+            glyphAdjust += letterSpacing;
+            if (dx != null && i < dxl - 1) {
+                glyphAdjust += dx[i + 1];
+            }
+
+            if (glyphAdjust != 0) {
+                
gen.getOutputStream().write(sb.toString().getBytes(gen.getTextEncoding()));
+                for (int j = 0; j < current.length(); j++) {
+                    
gen.getOutputStream().write(softFont.getCharCode(current.charAt(j)));
+                }
+                sb = new StringBuffer();
+
+                String command = (glyphAdjust > 0) ? "\u001B&a+" : "\u001B&a";
+                sb.append(command).append(gen.formatDouble2(glyphAdjust / 
100.0)).append('H');
+
+                current = "";
+            }
+        }
+        if (!current.equals("")) {
+            
gen.getOutputStream().write(sb.toString().getBytes(gen.getTextEncoding()));
+            for (int i = 0; i < current.length(); i++) {
+                
gen.getOutputStream().write(softFont.getCharCode(current.charAt(i)));
+            }
+        }
+    }
+
     private static final double SAFETY_MARGIN_FACTOR = 0.05;
 
-    private Rectangle getTextBoundingBox(int x, int y,
-            int letterSpacing, int wordSpacing, int[][] dp,
-            String text,
-            Font font, FontMetricsMapper metrics) {
+    private Rectangle getTextBoundingBox(int x, int y, int letterSpacing, int 
wordSpacing,
+            int[][] dp, String text, Font font, FontMetricsMapper metrics) {
         int maxAscent = metrics.getMaxAscent(font.getFontSize()) / 1000;
-        int descent = metrics.getDescender(font.getFontSize()) / 1000; //is 
negative
-        int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
-        Rectangle boundingRect = new Rectangle(
-                x, y - maxAscent - safetyMargin,
-                0, maxAscent - descent + 2 * safetyMargin);
+        int descent = metrics.getDescender(font.getFontSize()) / 1000; // is 
negative
+        int safetyMargin = (int) (SAFETY_MARGIN_FACTOR * font.getFontSize());
+        Rectangle boundingRect = new Rectangle(x, y - maxAscent - 
safetyMargin, 0, maxAscent
+                - descent + 2 * safetyMargin);
 
         int l = text.length();
         int[] dx = IFUtil.convertDPToDX(dp);
         int dxl = (dx != null ? dx.length : 0);
 
         if (dx != null && dxl > 0 && dx[0] != 0) {
-            boundingRect.setLocation(boundingRect.x - (int)Math.ceil(dx[0] / 
10f), boundingRect.y);
+            boundingRect.setLocation(boundingRect.x - (int) Math.ceil(dx[0] / 
10f), boundingRect.y);
         }
         float width = 0.0f;
         for (int i = 0; i < l; i++) {
@@ -451,19 +586,17 @@ public class PCLPainter extends Abstract
             width += cw + glyphAdjust;
         }
         int extraWidth = font.getFontSize() / 3;
-        boundingRect.setSize(
-                (int)Math.ceil(width) + extraWidth,
-                boundingRect.height);
+        boundingRect.setSize((int) Math.ceil(width) + extraWidth, 
boundingRect.height);
         return boundingRect;
     }
 
-    private void drawTextAsBitmap(final int x, final int y,
-            final int letterSpacing, final int wordSpacing, final int[][] dp,
-            final String text, FontTriplet triplet) throws IFException {
-        //Use Java2D to paint different fonts via bitmap
+    private void drawTextAsBitmap(final int x, final int y, final int 
letterSpacing,
+            final int wordSpacing, final int[][] dp, final String text, 
FontTriplet triplet)
+            throws IFException {
+        // Use Java2D to paint different fonts via bitmap
         final Font font = getFontInfo().getFontInstance(triplet, 
state.getFontSize());
 
-        //for cursive fonts, so the text isn't clipped
+        // for cursive fonts, so the text isn't clipped
         FontMetricsMapper mapper;
         try {
             mapper = (FontMetricsMapper) 
getFontInfo().getMetricsFor(font.getFontName());
@@ -473,11 +606,11 @@ public class PCLPainter extends Abstract
         final int maxAscent = mapper.getMaxAscent(font.getFontSize()) / 1000;
         final int ascent = mapper.getAscender(font.getFontSize()) / 1000;
         final int descent = mapper.getDescender(font.getFontSize()) / 1000;
-        int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
+        int safetyMargin = (int) (SAFETY_MARGIN_FACTOR * font.getFontSize());
         final int baselineOffset = maxAscent + safetyMargin;
 
-        final Rectangle boundingBox = getTextBoundingBox(x, y,
-                letterSpacing, wordSpacing, dp, text, font, mapper);
+        final Rectangle boundingBox = getTextBoundingBox(x, y, letterSpacing, 
wordSpacing, dp,
+                text, font, mapper);
         final Dimension dim = boundingBox.getSize();
 
         Graphics2DImagePainter painter = new Graphics2DImagePainter() {
@@ -485,7 +618,7 @@ public class PCLPainter extends Abstract
             public void paint(Graphics2D g2d, Rectangle2D area) {
                 if (DEBUG) {
                     g2d.setBackground(Color.LIGHT_GRAY);
-                    g2d.clearRect(0, 0, (int)area.getWidth(), 
(int)area.getHeight());
+                    g2d.clearRect(0, 0, (int) area.getWidth(), (int) 
area.getHeight());
                 }
                 g2d.translate(-x, -y + baselineOffset);
 
@@ -501,7 +634,7 @@ public class PCLPainter extends Abstract
                 try {
                     painter.drawText(x, y, letterSpacing, wordSpacing, dp, 
text);
                 } catch (IFException e) {
-                    //This should never happen with the Java2DPainter
+                    // This should never happen with the Java2DPainter
                     throw new RuntimeException("Unexpected error while 
painting text", e);
                 }
             }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
 Mon Aug 10 14:15:48 2015
@@ -67,6 +67,7 @@ public class PCLRendererConfigurator ext
         if (config.isTextRendering() != null) {
             pclUtil.setAllTextAsBitmaps(config.isTextRendering());
         }
+
     }
 
     @Override

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java?rev=1695082&r1=1695081&r2=1695082&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java 
Mon Aug 10 14:15:48 2015
@@ -51,12 +51,6 @@ public class PCLRenderingUtil {
     private float ditheringQuality = 0.5f;
 
     /**
-     * Controls whether all text should be painted as text. This is a fallback 
setting in case
-     * the mixture of native and bitmapped text does not provide the necessary 
quality.
-     */
-    private boolean allTextAsBitmaps;
-
-    /**
      * Controls whether an RGB canvas is used when converting Java2D graphics 
to bitmaps.
      * This can be used to work around problems with Apache Batik, for 
example, but setting
      * this to true will increase memory consumption.
@@ -68,6 +62,12 @@ public class PCLRenderingUtil {
      */
     private boolean disabledPJL;
 
+    /**
+     * Controls whether all text should be painted as text. This is a fallback 
setting in case the mixture of native and
+     * bitmapped text does not provide the necessary quality.
+     */
+    private boolean allTextAsBitmaps;
+
     PCLRenderingUtil(FOUserAgent userAgent) {
         this.userAgent = userAgent;
         initialize();
@@ -127,8 +127,7 @@ public class PCLRenderingUtil {
     }
 
     /**
-     * Controls whether all text should be generated as bitmaps or only text 
for which there's
-     * no native font.
+     * Controls whether all text should be generated as bitmaps or only text 
for which there's no native font.
      * @param allTextAsBitmaps true if all text should be painted as bitmaps
      */
     public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to