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 je...@apache.org on 2008/03/28 10:09:48 UTC

svn commit: r642155 [2/2] - in /xmlgraphics/fop/branches/Temp_ProcessingFeedback: ./ lib/ src/codegen/fonts/ src/documentation/ src/java/org/apache/fop/fo/properties/ src/java/org/apache/fop/fonts/ src/java/org/apache/fop/fonts/truetype/ src/java/org/a...

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java Fri Mar 28 02:09:26 2008
@@ -23,7 +23,6 @@
 import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
 
@@ -36,8 +35,7 @@
  * @todo Implement getNextKnuthElements()
  */
 public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager {
-    private TableAndCaption fobj;
-    
+
     private Block curBlockArea;
 
     //private List childBreaks = new java.util.ArrayList();
@@ -48,7 +46,6 @@
      */
     public TableAndCaptionLayoutManager(TableAndCaption node) {
         super(node);
-        fobj = node;
     }
 
     /**
@@ -134,7 +131,7 @@
     public void addAreas(PositionIterator parentIter,
                          LayoutContext layoutContext) {
         getParentArea(null);
-        getPSLM().addIDToPage(fobj.getId());
+        addId();
 
         /* TODO: Reimplement using Knuth approach
         LayoutManager childLM;

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java Fri Mar 28 02:09:26 2008
@@ -23,7 +23,6 @@
 import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
 
@@ -34,7 +33,6 @@
  * @todo Implement getNextKnuthElements()
  */
 public class TableCaptionLayoutManager extends BlockStackingLayoutManager {
-    private TableCaption fobj;
 
     private Block curBlockArea;
 
@@ -46,7 +44,6 @@
      */
     public TableCaptionLayoutManager(TableCaption node) {
         super(node);
-        fobj = node;
     }
 
     /**
@@ -133,7 +130,7 @@
     public void addAreas(PositionIterator parentIter,
                          LayoutContext layoutContext) {
         getParentArea(null);
-        getPSLM().addIDToPage(fobj.getId());
+        addId();
 
         /* TODO: Reimplement using Knuth approach
         LayoutManager childLM;

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java Fri Mar 28 02:09:26 2008
@@ -136,7 +136,7 @@
         cellIPD = referenceIPD;
         cellIPD -= getIPIndents();
 
-        LinkedList returnedList = null;
+        LinkedList returnedList;
         LinkedList contentList = new LinkedList();
         LinkedList returnList = new LinkedList();
 
@@ -242,7 +242,7 @@
             p.setP(0);
         }
 
-        getPSLM().notifyEndOfLayout(((TableCell)getFObj()).getId());
+        getPSLM().notifyEndOfLayout(fobj.getId());
 
         setFinished(true);
         return returnList;
@@ -330,7 +330,7 @@
                          int firstRowHeight) {
         getParentArea(null);
 
-        getPSLM().addIDToPage(getTableCell().getId());
+        addId();
 
         int borderBeforeWidth = primaryGridUnit.getBeforeBorderWidth(startRow, borderBeforeWhich);
         int borderAfterWidth = primaryGridUnit.getAfterBorderWidth(endRow, borderAfterWhich);
@@ -419,7 +419,7 @@
                     int dx = xoffset;
                     for (int x = 0; x < gridUnits.length; x++) {
                         int ipd = getTable().getColumn(primaryGridUnit.getColIndex() + x)
-                                .getColumnWidth().getValue((PercentBaseContext) getParent());
+                                .getColumnWidth().getValue(getParent());
                         if (blocks[y][x] != null) {
                             Block block = blocks[y][x];
                             adjustYOffset(block, dy);
@@ -491,7 +491,7 @@
             Block rowBackgroundArea = getBackgroundArea(paddingRectBPD, borderBeforeWidth);
             ((TableLayoutManager) parentLM).addBackgroundArea(rowBackgroundArea);
             TraitSetter.addBackground(rowBackgroundArea, row.getCommonBorderPaddingBackground(),
-                    (TableLayoutManager) parentLM,
+                    parentLM,
                     -xoffset - startIndent, -borderBeforeWidth,
                     parentLM.getContentAreaIPD(), firstRowHeight);
         }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java Fri Mar 28 02:09:26 2008
@@ -235,7 +235,7 @@
 
 
         // Elements for the table-header/footer/body
-        LinkedList contentKnuthElements = null;
+        LinkedList contentKnuthElements;
         contentLM = new TableContentLayoutManager(this);
         LayoutContext childLC = new LayoutContext(0);
         /*
@@ -321,7 +321,7 @@
     public void addAreas(PositionIterator parentIter,
                          LayoutContext layoutContext) {
         getParentArea(null);
-        getPSLM().addIDToPage(getTable().getId());
+        addId();
 
         // add space before, in order to implement display-align = "center" or "after"
         if (layoutContext.getSpaceBefore() != 0) {
@@ -381,7 +381,7 @@
         resetSpaces();
         curBlockArea = null;
         
-        getPSLM().notifyEndOfLayout(((Table)getFObj()).getId());
+        getPSLM().notifyEndOfLayout(fobj.getId());
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFCMap.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFCMap.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFCMap.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFCMap.java Fri Mar 28 02:09:26 2008
@@ -21,7 +21,6 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.StringWriter;
 import java.io.Writer;
 
 /**
@@ -425,10 +424,8 @@
     
     /** {@inheritDoc} */
     protected int output(OutputStream stream) throws IOException {
-        StringWriter writer = new StringWriter();
-        CMapBuilder builder = createCMapBuilder(writer);
+        CMapBuilder builder = createCMapBuilder(getBufferWriter());
         builder.writeCMap();
-        add(writer.getBuffer().toString()); //TODO Could be optimized by not buffering
         return super.output(stream);
     }
 }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFEncoding.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFEncoding.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFEncoding.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFEncoding.java Fri Mar 28 02:09:26 2008
@@ -132,6 +132,14 @@
         }
         
         /**
+         * Indicates whether any differences have been recorded.
+         * @return true if there are differences.
+         */
+        public boolean hasDifferences() {
+            return (this.differences.length() > 0);
+        }
+        
+        /**
          * Creates and returns the PDFArray representing the Differences entry.
          * @return the Differences entry
          */

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFFactory.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFFactory.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFFactory.java Fri Mar 28 02:09:26 2008
@@ -43,6 +43,7 @@
 import org.apache.xmlgraphics.xmp.Metadata;
 
 import org.apache.fop.fonts.CIDFont;
+import org.apache.fop.fonts.CIDSubset;
 import org.apache.fop.fonts.CodePointMapping;
 import org.apache.fop.fonts.CustomFont;
 import org.apache.fop.fonts.FontDescriptor;
@@ -50,6 +51,8 @@
 import org.apache.fop.fonts.FontType;
 import org.apache.fop.fonts.LazyFont;
 import org.apache.fop.fonts.MultiByteFont;
+import org.apache.fop.fonts.SimpleSingleByteEncoding;
+import org.apache.fop.fonts.SingleByteEncoding;
 import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.truetype.FontFileReader;
@@ -1166,7 +1169,7 @@
     }
 
     /**
-     * make a Type1 /Font object
+     * Make a Type1 /Font object.
      *
      * @param fontname internal name to use for this font (eg "F1")
      * @param basefont name of the base font (eg "Helvetica")
@@ -1217,10 +1220,12 @@
                                    (PDFCIDFontDescriptor)pdfdesc);
                 getDocument().registerObject(cidFont);
 
-                PDFCMap cmap = new PDFToUnicodeCMap(cidMetrics.getCharsUsed(), "fop-ucs-H",
-                    new PDFCIDSystemInfo("Adobe",
-                        "Identity",
-                        0));
+                PDFCMap cmap = new PDFToUnicodeCMap(
+                        cidMetrics.getCIDSubset().getSubsetChars(),
+                        "fop-ucs-H",
+                        new PDFCIDSystemInfo("Adobe",
+                            "Identity",
+                            0));
                 getDocument().registerObject(cmap);
                 ((PDFFontType0)font).setCMAP(cmap);
                 ((PDFFontType0)font).setDescendantFonts(cidFont);
@@ -1238,35 +1243,20 @@
                 int lastChar = singleByteFont.getLastChar();
                 nonBase14.setWidthMetrics(firstChar,
                                      lastChar,
-                                     makeArray(metrics.getWidths()));
+                                     new PDFArray(null, metrics.getWidths()));
                 
                 //Handle encoding
-                CodePointMapping mapping = singleByteFont.getCodePointMapping();
+                SingleByteEncoding mapping = singleByteFont.getEncoding();
                 if (PDFEncoding.isPredefinedEncoding(mapping.getName())) {
                     font.setEncoding(mapping.getName());
                 } else {
-                    CodePointMapping winansi = CodePointMapping.getMapping(
-                            CodePointMapping.WIN_ANSI_ENCODING);
-                    PDFEncoding pdfEncoding = new PDFEncoding(winansi.getName());
-                    PDFEncoding.DifferencesBuilder builder
-                            = pdfEncoding.createDifferencesBuilder();
-                    int start = -1;
-                    String[] winansiNames = winansi.getCharNameMap();
-                    String[] charNameMap = mapping.getCharNameMap();
-                    for (int i = 0; i < 256; i++) {
-                        String wac = winansiNames[i];
-                        String c = charNameMap[i];
-                        if (!wac.equals(c)) {
-                            if (start != i) {
-                                builder.addDifference(i);
-                                start = i;
-                            }
-                            builder.addName(c);
-                            start++;
-                        }
+                    Object pdfEncoding = createPDFEncoding(mapping,
+                            singleByteFont.getFontName());
+                    if (pdfEncoding instanceof PDFEncoding) {
+                        font.setEncoding((PDFEncoding)pdfEncoding);
+                    } else {
+                        font.setEncoding((String)pdfEncoding);
                     }
-                    pdfEncoding.setDifferences(builder.toPDFArray());
-                    font.setEncoding(pdfEncoding);
                     
                     /* JM: What I thought would be a necessity with custom encodings turned out to
                      * be a bug in Adobe Acrobat 8. The following section just demonstrates how
@@ -1278,21 +1268,88 @@
                     nonBase14.setToUnicode(cmap);
                     */
                 }
+                
+                //Handle additional encodings (characters outside the primary encoding)
+                if (singleByteFont.hasAdditionalEncodings()) {
+                    for (int i = 0, c = singleByteFont.getAdditionalEncodingCount(); i < c; i++) {
+                        SimpleSingleByteEncoding addEncoding
+                            = singleByteFont.getAdditionalEncoding(i);
+                        String name = fontname + "_" + (i + 1);
+                        Object pdfenc = createPDFEncoding(addEncoding,
+                                singleByteFont.getFontName());
+                        PDFFontNonBase14 addFont = (PDFFontNonBase14)PDFFont.createFont(
+                                name, fonttype,
+                                basefont, pdfenc);
+                        addFont.setDescriptor(pdfdesc);
+                        addFont.setWidthMetrics(
+                                addEncoding.getFirstChar(),
+                                addEncoding.getLastChar(),
+                                new PDFArray(null, singleByteFont.getAdditionalWidths(i)));
+                        getDocument().registerObject(addFont);
+                        getDocument().getResources().addFont(addFont);
+                    }
+                }
             }
 
             return font;
         }
     }
 
+    /**
+     * Creates a PDFEncoding instance from a CodePointMapping instance.
+     * @param encoding the code point mapping (encoding)
+     * @return the PDF Encoding dictionary (or a String with the predefined encoding)
+     */
+    public Object createPDFEncoding(SingleByteEncoding encoding, String fontNameHint) {
+        SingleByteEncoding baseEncoding;
+        if (fontNameHint.indexOf("Symbol") >= 0) {
+            baseEncoding = CodePointMapping.getMapping(
+                    CodePointMapping.SYMBOL_ENCODING);
+        } else {
+            baseEncoding = CodePointMapping.getMapping(
+                    CodePointMapping.STANDARD_ENCODING);
+        }
+        PDFEncoding pdfEncoding = new PDFEncoding(baseEncoding.getName());
+        PDFEncoding.DifferencesBuilder builder
+                = pdfEncoding.createDifferencesBuilder();
+        int start = -1;
+        String[] baseNames = baseEncoding.getCharNameMap();
+        String[] charNameMap = encoding.getCharNameMap();
+        for (int i = 0, ci = charNameMap.length; i < ci; i++) {
+            String basec = baseNames[i];
+            String c = charNameMap[i];
+            if (!basec.equals(c)) {
+                if (start != i) {
+                    builder.addDifference(i);
+                    start = i;
+                }
+                builder.addName(c);
+                start++;
+            }
+        }
+        if (builder.hasDifferences()) {
+            pdfEncoding.setDifferences(builder.toPDFArray());
+            return pdfEncoding;
+        } else {
+            return baseEncoding.getName();
+        }
+    }
+
+    /**
+     * Creates and returns a width array with the widths of all the characters in the subset.
+     * @param cidFont the font
+     * @return the width array
+     */
     public PDFWArray getSubsetWidths(CIDFont cidFont) {
         // Create widths for reencoded chars
         PDFWArray warray = new PDFWArray();
-        int[] tmpWidth = new int[cidFont.usedGlyphsCount];
-
-        for (int i = 0; i < cidFont.usedGlyphsCount; i++) {
-            Integer nw = (Integer)cidFont.usedGlyphsIndex.get(new Integer(i));
-            int nwx = (nw == null) ? 0 : nw.intValue();
-            tmpWidth[i] = cidFont.width[nwx];
+        int[] widths = cidFont.getWidths();
+        CIDSubset subset = cidFont.getCIDSubset();
+        int[] tmpWidth = new int[subset.getSubsetSize()];
+
+        for (int i = 0, c = subset.getSubsetSize(); i < c; i++) {
+            int nwx = Math.max(0, subset.getGlyphIndexForSubsetIndex(i));
+            tmpWidth[i] = widths[nwx];
         }
         warray.addEntry(0, tmpWidth);
         return warray;
@@ -1345,12 +1402,7 @@
     }
 
     private void buildCIDSet(PDFFontDescriptor descriptor, CIDFont cidFont) {
-        BitSet cidSubset = new BitSet();
-        Iterator iter = cidFont.usedGlyphs.keySet().iterator();
-        while (iter.hasNext()) {
-            Integer cid = (Integer)iter.next();
-            cidSubset.set(cid.intValue());
-        }
+        BitSet cidSubset = cidFont.getCIDSubset().getGlyphIndexBitSet();
         PDFStream cidSet = makeStream(null, true);
         ByteArrayOutputStream baout = new ByteArrayOutputStream(cidSubset.length() / 8 + 1);
         int value = 0;
@@ -1548,14 +1600,13 @@
     }
 
     /**
-     * make an Array object (ex. Widths array for a font)
+     * Make an Array object (ex. Widths array for a font).
      *
      * @param values the int array values
      * @return the PDF Array with the int values
      */
     public PDFArray makeArray(int[] values) {
         PDFArray array = new PDFArray(null, values);
-
         getDocument().registerObject(array);
         return array;
     }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFResources.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFResources.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFResources.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFResources.java Fri Mar 28 02:09:26 2008
@@ -110,7 +110,7 @@
                     desc = (FontDescriptor)font;
                 }
                 addFont(doc.getFactory().makeFont(
-                    f, font.getEmbedFontName(), font.getEncoding(), font, desc));
+                    f, font.getEmbedFontName(), font.getEncodingName(), font, desc));
             }
         }
     }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFStream.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFStream.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFStream.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFStream.java Fri Mar 28 02:09:26 2008
@@ -19,8 +19,9 @@
  
 package org.apache.fop.pdf;
 
-import java.io.OutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
 
 /**
  * Class representing a PDF stream.
@@ -37,6 +38,8 @@
      */
     protected StreamCache data;
 
+    private transient Writer streamWriter;
+    
     /**
      * Create an empty stream object
      */
@@ -44,6 +47,10 @@
         super();
         try {
             data = StreamCacheFactory.getInstance().createStreamCache();
+            this.streamWriter = new java.io.OutputStreamWriter(
+                    getBufferOutputStream(), PDFDocument.ENCODING);
+            //Buffer to minimize calls to the converter
+            this.streamWriter = new java.io.BufferedWriter(this.streamWriter);
         } catch (IOException ex) {
             //TODO throw the exception and catch it elsewhere
             ex.printStackTrace();
@@ -57,21 +64,35 @@
      */
     public void add(String s) {
         try {
-            data.getOutputStream().write(PDFDocument.encode(s));
+            this.streamWriter.write(s);
         } catch (IOException ex) {
             //TODO throw the exception and catch it elsewhere
             ex.printStackTrace();
         }
-
+    }
+    
+    private void flush() throws IOException {
+        this.streamWriter.flush();
     }
     
     /**
+     * Returns a Writer that writes to the OutputStream of the buffer.
+     * @return the Writer
+     */
+    public Writer getBufferWriter() {
+        return this.streamWriter;
+    }
+
+    /**
      * Returns an OutputStream that can be used to write to the buffer which is used
      * to build up the PDF stream.
      * @return the OutputStream
      * @throws IOException In case of an I/O problem
      */
     public OutputStream getBufferOutputStream() throws IOException {
+        if (this.streamWriter != null) {
+            flush(); //Just to be sure
+        }
         return this.data.getOutputStream();
     }
     
@@ -91,6 +112,7 @@
      */
     public int getDataLength() {
         try {
+            flush();
             return data.getSize();
         } catch (Exception e) {
             //TODO throw the exception and catch it elsewhere
@@ -99,17 +121,15 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     protected int getSizeHint() throws IOException {
+        flush();
         return data.getSize();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     protected void outputRawStreamData(OutputStream out) throws IOException {
+        flush();
         data.outputContents(out);
     }
 

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFTTFStream.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFTTFStream.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFTTFStream.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/pdf/PDFTTFStream.java Fri Mar 28 02:09:26 2008
@@ -67,7 +67,7 @@
      */
     public void setData(byte[] data, int size) throws IOException {
         this.data.clear();
-        this.data.getOutputStream().write(data, 0, size);
+        getBufferOutputStream().write(data, 0, size);
     }
 
 }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java Fri Mar 28 02:09:26 2008
@@ -174,11 +174,8 @@
         return charSet.mapChar(c);
     }
 
-    /**
-     * Get the encoding of the font.
-     * @return the encoding
-     */
-    public String getEncoding() {
+    /** {@inheritDoc} */
+    public String getEncodingName() {
         return charSet.getEncoding();
     }
 }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/RasterFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/RasterFont.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/RasterFont.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/afp/fonts/RasterFont.java Fri Mar 28 02:09:26 2008
@@ -25,6 +25,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.fo.properties.FixedLength;
 import org.apache.fop.render.afp.exceptions.FontRuntimeException;
 
@@ -229,11 +230,8 @@
         return charSet.mapChar(c);
     }
 
-    /**
-     * Get the encoding of the font.
-     * @return the encoding
-     */
-    public String getEncoding() {
+    /** {@inheritDoc} */
+    public String getEncodingName() {
         return charSet.getEncoding();
     }
 

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java Fri Mar 28 02:09:26 2008
@@ -112,7 +112,7 @@
     }
 
     /** {@inheritDoc} */
-    public final String getEncoding() {
+    public final String getEncodingName() {
         return null; //Not applicable to Java2D rendering
     }
 

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java Fri Mar 28 02:09:26 2008
@@ -172,7 +172,7 @@
     }
 
     /** {@inheritDoc} */
-    public String getEncoding() {
+    public String getEncodingName() {
         return null; //Not applicable to Java2D rendering
     }
 

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java Fri Mar 28 02:09:26 2008
@@ -81,7 +81,7 @@
     /** {@inheritDoc} */
     public void setup(PDFDocument doc) {
 
-        ICC_Profile prof = image.getICCProfile();
+        ICC_Profile prof = getEffectiveICCProfile();
         PDFDeviceColorSpace pdfCS = toPDFColorSpace(getImageColorSpace());
         if (prof != null) {
             pdfICCStream = setupColorProfile(doc, prof, pdfCS);
@@ -100,6 +100,14 @@
         }
     }
 
+    /**
+     * Returns the effective ICC profile for the image.
+     * @return an ICC profile or null
+     */
+    protected ICC_Profile getEffectiveICCProfile() {
+        return image.getICCProfile();
+    }
+    
     private static PDFICCStream setupColorProfile(PDFDocument doc,
                 ICC_Profile prof, PDFDeviceColorSpace pdfCS) {
         boolean defaultsRGB = ColorProfileUtil.isDefaultsRGB(prof);

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java Fri Mar 28 02:09:26 2008
@@ -18,19 +18,33 @@
 /* $Id$ */
 
 package org.apache.fop.render.pdf;
+import java.awt.color.ICC_Profile;
+import java.io.DataInput;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.commons.io.IOUtils;
+
 import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.image.loader.impl.JPEGConstants;
+import org.apache.xmlgraphics.image.loader.impl.JPEGFile;
+import org.apache.xmlgraphics.image.loader.util.ImageUtil;
 
 import org.apache.fop.pdf.DCTFilter;
 import org.apache.fop.pdf.PDFDeviceColorSpace;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFFilter;
 import org.apache.fop.pdf.PDFFilterList;
+import org.apache.fop.util.ColorProfileUtil;
 
 /**
  * PDFImage implementation for the PDF renderer which handles raw JPEG images.
+ * <p>
+ * The JPEG is copied to the XObject's stream as-is but some elements (marker segments) are
+ * filtered. For example, an embedded color profile is filtered since it is already added as
+ * a PDF object and associated with the XObject. This way, the PDF file size is kept as small
+ * as possible.
  */
 public class ImageRawJPEGAdapter extends AbstractImageAdapter {
 
@@ -68,6 +82,21 @@
     }
 
     /** {@inheritDoc} */
+    protected ICC_Profile getEffectiveICCProfile() {
+        ICC_Profile profile = super.getEffectiveICCProfile();
+        if (profile != null 
+                && profile.getNumComponents() == 3
+                && !ColorProfileUtil.isDefaultsRGB(profile)) {
+            //RGB profiles which are not sRGB don't seem to work.
+            //Without this override, the image drifts into yellow for an unknown reason.
+            //TODO Find out why this happens.
+            //Test using a JPEG images with, for example, "Adobe RGB 1998" color profile.
+            profile = null;
+        }
+        return profile;
+    }
+    
+    /** {@inheritDoc} */
     public int getBitsPerComponent() {
         return 8;
     }
@@ -84,7 +113,77 @@
     
     /** {@inheritDoc} */
     public void outputContents(OutputStream out) throws IOException {
-        getImage().writeTo(out);
+        InputStream in = getImage().createInputStream();
+        in = ImageUtil.decorateMarkSupported(in);
+        try {
+            JPEGFile jpeg = new JPEGFile(in);
+            DataInput din = jpeg.getDataInput();
+            
+            //Copy the whole JPEG file except:
+            // - the ICC profile
+            //TODO Thumbnails could safely be skipped, too.
+            //TODO Metadata (XMP, IPTC, EXIF) could safely be skipped, too.
+            while (true) {
+                int reclen;
+                int segID = jpeg.readMarkerSegment();
+                switch (segID) {
+                case JPEGConstants.SOI:
+                    out.write(0xFF);
+                    out.write(segID);
+                    break;
+                case JPEGConstants.EOI:
+                case JPEGConstants.SOS:
+                    out.write(0xFF);
+                    out.write(segID);
+                    IOUtils.copy(in, out); //Just copy the rest!
+                    return;
+                /*
+                case JPEGConstants.APP1: //Metadata
+                case JPEGConstants.APPD:
+                    jpeg.skipCurrentMarkerSegment();
+                    break;*/
+                case JPEGConstants.APP2: //ICC (see ICC1V42.pdf)
+                    boolean skipICCProfile = false;
+                    in.mark(16);
+                    try {
+                        reclen = jpeg.readSegmentLength();
+                        // Check for ICC profile
+                        byte[] iccString = new byte[11];
+                        din.readFully(iccString);
+                        din.skipBytes(1); //string terminator (null byte)
+
+                        if ("ICC_PROFILE".equals(new String(iccString, "US-ASCII"))) {
+                            skipICCProfile = (this.image.getICCProfile() != null);
+                        }
+                    } finally {
+                        in.reset();
+                    }
+                    if (skipICCProfile) {
+                        //ICC profile is skipped as it is already embedded as a PDF object
+                        jpeg.skipCurrentMarkerSegment();
+                        break;
+                    }
+                default:
+                    out.write(0xFF);
+                    out.write(segID);
+                    
+                    reclen = jpeg.readSegmentLength();
+                    //write short
+                    out.write((reclen >>> 8) & 0xFF);
+                    out.write((reclen >>> 0) & 0xFF);
+                    int left = reclen - 2;
+                    byte[] buf = new byte[2048];
+                    while (left > 0) {
+                        int part = Math.min(buf.length, left);
+                        din.readFully(buf, 0, part);
+                        out.write(buf, 0, part);
+                        left -= part;
+                    }
+                }
+            }
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java Fri Mar 28 02:09:26 2008
@@ -89,8 +89,8 @@
         PDFGraphics2D graphics = new PDFGraphics2D(textAsShapes, 
                 pdfInfo.fi, pdfInfo.pdfDoc,
                 pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(),
-                renderer.currentFontName,
-                renderer.currentFontSize);
+                pdfInfo.currentFontName,
+                pdfInfo.currentFontSize);
         graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
         
         AffineTransform transform = new AffineTransform();

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFRenderer.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/pdf/PDFRenderer.java Fri Mar 28 02:09:26 2008
@@ -63,7 +63,6 @@
 import org.apache.fop.area.OffDocumentItem;
 import org.apache.fop.area.PageSequence;
 import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.RegionViewport;
 import org.apache.fop.area.Trait;
 import org.apache.fop.area.inline.AbstractTextArea;
 import org.apache.fop.area.inline.Image;
@@ -79,6 +78,8 @@
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.extensions.xmp.XMPMetadata;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.pdf.PDFAMode;
 import org.apache.fop.pdf.PDFAction;
@@ -107,7 +108,7 @@
 import org.apache.fop.pdf.PDFResources;
 import org.apache.fop.pdf.PDFState;
 import org.apache.fop.pdf.PDFStream;
-import org.apache.fop.pdf.PDFText;
+import org.apache.fop.pdf.PDFTextUtil;
 import org.apache.fop.pdf.PDFXMode;
 import org.apache.fop.pdf.PDFXObject;
 import org.apache.fop.render.AbstractPathOrientedRenderer;
@@ -251,21 +252,14 @@
     /** drawing state */
     protected PDFState currentState = null;
 
-    /** Name of currently selected font */
-    protected String currentFontName = "";
-    /** Size of currently selected font */
-    protected int currentFontSize = 0;
+    /** Text generation utility holding the current font status */
+    protected PDFTextUtil textutil;
     /** page height */
     protected int pageHeight;
 
     /** Registry of PDF filters */
     protected Map filterMap;
 
-    /**
-     * true if a BT command has been written. 
-     */
-    protected boolean inTextMode = false;
-
     /** Image handler registry */
     private PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry();
     
@@ -525,7 +519,7 @@
         currentContext = null;
         currentPage = null;
         currentState = null;
-        currentFontName = "";
+        this.textutil = null;
 
         idPositions.clear();
         idGoTos.clear();
@@ -664,19 +658,15 @@
 
     /** Indicates the beginning of a text object. */
     protected void beginTextObject() {
-        if (!inTextMode) {
-            currentStream.add("BT\n");
-            currentFontName = "";
-            inTextMode = true;
+        if (!textutil.isInTextObject()) {
+            textutil.beginTextObject();
         }
     }
 
     /** Indicates the end of a text object. */
     protected void endTextObject() {
-        closeText();
-        if (inTextMode) {
-            currentStream.add("ET\n");
-            inTextMode = false;
+        if (textutil.isInTextObject()) {
+            textutil.endTextObject();
         }
     }
 
@@ -786,6 +776,11 @@
 
         currentStream = this.pdfDoc.getFactory()
             .makeStream(PDFFilterList.CONTENT_FILTER, false);
+        this.textutil = new PDFTextUtil() {
+            protected void write(String code) {
+                currentStream.add(code);
+            }
+        };
 
         currentState = new PDFState();
         // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's
@@ -794,9 +789,6 @@
         currentState.concatenate(basicPageTransform);
         currentStream.add(CTMHelper.toPDFString(basicPageTransform, false) + " cm\n");
         
-        
-        currentFontName = "";
-
         super.renderPage(page);
 
         this.pdfDoc.registerObject(currentStream);
@@ -807,6 +799,7 @@
         }
         this.pdfDoc.addObject(currentPage);
         this.pdfDoc.output(ostream);
+        this.textutil = null;
     }
 
     /** {@inheritDoc} */
@@ -840,17 +833,6 @@
     }
     
     /**
-     * Handle the traits for a region
-     * This is used to draw the traits for the given page region.
-     * (See Sect. 6.4.1.2 of XSL-FO spec.)
-     * @param region the RegionViewport whose region is to be drawn
-     */
-    protected void handleRegionTraits(RegionViewport region) {
-        currentFontName = "";
-        super.handleRegionTraits(region);
-    }
-
-    /**
      * Formats a float value (normally coordinates) as Strings.
      * @param value the value
      * @return the formatted value
@@ -865,7 +847,8 @@
         float w = x2 - x1;
         float h = y2 - y1;
         if ((w < 0) || (h < 0)) {
-            log.error("Negative extent received (w=" + w + ", h=" + h + "). Border won't be painted.");
+            log.error("Negative extent received (w=" + w + ", h=" + h
+                    + "). Border won't be painted.");
             return;
         }
         switch (style) {
@@ -1328,12 +1311,9 @@
         super.renderBlock(block);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     protected void renderLineArea(LineArea line) {
         super.renderLineArea(line);
-        closeText();
     }
 
     /**
@@ -1415,11 +1395,20 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    private Typeface getTypeface(String fontName) {
+        Typeface tf = (Typeface) fontInfo.getFonts().get(fontName);
+        if (tf instanceof LazyFont) {
+            tf = ((LazyFont)tf).getRealFont();
+        }
+        return tf;
+    }
+    
+    /** {@inheritDoc} */
     public void renderText(TextArea text) {
         renderInlineAreaBackAndBorders(text);
+        Color ct = (Color) text.getTrait(Trait.COLOR);
+        updateColor(ct, true);
+        
         beginTextObject();
         StringBuffer pdf = new StringBuffer();
 
@@ -1427,12 +1416,10 @@
         int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
         
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
-        Typeface tf = (Typeface) fontInfo.getFonts().get(fontName);
-        boolean useMultiByte = tf.isMultiByte();
+        Typeface tf = getTypeface(fontName);
+        
+        textutil.updateTf(fontName, size / 1000f, tf.isMultiByte());
         
-        updateFont(fontName, size, pdf);
-        Color ct = (Color) text.getTrait(Trait.COLOR);
-        updateColor(ct, true, pdf);
 
         // word.getOffset() = only height of text itself
         // currentBlockIPPosition: 0 for beginning of line; nonzero
@@ -1440,66 +1427,46 @@
         int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
         int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
 
-        pdf.append("1 0 0 -1 " + format(rx / 1000f) + " " + format(bl / 1000f) + " Tm "
-                   /*+ format(text.getTextLetterSpaceAdjust() / 1000f) + " Tc\n"*/
-                   /*+ format(text.getTextWordSpaceAdjust() / 1000f) + " Tw ["*/);
+        textutil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, rx / 1000f, bl / 1000f));
 
-        pdf.append("[");
         currentStream.add(pdf.toString());
 
         super.renderText(text);
 
-        currentStream.add("] TJ\n");
+        textutil.writeTJ();
         
         renderTextDecoration(tf, size, text, bl, rx);
     }
-    
-    /**
-     * {@inheritDoc}
-     */
+
+    /** {@inheritDoc} */
     public void renderWord(WordArea word) {
         Font font = getFontFromArea(word.getParentArea());
-        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
-        boolean useMultiByte = tf.isMultiByte();
-
-        StringBuffer pdf = new StringBuffer();
-        
         String s = word.getWord();
-        escapeText(s, word.getLetterAdjustArray(), 
-                font, (AbstractTextArea)word.getParentArea(), useMultiByte, pdf);
 
-        currentStream.add(pdf.toString());
+        escapeText(s, word.getLetterAdjustArray(), 
+                font, (AbstractTextArea)word.getParentArea());
 
         super.renderWord(word);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void renderSpace(SpaceArea space) {
         Font font = getFontFromArea(space.getParentArea());
-        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
-        boolean useMultiByte = tf.isMultiByte();
-
         String s = space.getSpace();
         
-        StringBuffer pdf = new StringBuffer();
-
         AbstractTextArea textArea = (AbstractTextArea)space.getParentArea();
-        escapeText(s, null, font, textArea, useMultiByte, pdf);
+        escapeText(s, null, font, textArea);
 
         if (space.isAdjustable()) {
             int tws = -((TextArea) space.getParentArea()).getTextWordSpaceAdjust()
                          - 2 * textArea.getTextLetterSpaceAdjust();
 
             if (tws != 0) {
-                pdf.append(format(tws / (font.getFontSize() / 1000f)));
-                pdf.append(" ");
+                float adjust = tws / (font.getFontSize() / 1000f);
+                textutil.adjustGlyphTJ(adjust);
             }
         }
 
-        currentStream.add(pdf.toString());
-
         super.renderSpace(space);
     }
 
@@ -1507,101 +1474,77 @@
      * Escapes text according to PDF rules.
      * @param s Text to escape
      * @param letterAdjust an array of widths for letter adjustment (may be null)
-     * @param fs Font state
+     * @param font to font in use
+     * @param parentArea the parent text area to retrieve certain traits from
+     */
+    protected void escapeText(String s,
+                           int[] letterAdjust,
+                           Font font, AbstractTextArea parentArea) {
+        escapeText(s, 0, s.length(), letterAdjust, font, parentArea);
+    }
+    
+    /**
+     * Escapes text according to PDF rules.
+     * @param s Text to escape
+     * @param start the start position in the text
+     * @param end the end position in the text
+     * @param letterAdjust an array of widths for letter adjustment (may be null)
+     * @param font to font in use
      * @param parentArea the parent text area to retrieve certain traits from
-     * @param useMultiByte Indicates the use of multi byte convention
-     * @param pdf target buffer for the escaped text
      */
-    public void escapeText(String s, int[] letterAdjust,
-                           Font fs, AbstractTextArea parentArea,
-                           boolean useMultiByte, StringBuffer pdf) {
-        String startText = useMultiByte ? "<" : "(";
-        String endText = useMultiByte ? "> " : ") ";
-
-        /*
-        boolean kerningAvailable = false;
-        Map kerning = fs.getKerning();
-        if (kerning != null && !kerning.isEmpty()) {
-            //kerningAvailable = true;
-            //TODO Reenable me when the layout engine supports kerning, too
-            log.warn("Kerning support is disabled until it is supported by the layout engine!");
+    protected void escapeText(String s, int start, int end,
+                           int[] letterAdjust,
+                           Font font, AbstractTextArea parentArea) {
+        String fontName = font.getFontName();
+        float fontSize = font.getFontSize() / 1000f;
+        Typeface tf = getTypeface(fontName);
+        SingleByteFont singleByteFont = null;
+        if (tf instanceof SingleByteFont) {
+            singleByteFont = (SingleByteFont)tf;
         }
-        */
 
         int l = s.length();
-
-        float fontSize = fs.getFontSize() / 1000f;
-        boolean startPending = true;
-        for (int i = 0; i < l; i++) {
+        
+        for (int i = start; i < end; i++) {
             char orgChar = s.charAt(i);
             char ch;
             float glyphAdjust = 0;
-            if (fs.hasChar(orgChar)) {
-                ch = fs.mapChar(orgChar);
+            if (font.hasChar(orgChar)) {
+                ch = font.mapChar(orgChar);
+                if (singleByteFont != null && singleByteFont.hasAdditionalEncodings()) {
+                    int encoding = ch / 256;
+                    if (encoding == 0) {
+                        textutil.updateTf(fontName, fontSize, tf.isMultiByte());
+                    } else {
+                        textutil.updateTf(fontName + "_" + Integer.toString(encoding),
+                                fontSize, tf.isMultiByte());
+                        ch = (char)(ch % 256);
+                    }
+                }
                 int tls = (i < l - 1 ? parentArea.getTextLetterSpaceAdjust() : 0);
                 glyphAdjust -= tls;
             } else {
                 if (CharUtilities.isFixedWidthSpace(orgChar)) {
                     //Fixed width space are rendered as spaces so copy/paste works in a reader
-                    ch = fs.mapChar(CharUtilities.SPACE);
-                    glyphAdjust = fs.getCharWidth(ch) - fs.getCharWidth(orgChar);
+                    ch = font.mapChar(CharUtilities.SPACE);
+                    glyphAdjust = font.getCharWidth(ch) - font.getCharWidth(orgChar);
                 } else {
-                    ch = fs.mapChar(orgChar);
+                    ch = font.mapChar(orgChar);
                 }
             }
             if (letterAdjust != null && i < l - 1) {
                 glyphAdjust -= letterAdjust[i + 1];
             }
 
-            if (startPending) {
-                pdf.append(startText);
-                startPending = false;
-            }
-            if (!useMultiByte) {
-                if (ch < 32 || ch > 127) {
-                    pdf.append("\\");
-                    pdf.append(Integer.toOctalString((int) ch));
-                } else {
-                    switch (ch) {
-                        case '(':
-                        case ')':
-                        case '\\':
-                            pdf.append("\\");
-                            break;
-                        default:
-                    }
-                    pdf.append(ch);
-                }
-            } else {
-                pdf.append(PDFText.toUnicodeHex(ch));
-            }
+            textutil.writeTJMappedChar(ch);
 
             float adjust = glyphAdjust / fontSize;
 
             if (adjust != 0) {
-                pdf.append(endText).append(format(adjust)).append(' ');
-                startPending = true;
+                textutil.adjustGlyphTJ(adjust);
             }
 
         }
-        if (!startPending) {
-            pdf.append(endText);
-        }
-    }
-
-    /**
-     * Checks to see if we have some text rendering commands open
-     * still and writes out the TJ command to the stream if we do
-     */
-    protected void closeText() {
-        /*
-        if (textOpen) {
-            currentStream.add("] TJ\n");
-            textOpen = false;
-            prevWordX = 0;
-            prevWordY = 0;
-            currentFontName = "";
-        }*/
     }
 
     /**
@@ -1615,8 +1558,6 @@
     protected void setColor(Color col, boolean fill, StringBuffer pdf) {
         PDFColor color = new PDFColor(this.pdfDoc, col);
 
-        closeText();
-        
         if (pdf != null) {
             pdf.append(color.getColorSpaceOut(fill));
         } else {
@@ -1648,22 +1589,10 @@
     }
 
     /** {@inheritDoc} */
-    protected  void updateColor(Color col, boolean fill) {
+    protected void updateColor(Color col, boolean fill) {
         updateColor(col, fill, null);
     }
     
-    private void updateFont(String name, int size, StringBuffer pdf) {
-        if ((!name.equals(this.currentFontName))
-                || (size != this.currentFontSize)) {
-            closeText();
-
-            this.currentFontName = name;
-            this.currentFontSize = size;
-            pdf = pdf.append("/" + name + " " + format((float) size / 1000f)
-                              + " Tf\n");
-        }
-    }
-
     /** {@inheritDoc} */
     public void renderImage(Image image, Rectangle2D pos) {
         endTextObject();
@@ -1798,9 +1727,8 @@
         context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext);
         context.setProperty(PDFRendererContextConstants.PDF_STREAM, currentStream);
         context.setProperty(PDFRendererContextConstants.PDF_FONT_INFO, fontInfo);
-        context.setProperty(PDFRendererContextConstants.PDF_FONT_NAME, currentFontName);
-        context.setProperty(PDFRendererContextConstants.PDF_FONT_SIZE,
-                            new Integer(currentFontSize));
+        context.setProperty(PDFRendererContextConstants.PDF_FONT_NAME, "");
+        context.setProperty(PDFRendererContextConstants.PDF_FONT_SIZE, new Integer(0));
         return context;
     }
 

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSFontUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSFontUtils.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSFontUtils.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSFontUtils.java Fri Mar 28 02:09:26 2008
@@ -32,16 +32,20 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.fonts.Glyphs;
 import org.apache.xmlgraphics.ps.DSCConstants;
 import org.apache.xmlgraphics.ps.PSGenerator;
 import org.apache.xmlgraphics.ps.PSResource;
 import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
 
+import org.apache.fop.fonts.Base14Font;
 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.SingleByteEncoding;
+import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
 
 /**
@@ -81,9 +85,21 @@
         while (iter.hasNext()) {
             String key = (String)iter.next();
             Typeface tf = getTypeFace(fontInfo, fonts, key);
-            PSResource fontRes = new PSResource("font", tf.getFontName());
+            PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getFontName());
             fontResources.put(key, fontRes);
             embedFont(gen, tf, fontRes);
+            
+            if (tf instanceof SingleByteFont) {
+                SingleByteFont sbf = (SingleByteFont)tf;
+                for (int i = 0, c = sbf.getAdditionalEncodingCount(); i < c; i++) {
+                    SingleByteEncoding encoding = sbf.getAdditionalEncoding(i);
+                    defineEncoding(gen, encoding);
+                    String postFix = "_" + (i + 1);
+                    PSResource derivedFontRes = defineDerivedFont(gen, tf.getFontName(),
+                            tf.getFontName() + postFix, encoding.getName());
+                    fontResources.put(key + postFix, derivedFontRes);
+                }
+            }
         }
         gen.commentln("%FOPEndFontDict");
         reencodeFonts(gen, fonts);
@@ -91,29 +107,35 @@
     }
 
     private static void reencodeFonts(PSGenerator gen, Map fonts) throws IOException {
+        ResourceTracker tracker = gen.getResourceTracker();
+        
+        if (!tracker.isResourceSupplied(WINANSI_ENCODING_RESOURCE)) {
+            defineWinAnsiEncoding(gen);
+        }
         gen.commentln("%FOPBeginFontReencode");
-        defineWinAnsiEncoding(gen);
         
         //Rewrite font encodings
         Iterator iter = fonts.keySet().iterator();
         while (iter.hasNext()) {
             String key = (String)iter.next();
-            Typeface fm = (Typeface)fonts.get(key);
-            if (fm instanceof LazyFont && ((LazyFont)fm).getRealFont() == null) {
-                continue;
-            } else if (null == fm.getEncoding()) {
+            Typeface tf = (Typeface)fonts.get(key);
+            if (tf instanceof LazyFont) {
+                tf = ((LazyFont)tf).getRealFont();
+                if (tf == null) {
+                    continue;
+                }
+            }
+            if (null == tf.getEncodingName()) {
                 //ignore (ZapfDingbats and Symbol used to run through here, kept for safety reasons)
-            } else if ("SymbolEncoding".equals(fm.getEncoding())) {
+            } else if ("SymbolEncoding".equals(tf.getEncodingName())) {
                 //ignore (no encoding redefinition)
-            } else if ("ZapfDingbatsEncoding".equals(fm.getEncoding())) {
+            } else if ("ZapfDingbatsEncoding".equals(tf.getEncodingName())) {
                 //ignore (no encoding redefinition)
-            } else if ("WinAnsiEncoding".equals(fm.getEncoding())) {
-                redefineFontEncoding(gen, fm.getFontName(), fm.getEncoding());
             } else {
-                /* Don't complain anymore, just use the font's default encoding.
-                gen.commentln("%WARNING: Only WinAnsiEncoding is supported. Font '" 
-                    + fm.getFontName() + "' asks for: " + fm.getEncoding());
-                */
+                if (tf instanceof Base14Font) {
+                    //Our Base 14 fonts don't use the default encoding 
+                    redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName());
+                }
             }
         }
         gen.commentln("%FOPEndFontReencode");
@@ -233,10 +255,88 @@
                     if (isEmbeddable(cf)) {
                         resTracker.registerSuppliedResource(fontRes);
                     }
+                    if (tf instanceof SingleByteFont) {
+                        SingleByteFont sbf = (SingleByteFont)tf;
+                        for (int i = 0, c = sbf.getAdditionalEncodingCount(); i < c; i++) {
+                            SingleByteEncoding encoding = sbf.getAdditionalEncoding(i);
+                            PSResource encodingRes = new PSResource(
+                                    PSResource.TYPE_ENCODING, encoding.getName());
+                            resTracker.registerSuppliedResource(encodingRes);
+                            PSResource derivedFontRes = new PSResource(
+                                    PSResource.TYPE_FONT, tf.getFontName() + "_" + (i + 1));
+                            resTracker.registerSuppliedResource(derivedFontRes);
+                        }
+                    }
                 }
             }
         }
         return fontResources;
     }
 
+    /**
+     * Defines the single-byte encoding for use in PostScript files.
+     * @param gen the PostScript generator
+     * @param encoding the single-byte encoding
+     * @return the PSResource instance that represents the encoding
+     * @throws IOException In case of an I/O problem
+     */
+    public static PSResource defineEncoding(PSGenerator gen, SingleByteEncoding encoding)
+            throws IOException {
+        PSResource res = new PSResource(PSResource.TYPE_ENCODING, encoding.getName());
+        gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res);
+        gen.writeln("/" + encoding.getName() + " [");
+        String[] charNames = encoding.getCharNameMap();
+        for (int i = 0; i < 256; i++) {
+            if (i > 0) {
+                if ((i % 5) == 0) {
+                    gen.newLine();
+                } else {
+                    gen.write(" ");
+                }
+            }
+            String glyphname = null;
+            if (i < charNames.length) {
+                glyphname = charNames[i];
+            }
+            if (glyphname == null || "".equals(glyphname)) {
+                glyphname = Glyphs.NOTDEF;
+            }
+            gen.write("/");
+            gen.write(glyphname);
+        }
+        gen.newLine();
+        gen.writeln("] def");
+        gen.writeDSCComment(DSCConstants.END_RESOURCE);
+        gen.getResourceTracker().registerSuppliedResource(res);
+        return res;
+    }
+
+    /**
+     * Derives a new font based on an existing font with a given encoding. The encoding must
+     * have been registered before.
+     * @param gen the PostScript generator
+     * @param baseFontName the font name of the font to derive from
+     * @param fontName the font name of the new font to be define
+     * @param encoding the new encoding (must be predefined in the PS file)
+     * @return the PSResource representing the derived font
+     * @throws IOException In case of an I/O problem
+     */
+    public static PSResource defineDerivedFont(PSGenerator gen, String baseFontName, String fontName,
+            String encoding) throws IOException {
+        PSResource res = new PSResource(PSResource.TYPE_FONT, fontName);
+        gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res);
+        gen.commentln("%XGCDependencies: font " + baseFontName);
+        gen.commentln("%XGC+ encoding " + encoding);
+        gen.writeln("/" + baseFontName + " findfont");
+        gen.writeln("dup length dict begin");
+        gen.writeln("  {1 index /FID ne {def} {pop pop} ifelse} forall");
+        gen.writeln("  /Encoding " + encoding + " def");
+        gen.writeln("  currentdict");
+        gen.writeln("end");
+        gen.writeln("/" + fontName + " exch definefont pop");
+        gen.writeDSCComment(DSCConstants.END_RESOURCE);
+        gen.getResourceTracker().registerSuppliedResource(res);
+        return res;
+    }
+    
 }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSRenderer.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/render/ps/PSRenderer.java Fri Mar 28 02:09:26 2008
@@ -90,6 +90,7 @@
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.Graphics2DAdapter;
@@ -669,6 +670,12 @@
     }
     
     private String getPostScriptNameForFontKey(String key) {
+        int pos = key.indexOf('_');
+        String postFix = null;
+        if (pos > 0) {
+            postFix = key.substring(pos);
+            key = key.substring(0, pos);
+        }
         Map fonts = fontInfo.getFonts();
         Typeface tf = (Typeface)fonts.get(key);
         if (tf instanceof LazyFont) {
@@ -677,7 +684,11 @@
         if (tf == null) {
             throw new IllegalStateException("Font not available: " + key);
         }
-        return tf.getFontName();
+        if (postFix == null) {
+            return tf.getFontName();
+        } else {
+            return tf.getFontName() + postFix;
+        }
     }
     
     /**
@@ -707,7 +718,6 @@
     protected void useFont(String key, int size) {
         try {
             PSResource res = getPSResourceForFontKey(key);
-            //gen.useFont(key, size / 1000f);
             gen.useFont("/" + res.getName(), size / 1000f);
             gen.getResourceTracker().notifyResourceUsageOnPage(res);
         } catch (IOException ioe) {
@@ -960,7 +970,7 @@
         if (!isOptimizeResources()) {
             this.fontResources = PSFontUtils.writeFontDict(gen, fontInfo);
         } else {
-            gen.commentln("%FOPFontSetup");
+            gen.commentln("%FOPFontSetup"); //Place-holder, will be replaced in the second pass
         }
         gen.writeDSCComment(DSCConstants.END_SETUP);
     }
@@ -1303,17 +1313,16 @@
      */
     public void renderText(TextArea area) {
         renderInlineAreaBackAndBorders(area);
-        String fontname = getInternalFontNameForArea(area);
+        String fontkey = getInternalFontNameForArea(area);
         int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE);
 
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
-        Typeface tf = (Typeface) fontInfo.getFonts().get(fontname);
+        Typeface tf = (Typeface) fontInfo.getFonts().get(fontkey);
 
         //Determine position
         int rx = currentIPPosition + area.getBorderAndPaddingWidthStart();
         int bl = currentBPPosition + area.getOffset() + area.getBaselineOffset();
 
-        useFont(fontname, fontsize);
         Color ct = (Color)area.getTrait(Trait.COLOR);
         if (ct != null) {
             try {
@@ -1358,30 +1367,75 @@
         super.renderSpace(space);
     }
 
+    private Typeface getTypeface(String fontName) {
+        Typeface tf = (Typeface)fontInfo.getFonts().get(fontName);
+        if (tf instanceof LazyFont) {
+            tf = ((LazyFont)tf).getRealFont();
+        }
+        return tf;
+    }
+    
     private void renderText(AbstractTextArea area, String text, int[] letterAdjust) {
+        String fontkey = getInternalFontNameForArea(area);
+        int fontSize = area.getTraitAsInteger(Trait.FONT_SIZE);
         Font font = getFontFromArea(area);
-        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
+        Typeface tf = getTypeface(font.getFontName());
+        SingleByteFont singleByteFont = null;
+        if (tf instanceof SingleByteFont) {
+            singleByteFont = (SingleByteFont)tf;
+        }
 
+        int textLen = text.length();
+        if (singleByteFont != null && singleByteFont.hasAdditionalEncodings()) {
+            int start = 0;
+            int currentEncoding = -1;
+            for (int i = 0; i < textLen; i++) {
+                char c = text.charAt(i);
+                char mapped = tf.mapChar(c);
+                int encoding = mapped / 256;
+                if (currentEncoding != encoding) {
+                    if (i > 0) {
+                        writeText(area, text, start, i - start, letterAdjust, fontSize, tf);
+                    }
+                    if (encoding == 0) {
+                        useFont(fontkey, fontSize);
+                    } else {
+                        useFont(fontkey + "_" + Integer.toString(encoding), fontSize);
+                    }
+                    currentEncoding = encoding;
+                    start = i;
+                }
+            }
+            writeText(area, text, start, textLen - start, letterAdjust, fontSize, tf);
+        } else {
+            useFont(fontkey, fontSize);
+            writeText(area, text, 0, textLen, letterAdjust, fontSize, tf);
+        }
+    }
+
+    private void writeText(AbstractTextArea area, String text, int start, int len,
+            int[] letterAdjust, int fontsize, Typeface tf) {
+        int end = start + len;
         int initialSize = text.length();
         initialSize += initialSize / 2;
         StringBuffer sb = new StringBuffer(initialSize);
-        int textLen = text.length();
         if (letterAdjust == null 
                 && area.getTextLetterSpaceAdjust() == 0 
                 && area.getTextWordSpaceAdjust() == 0) {
             sb.append("(");
-            for (int i = 0; i < textLen; i++) {
+            for (int i = start; i < end; i++) {
                 final char c = text.charAt(i);
-                final char mapped = tf.mapChar(c);
+                final char mapped = (char)(tf.mapChar(c) % 256);
                 PSGenerator.escapeChar(mapped, sb);
             }
             sb.append(") t");
         } else {
             sb.append("(");
-            int[] offsets = new int[textLen];
-            for (int i = 0; i < textLen; i++) {
+            int[] offsets = new int[len];
+            for (int i = start; i < end; i++) {
                 final char c = text.charAt(i);
                 final char mapped = tf.mapChar(c);
+                char codepoint = (char)(mapped % 256);
                 int wordSpace;
 
                 if (CharUtilities.isAdjustableSpace(mapped)) {
@@ -1389,14 +1443,14 @@
                 } else {
                     wordSpace = 0;
                 }
-                int cw = tf.getWidth(mapped, font.getFontSize()) / 1000;
-                int ladj = (letterAdjust != null && i < textLen - 1 ? letterAdjust[i + 1] : 0);
-                int tls = (i < textLen - 1 ? area.getTextLetterSpaceAdjust() : 0); 
-                offsets[i] = cw + ladj + tls + wordSpace;
-                PSGenerator.escapeChar(mapped, sb);
+                int cw = tf.getWidth(mapped, fontsize) / 1000;
+                int ladj = (letterAdjust != null && i < end - 1 ? letterAdjust[i + 1] : 0);
+                int tls = (i < end - 1 ? area.getTextLetterSpaceAdjust() : 0); 
+                offsets[i - start] = cw + ladj + tls + wordSpace;
+                PSGenerator.escapeChar(codepoint, sb);
             }
             sb.append(")" + PSGenerator.LF + "[");
-            for (int i = 0; i < textLen; i++) {
+            for (int i = 0; i < len; i++) {
                 if (i > 0) {
                     if (i % 8 == 0) {
                         sb.append(PSGenerator.LF);
@@ -1409,7 +1463,6 @@
             sb.append("]" + PSGenerator.LF + "xshow");
         }
         writeln(sb.toString());
-
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFGraphics2D.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFGraphics2D.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFGraphics2D.java Fri Mar 28 02:09:26 2008
@@ -70,12 +70,10 @@
 import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
 import org.apache.xmlgraphics.java2d.GraphicContext;
 
-import org.apache.fop.fonts.CIDFont;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.fonts.LazyFont;
 import org.apache.fop.pdf.BitmapImage;
 import org.apache.fop.pdf.PDFAnnotList;
 import org.apache.fop.pdf.PDFColor;
@@ -1473,14 +1471,7 @@
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
         org.apache.fop.fonts.Typeface f
             = (org.apache.fop.fonts.Typeface)fontInfo.getFonts().get(name);
-        if (f instanceof LazyFont) {
-            if (((LazyFont) f).getRealFont() instanceof CIDFont) {
-                return true;
-            }
-        } else if (f instanceof CIDFont) {
-            return true;
-        }
-        return false;
+        return f.isMultiByte();
     }
 
     private void addKerning(StringWriter buf, Integer ch1, Integer ch2,

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextPainter.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextPainter.java Fri Mar 28 02:09:26 2008
@@ -43,6 +43,7 @@
 import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
 import org.apache.batik.gvt.text.TextPaintInfo;
 import org.apache.batik.gvt.text.TextSpanLayout;
+
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
@@ -83,8 +84,12 @@
             super.paintTextRuns(textRuns, g2d);
             return;
         }
-        PDFGraphics2D pdf = (PDFGraphics2D)g2d;
-        PDFTextUtil textUtil = new PDFTextUtil(pdf);
+        final PDFGraphics2D pdf = (PDFGraphics2D)g2d;
+        PDFTextUtil textUtil = new PDFTextUtil(pdf.fontInfo) {
+            protected void write(String code) {
+                pdf.currentStream.write(code);
+            }
+        };
         for (int i = 0; i < textRuns.size(); i++) {
             TextRun textRun = (TextRun)textRuns.get(i);
             AttributedCharacterIterator runaci = textRun.getACI();
@@ -134,7 +139,7 @@
             }
             
             textUtil.saveGraphicsState();
-            textUtil.concatMatrixCurrentTransform();
+            textUtil.concatMatrix(g2d.getTransform());
             Shape imclip = g2d.getClip();
             pdf.writeClip(imclip);
             

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextUtil.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/svg/PDFTextUtil.java Fri Mar 28 02:09:26 2008
@@ -19,145 +19,33 @@
 
 package org.apache.fop.svg;
 
-import java.awt.geom.AffineTransform;
-
 import org.apache.fop.fonts.Font;
-import org.apache.fop.pdf.PDFNumber;
-import org.apache.fop.pdf.PDFText;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.Typeface;
 
 /**
- * Utility class for generating PDF text objects.
+ * Utility class for generating PDF text objects. It needs to be subclassed to add writing
+ * functionality (see {@link #write(String)}).
  */
-public class PDFTextUtil {
+public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {
 
-    /** The number of decimal places. */ 
-    private static final int DEC = 8;
-    
-    /** PDF text rendering mode: Fill text */
-    public static final int TR_FILL = 0;
-    /** PDF text rendering mode: Stroke text */
-    public static final int TR_STROKE = 1;
-    /** PDF text rendering mode: Fill, then stroke text */
-    public static final int TR_FILL_STROKE = 2;
-    /** PDF text rendering mode: Neither fill nor stroke text (invisible) */
-    public static final int TR_INVISIBLE = 3;
-    /** PDF text rendering mode: Fill text and add to path for clipping */
-    public static final int TR_FILL_CLIP = 4;
-    /** PDF text rendering mode: Stroke text and add to path for clipping */
-    public static final int TR_STROKE_CLIP = 5;
-    /** PDF text rendering mode: Fill, then stroke text and add to path for clipping */
-    public static final int TR_FILL_STROKE_CLIP = 6;
-    /** PDF text rendering mode: Add text to path for clipping */
-    public static final int TR_CLIP = 7;
-    
-    
-    private PDFGraphics2D g2d;
-    private boolean inTextObject = false;
+    private FontInfo fontInfo;
     private Font[] fonts;
     private Font font;
-    private String startText;
-    private String endText;
-    private boolean useMultiByte;
-    private StringBuffer bufTJ;
-    private int textRenderingMode = 0;
     
     /**
      * Main constructor.
-     * @param g2d the PDFGraphics2D instance to work with
+     * @param fontInfo the font catalog
      */
-    public PDFTextUtil(PDFGraphics2D g2d) {
-        this.g2d = g2d;
+    public PDFTextUtil(FontInfo fontInfo) {
+        super();
+        this.fontInfo = fontInfo;
     }
     
-    private void writeAffineTransform(AffineTransform at, StringBuffer sb) {
-        double[] lt = new double[6];
-        at.getMatrix(lt);
-        sb.append(PDFNumber.doubleOut(lt[0], DEC)).append(" ");
-        sb.append(PDFNumber.doubleOut(lt[1], DEC)).append(" ");
-        sb.append(PDFNumber.doubleOut(lt[2], DEC)).append(" ");
-        sb.append(PDFNumber.doubleOut(lt[3], DEC)).append(" ");
-        sb.append(PDFNumber.doubleOut(lt[4], DEC)).append(" ");
-        sb.append(PDFNumber.doubleOut(lt[5], DEC));
-    }
-
-    private void writeChar(char ch, StringBuffer sb) {
-        if (!useMultiByte) {
-            if (ch > 127) {
-                sb.append("\\").append(Integer.toOctalString((int)ch));
-            } else {
-                switch (ch) {
-                case '(':
-                case ')':
-                case '\\':
-                    sb.append("\\");
-                    break;
-                default:
-                }
-                sb.append(ch);
-            }
-        } else {
-            sb.append(PDFText.toUnicodeHex(ch));
-        }
-    }
-    
-    private void checkInTextObject() {
-        if (!inTextObject) {
-            throw new IllegalStateException("Not in text object");
-        }
-    }
-    
-    /**
-     * Called when a new text object should be started. Be sure to call setFont() before
-     * issuing any text painting commands.
-     */
-    public void beginTextObject() {
-        if (inTextObject) {
-            throw new IllegalStateException("Already in text object");
-        }
-        g2d.currentStream.write("BT\n");
-        this.inTextObject = true;
-    }
-    
-    /**
-     * Called when a text object should be ended.
-     */
-    public void endTextObject() {
-        checkInTextObject();
-        g2d.currentStream.write("ET\n");
-        this.inTextObject = false;
-        initValues();
-    }
-    
-    private void initValues() {
+    /** {@inheritDoc} */
+    protected void initValues() {
+        super.initValues();
         this.font = null;
-        this.textRenderingMode = TR_FILL;
-    }
-    
-    /**
-     * Creates a "q" command, pushing a copy of the entire graphics state onto the stack.
-     */
-    public void saveGraphicsState() {
-        g2d.currentStream.write("q\n");
-    }
-    
-    /**
-     * Creates a "Q" command, restoring the entire graphics state to its former value by popping
-     * it from the stack.
-     */
-    public void restoreGraphicsState() {
-        g2d.currentStream.write("Q\n");
-    }
-    
-    /**
-     * Creates a "cm" command using the current transformation as the matrix.
-     */
-    public void concatMatrixCurrentTransform() {
-        StringBuffer sb = new StringBuffer();
-        if (!g2d.getTransform().isIdentity()) {
-            writeAffineTransform(g2d.getTransform(), sb);
-            sb.append(" cm\n");
-        }
-        g2d.currentStream.write(sb.toString());
     }
     
     /**
@@ -194,63 +82,23 @@
     }
     
     /**
+     * Determines whether the font with the given name is a multi-byte font.
+     * @param name the name of the font
+     * @return true if it's a multi-byte font
+     */
+    protected boolean isMultiByteFont(String name) {
+        Typeface f = (Typeface)fontInfo.getFonts().get(name);
+        return f.isMultiByte();
+    }
+
+    /**
      * Writes a "Tf" command, setting a new current font.
      * @param f the font to select
      */
     public void writeTf(Font f) {
-        checkInTextObject();
         String fontName = f.getFontName();
         float fontSize = (float)f.getFontSize() / 1000f;
-        g2d.currentStream.write("/" + fontName + " " + PDFNumber.doubleOut(fontSize) + " Tf\n");
-        
-        this.useMultiByte = g2d.isMultiByteFont(fontName);
-        this.startText = useMultiByte ? "<" : "(";
-        this.endText = useMultiByte ? ">" : ")";
-    }
-
-    /**
-     * Sets the text rendering mode.
-     * @param mode the rendering mode (value 0 to 7, see PDF Spec, constants: TR_*)
-     */
-    public void setTextRenderingMode(int mode) {
-        if (mode < 0 || mode > 7) {
-            throw new IllegalArgumentException(
-                    "Illegal value for text rendering mode. Expected: 0-7");
-        }
-        if (mode != this.textRenderingMode) {
-            this.textRenderingMode = mode;
-            g2d.currentStream.write(this.textRenderingMode + " Tr\n");
-        }
-    }
-    
-    /**
-     * Sets the text rendering mode.
-     * @param fill true if the text should be filled
-     * @param stroke true if the text should be stroked
-     * @param addToClip true if the path should be added for clipping
-     */
-    public void setTextRenderingMode(boolean fill, boolean stroke, boolean addToClip) {
-        int mode;
-        if (fill) {
-            mode = (stroke ? 2 : 0);
-        } else {
-            mode = (stroke ? 1 : 3);
-        }
-        if (addToClip) {
-            mode += 4;
-        }
-        setTextRenderingMode(mode);
-    }
-    
-    /**
-     * Writes a "Tm" command, setting a new text transformation matrix.
-     * @param localTransform the new text transformation matrix
-     */
-    public void writeTextMatrix(AffineTransform localTransform) {
-        StringBuffer sb = new StringBuffer();
-        writeAffineTransform(localTransform, sb);
-        sb.append(" Tm\n");
-        g2d.currentStream.write(sb.toString());
+        updateTf(fontName, fontSize, isMultiByteFont(fontName));
     }
 
     /**
@@ -272,37 +120,8 @@
      * @param ch the unmapped character
      */
     public void writeTJChar(char ch) {
-        if (bufTJ == null) {
-            bufTJ = new StringBuffer();
-        }
-        if (bufTJ.length() == 0) {
-            bufTJ.append("[").append(startText);
-        }
         char mappedChar = font.mapChar(ch);
-        writeChar(mappedChar, bufTJ);
-    }
-
-    /**
-     * Writes a glyph adjust value to the "TJ-Buffer".
-     * @param adjust the glyph adjust value in thousands of text unit space.
-     */
-    public void adjustGlyphTJ(double adjust) {
-        bufTJ.append(endText).append(" ");
-        bufTJ.append(PDFNumber.doubleOut(adjust, DEC - 4));
-        bufTJ.append(" ");
-        bufTJ.append(startText);
-    }
-
-    /**
-     * Writes a "TJ" command, writing out the accumulated buffer with the characters and glyph
-     * positioning values. The buffer is reset afterwards.
-     */
-    public void writeTJ() {
-        if (bufTJ != null && bufTJ.length() > 0) {
-            bufTJ.append(endText).append("] TJ\n");
-            g2d.currentStream.write(bufTJ.toString());
-            bufTJ.setLength(0);
-        }
+        writeTJMappedChar(mappedChar);
     }
 
 }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/status.xml?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/status.xml (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/status.xml Fri Mar 28 02:09:26 2008
@@ -52,13 +52,26 @@
   </contexts>
   
   <changes>
-    <!--release version="FOP Trunk" date="TBD"-->
+    <release version="FOP Trunk" date="TBD">
       <!-- change reverted, to be added back later
         <action context="Renderers" dev="AC" importance="high" type="add">
         Added SVG support for AFP (GOCA).
         </action>
       -->
-    <!--/release-->
+      <action context="Renderers" dev="JM" type="update">
+        When a JPEG image is embedded, an optionally embedded color profile is filtered out
+        as it's already embedded separately in the PDF file.
+      </action>
+      <action context="Renderers" dev="JM" type="fix">
+        Worked around a problem (PDF renderer) with JPEG image containing RGB color profiles which
+        are not sRGB. The images drifted into yellow. The color profile is simply disabled in this
+        case. Please let us know if you know what the problem could be.
+      </action>
+      <action context="Fonts" dev="JM" type="add">
+        Added support for addressing all glyphs available in a Type 1 font, not just the ones
+        in the font's primary encoding.
+      </action>
+    </release>
     <release version="0.95beta" date="22 March 2008">
       <notes>
         <section>

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java?rev=642155&r1=642154&r2=642155&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java Fri Mar 28 02:09:26 2008
@@ -65,7 +65,7 @@
          *  The following array is used to look for these patterns
          */ 
         final String[] testPatterns = { 
-                TEST_MARKER + "1", "(Standard)",
+                TEST_MARKER + "1", "Standard",
                 TEST_MARKER + "2", "XX_\\351_XX", 
                 TEST_MARKER + "3", "XX_\\342\\352\\356\\364\\373_XX" 
               };
@@ -75,7 +75,9 @@
 
     /**
      * TODO test disabled for now, fails due (probably) do different PDF
-     * encoding when custom font is used
+     * encoding when custom font is used.
+     * TODO This should be tested using PDFBox. If PDFBox can extract the text correctly,
+     * everything is fine. The tests here are too unstable.
      * 
      * @throws Exception
      *             checkstyle wants a comment here, even a silly one



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