]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Changed output from Writer to OutputStream to allow for binary output.
authorKelly Campbell <kellyc@apache.org>
Mon, 18 Dec 2000 02:28:40 +0000 (02:28 +0000)
committerKelly Campbell <kellyc@apache.org>
Mon, 18 Dec 2000 02:28:40 +0000 (02:28 +0000)
Added compression filters for PDF renderer.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193888 13f79535-47bb-0310-9956-ffa450edef68

44 files changed:
conf/config.xml
lib/Fop.class
lib/Fop.java
src/org/apache/fop/apps/CommandLine.java
src/org/apache/fop/apps/Driver.java
src/org/apache/fop/apps/PrintCommandLine.java
src/org/apache/fop/apps/XTCommandLine.java
src/org/apache/fop/apps/XalanCommandLine.java
src/org/apache/fop/layout/hyphenation/Hyphenator.java
src/org/apache/fop/pdf/ASCII85Filter.java [new file with mode: 0644]
src/org/apache/fop/pdf/ASCIIHexFilter.java [new file with mode: 0644]
src/org/apache/fop/pdf/FlateFilter.java [new file with mode: 0644]
src/org/apache/fop/pdf/PDFAction.java
src/org/apache/fop/pdf/PDFAnnotList.java
src/org/apache/fop/pdf/PDFArray.java
src/org/apache/fop/pdf/PDFBinaryStream.java [deleted file]
src/org/apache/fop/pdf/PDFColor.java
src/org/apache/fop/pdf/PDFDocument.java
src/org/apache/fop/pdf/PDFEncoding.java
src/org/apache/fop/pdf/PDFFileSpec.java
src/org/apache/fop/pdf/PDFFilter.java
src/org/apache/fop/pdf/PDFFont.java
src/org/apache/fop/pdf/PDFFontDescriptor.java
src/org/apache/fop/pdf/PDFFunction.java
src/org/apache/fop/pdf/PDFGoTo.java
src/org/apache/fop/pdf/PDFGoToRemote.java
src/org/apache/fop/pdf/PDFInfo.java
src/org/apache/fop/pdf/PDFInternalLink.java
src/org/apache/fop/pdf/PDFLink.java
src/org/apache/fop/pdf/PDFObject.java
src/org/apache/fop/pdf/PDFPage.java
src/org/apache/fop/pdf/PDFPages.java
src/org/apache/fop/pdf/PDFPattern.java
src/org/apache/fop/pdf/PDFRectangle.java
src/org/apache/fop/pdf/PDFResources.java
src/org/apache/fop/pdf/PDFRoot.java
src/org/apache/fop/pdf/PDFShading.java
src/org/apache/fop/pdf/PDFStream.java
src/org/apache/fop/pdf/PDFUri.java
src/org/apache/fop/pdf/PDFXObject.java
src/org/apache/fop/render/Renderer.java
src/org/apache/fop/render/awt/AWTRenderer.java
src/org/apache/fop/render/pdf/PDFRenderer.java
src/org/apache/fop/render/xml/XMLRenderer.java

index 076b7ca7ded081fa29aa0b9e33baecabb1daecb6..d0243ed012be69cce4b001992b2851e51b32d721 100644 (file)
@@ -8,4 +8,22 @@
     <value>Fop 0.16.0 dev</value>
   </entry>
 
-</configuration>
\ No newline at end of file
+  <!-- stream-filter-list provides the default filters that are applied to all
+       stream objects within the PDF file. These are normally used for 
+       compression -->
+  <entry role="pdf">
+    <key>stream-filter-list</key>
+    <list>
+      <!-- provides compression using zlib flate (default is on)-->
+      <value>flate</value>
+      
+      <!-- encodes binary data into printable ascii characters (default off)
+           This provides about a 4:5 expansion of data size -->
+      <!-- <value>ascii-85</value> -->
+
+      <!-- encodes binary data with hex representation (default off)
+           This filter is not recommended as it doubles the data size -->
+      <!-- <value>ascii-hex</value> -->
+    </list>
+  </entry>
+</configuration>
index d48961ea4f018bb8c21868db64fe233247085037..3efe0e708d9f8fa979b64481425a95c4df9b0078 100644 (file)
Binary files a/lib/Fop.class and b/lib/Fop.class differ
index 4a67db973fe4d235edaf5a3b77495b600df95079..d304cc3ed1bf52971f8276525454cba8c8b9eca4 100644 (file)
@@ -61,12 +61,7 @@ import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
 // Java
-import java.io.FileReader;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.io.FileNotFoundException;
+import java.io.*;
 import java.net.URL;
 
 // FOP
@@ -200,7 +195,7 @@ public class Fop {
                 driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
                 driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
                 driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
-                driver.setWriter(new PrintWriter(new FileWriter(pdffile)));
+                driver.setOutputStream(new FileOutputStream(pdffile));
                 driver.buildFOTree(parser, fileInputSource(fofile));
                 driver.format();
                 driver.render();
index 021b70cbaa5fb2e191bad5bd4b87f00786c1df7d..e8b0889d87f7f86ea9ee8e08345baa2011f66ad9 100644 (file)
@@ -59,14 +59,8 @@ import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
 // Java
-import java.io.FileReader;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.io.FileNotFoundException;
+import java.io.*;
 import java.net.URL;
-import java.io.InputStream;
 
 
 // FOP
@@ -176,7 +170,7 @@ public class CommandLine {
             driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
             driver.buildFOTree(parser, fileInputSource(foFile));
             driver.format();
-            driver.setWriter(new PrintWriter(new FileWriter(pdfFile)));
+           driver.setOutputStream(new FileOutputStream(pdfFile));
             driver.render();
         } catch (Exception e) {
             MessageHandler.errorln("FATAL ERROR: " + e.getMessage());
index f76b1786c366c38a4b627bd6940378727f07f8f2..e9a86c9b46dea25c99d20fb89f2e64f83e89f97b 100644 (file)
@@ -77,10 +77,8 @@ import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
 // Java
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.File;
+import java.io.*;
+
 
 /**
  * <P>Primary class that drives overall FOP process.
@@ -114,7 +112,7 @@ import java.io.File;
  *   driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
  *   driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
  *   driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
- *   driver.setWriter(new PrintWriter(new FileWriter(args[1])));
+ *   driver.setOutputStream(new FileOutputStream(args[1]));
  *   driver.buildFOTree(parser, fileInputSource(args[0]));
  *   driver.format();
  *   driver.render();
@@ -131,8 +129,8 @@ public class Driver {
     /** the renderer to use to output the area tree */
     protected Renderer renderer;
 
-    /** the PrintWriter to use to output the results of the renderer */
-    protected PrintWriter writer;
+    /** the stream to use to output the results of the renderer */
+    protected OutputStream stream;
 
     /** If true, full error stacks are reported */
     protected boolean errorDump = false;
@@ -421,13 +419,12 @@ public class Driver {
 
     }
 
-
     /**
-        * set the PrintWriter to use to output the result of the Renderer
-        * (if applicable)
-        */
-    public void setWriter(PrintWriter writer) {
-        this.writer = writer;
+       * set the OutputStream to use to output the result of the Renderer
+       * (if applicable)
+       */
+    public void setOutputStream(OutputStream stream) {
+        this.stream = stream;
     }
 
     /**
@@ -447,7 +444,7 @@ public class Driver {
         * render the area tree to the output form
         */
     public void render() throws IOException, FOPException {
-        this.renderer.render(areaTree, this.writer);
+        this.renderer.render(areaTree, this.stream);
     }
 
     /**
index 124e0f0eb4e0d1fab638636c0063d53a45ddc076..199568d133dbf778307ab2a0b03ebba888fbb997 100755 (executable)
@@ -14,7 +14,7 @@ import org.xml.sax.SAXParseException;
 
 import java.awt.Graphics;
 import java.awt.print.*;
-import java.io.PrintWriter;
+import java.io.OutputStream;
 import java.io.IOException;
 import java.util.Vector;
 
@@ -142,7 +142,7 @@ public class PrintCommandLine extends CommandLine {
       }
     }
 
-    public void render(AreaTree areaTree, PrintWriter writer) throws IOException {
+    public void render(AreaTree areaTree, OutputStream stream) throws IOException {
       tree = areaTree;
       if (endNumber == -1) {
         endNumber = tree.getPages().size();
index b11aed2d4445f19fcb70edadae519c54452efe69..863f7836c6e7d049892ababed7ccc6c56f0d8d02 100644 (file)
@@ -67,12 +67,7 @@ import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
 // Java
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.io.FileNotFoundException;
+import java.io.*;
 import java.net.URL;
 
 /**
@@ -121,7 +116,7 @@ public class XTCommandLine {
            driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
            driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
            driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
-           driver.setWriter(new PrintWriter(new FileWriter(args[2])));
+           driver.setOutputStream(new FileOutputStream(args[2]));
            driver.buildFOTree(xslProcessor, fileInputSource(args[0]));
            driver.format();
            driver.render();
index fc6ad454e4fcb565bd2acdb3cd5bc68eb5a3a743..a126e305c8cdb79df86e9b30c418a9e012e647f5 100644 (file)
@@ -60,16 +60,7 @@ import org.xml.sax.SAXParseException;
 
 
 // Java
-import java.io.FileReader;
-import java.io.File;
-import java.io.StringWriter;
-import java.io.StringReader;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.FileNotFoundException;
+import java.io.*;
 import java.net.URL;
 
 // Xalan
@@ -305,9 +296,8 @@ public class XalanCommandLine {
             driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
             driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
             driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
-            PrintWriter pwriter = new PrintWriter(
-                                    new BufferedWriter(new FileWriter(pdfFile)));
-            driver.setWriter(pwriter);
+            OutputStream stream = new BufferedOutputStream(new FileOutputStream(pdfFile));
+            driver.setOutputStream(stream);
             driver.buildFOTree(parser, new InputSource(reader));
             reader.close();
             driver.format();
@@ -315,8 +305,8 @@ public class XalanCommandLine {
             if (usefile) {
                 new File (pdfFile + ".tmp").delete();
             }
-            pwriter.flush();
-            pwriter.close();
+            stream.flush();
+            stream.close();
         }
         catch (Exception e) {
             MessageHandler.errorln("FATAL ERROR: " + e.getMessage());
index 73231724d36db5bfdab1095546c1b023a7907e10..137707d63eed7910be1c1c64898a730094d89f58 100644 (file)
@@ -91,7 +91,7 @@ public class Hyphenator {
 
         HyphenationTree hTree = getFopHyphenationTree(key);
         if (hTree == null) {
-            String hyphenDir = StandardConfiguration.getStringValue("hyphenation-dir");
+            String hyphenDir = Configuration.getStringValue("hyphenation-dir");
             if (hyphenDir != null){
                 hTree = getUserHyphenationTree(key,hyphenDir);
             }
diff --git a/src/org/apache/fop/pdf/ASCII85Filter.java b/src/org/apache/fop/pdf/ASCII85Filter.java
new file mode 100644 (file)
index 0000000..13368c4
--- /dev/null
@@ -0,0 +1,185 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.pdf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class ASCII85Filter extends PDFFilter
+{
+    private static final char ASCII85_ZERO = 'z';
+    private static final char ASCII85_START = '!';
+    private static final String ASCII85_EOD   = "~>";
+    
+    private static final long base85_4 = 85;
+    private static final long base85_3 = base85_4 * base85_4;
+    private static final long base85_2 = base85_3 * base85_4;
+    private static final long base85_1 = base85_2 * base85_4;
+    
+
+   
+    public String getName() 
+    {
+       return "/ASCII85Decode";
+    }
+    
+    public String getDecodeParms() 
+    {
+       return null;
+    }
+
+    public byte[] encode(byte[] data) 
+    {
+       
+       StringBuffer buffer = new StringBuffer();
+       int i;
+       int total = 0;
+       int diff = 0;
+       
+       for (i = 0; i+3 < data.length; i+=4) {
+           byte b1 = data[i];
+           byte b2 = data[i+1];
+           byte b3 = data[i+2];
+           byte b4 = data[i+3];
+           
+           long val = ((b1 << 24) & 0xff000000L) 
+               + ((b2 << 16) & 0xff0000L) 
+               + ((b3 << 8) & 0xff00L) 
+               + (b4 & 0xffL);
+           String conv = convertLong(val);
+           
+           buffer.append(conv);
+
+           
+       }
+
+       
+       if (i < data.length) {
+           int n = data.length - i;
+           byte b1,b2,b3,b4;
+           b1 = data[i++];
+           if (i < data.length) {
+               b2 = data[i++];
+           }
+           else {
+               b2 = 0;
+           }
+           if (i < data.length) {
+               b3 = data[i++];
+           }
+           else {
+               b3 = 0;
+           }
+           // assert i = data.length
+           b4 = 0;
+          
+           long val = ((b1 << 24) & 0xff000000L) 
+               + ((b2 << 16) & 0xff0000L) 
+               + ((b3 << 8) & 0xff00L) 
+               + (b4 & 0xffL);
+           String converted = convertLong(val);
+           
+           // special rule for handling zeros at the end
+           if (val == 0) {
+               converted = "!!!!!";
+           }
+           buffer.append(converted.substring(0,n));
+       }
+       buffer.append(ASCII85_EOD);
+       return buffer.toString().getBytes();
+       
+    }
+    
+    private String convertLong(long val) 
+    {
+       val = val & 0xffffffff;
+       if (val < 0) {
+           val = -val;
+       }
+       
+       if (val == 0) {
+           return new Character(ASCII85_ZERO).toString();
+       }
+       else {
+           byte c1 = (byte)((val / base85_1) & 0xFF);
+           byte c2 = (byte)(((val - (c1 * base85_1)) / base85_2) & 0xFF);
+           byte c3 = (byte)(((val 
+                      - (c1 * base85_1) 
+                      - (c2 * base85_2) 
+                      ) / base85_3) & 0xFF);
+           byte c4 = (byte)(((val 
+                      - (c1 * base85_1) 
+                      - (c2 * base85_2)
+                      - (c3 * base85_3)
+                      ) / base85_4) & 0xFF);
+           byte c5 = (byte)(((val 
+                      - (c1 * base85_1) 
+                      - (c2 * base85_2)
+                      - (c3 * base85_3)
+                      - (c4 * base85_4))) & 0xFF);
+                       
+           char[] ret = {(char)(c1+ASCII85_START),
+                          (char)(c2+ASCII85_START),
+                          (char)(c3+ASCII85_START),
+                          (char)(c4+ASCII85_START),
+                          (char)(c5+ASCII85_START)};
+           for (int i = 0; i< ret.length; i++) {
+               if (ret[i] < 33 || ret[i] > 117) {
+                   System.out.println("illegal char value "+new Integer(ret[i]));
+               }
+           }
+           
+           return new String(ret);
+                   
+       }       
+    }
+
+}
diff --git a/src/org/apache/fop/pdf/ASCIIHexFilter.java b/src/org/apache/fop/pdf/ASCIIHexFilter.java
new file mode 100644 (file)
index 0000000..e1a1031
--- /dev/null
@@ -0,0 +1,86 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.pdf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class ASCIIHexFilter extends PDFFilter
+{
+    private static final String ASCIIHEX_EOD = ">";
+    
+
+    public String getName() 
+    {
+       return "/ASCIIHexDecode";
+    }
+    
+    public String getDecodeParms() 
+    {
+       return null;
+    }
+
+    public byte[] encode(byte[] data) 
+    {
+       
+       StringBuffer buffer = new StringBuffer();
+       for (int i = 0; i < data.length; i++) {
+           int val = (int) (data[i] & 0xFF);
+           if (val < 16) buffer.append("0");
+           buffer.append(Integer.toHexString(val));
+       }
+       buffer.append(ASCIIHEX_EOD);
+       
+       return buffer.toString().getBytes();
+       
+    }
+    
+}
diff --git a/src/org/apache/fop/pdf/FlateFilter.java b/src/org/apache/fop/pdf/FlateFilter.java
new file mode 100644 (file)
index 0000000..d3994ae
--- /dev/null
@@ -0,0 +1,201 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.pdf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.DeflaterOutputStream;
+
+/**
+ * A filter to deflate a stream. Note that the attributes for
+ * prediction, colors, bitsPerComponent, and columns are not supported
+ * when this filter is used to handle the data compression. They are
+ * only valid for externally encoded data such as that from a graphics
+ * file. 
+ */
+public class FlateFilter extends PDFFilter {
+
+    public static final int PREDICTION_NONE = 1;
+    public static final int PREDICTION_TIFF2 = 2;
+    public static final int PREDICTION_PNG_NONE = 10;
+    public static final int PREDICTION_PNG_SUB  = 11;
+    public static final int PREDICTION_PNG_UP   = 12;
+    public static final int PREDICTION_PNG_AVG  = 13;
+    public static final int PREDICTION_PNG_PAETH= 14;
+    public static final int PREDICTION_PNG_OPT  = 15;
+   
+    
+    private int _predictor = PREDICTION_NONE;
+    private int _colors;
+    private int _bitsPerComponent;
+    private int _columns;
+    
+    public String getName() 
+    {
+       return "/FlateDecode";
+    }
+    
+    public String getDecodeParms() 
+    {
+       if (_predictor > PREDICTION_NONE) {
+           StringBuffer sb = new StringBuffer();
+           sb.append("<< /Predictor ");
+           sb.append(_predictor);
+           if (_colors > 0) {
+               sb.append(" /Colors "+_colors);
+           }
+           if (_bitsPerComponent > 0) {
+               sb.append(" /BitsPerComponent "+_bitsPerComponent);
+           }
+           if (_columns > 0) {
+               sb.append(" /Columns "+_columns);
+           }
+           sb.append(" >> ");
+           return sb.toString();
+       }
+       return null;
+    }
+    
+
+    /**
+     * Encode the given data and return it. Note: a side effect of
+     * this method is that it resets the prediction to the default
+     * because these attributes are not supported. So the DecodeParms
+     * should be retrieved after calling this method.  
+     */
+    public byte[] encode(byte[] data) 
+    {
+       ByteArrayOutputStream outArrayStream = new ByteArrayOutputStream();
+       _predictor = PREDICTION_NONE;
+       try {
+           DeflaterOutputStream compressedStream = 
+               new DeflaterOutputStream(outArrayStream);
+           compressedStream.write(data, 0, data.length);
+           compressedStream.flush();
+           compressedStream.close();
+       }
+       catch (IOException e) {
+           org.apache.fop.messaging.MessageHandler.error("Fatal error: "+
+                                                         e.getMessage());
+           e.printStackTrace();
+       }
+       
+       return outArrayStream.toByteArray();
+    }
+    
+    public void setPredictor(int predictor)
+       throws PDFFilterException
+    {
+       _predictor = predictor;
+       
+    }
+
+    public int getPredictor() 
+    {
+       return _predictor;
+    }
+    
+    
+    public void setColors(int colors)
+       throws PDFFilterException
+    {
+       if (_predictor != PREDICTION_NONE) {
+           _colors = colors;
+       }
+       else {
+           throw new PDFFilterException
+               ("Prediction must not be PREDICTION_NONE in order to set Colors");
+       }
+    }
+
+    public int getColors() 
+    {
+       return _colors;
+    }
+    
+
+    public void setBitsPerComponent(int bits) 
+       throws PDFFilterException
+    {
+       if (_predictor != PREDICTION_NONE) {
+           _bitsPerComponent = bits;
+       }
+       else {
+           throw new PDFFilterException
+               ("Prediction must not be PREDICTION_NONE in order to set bitsPerComponent");
+       }
+    }
+
+    public int getBitsPerComponent() 
+    {
+       return _bitsPerComponent;
+    }
+    
+
+    public void setColumns(int columns)
+       throws PDFFilterException
+    {
+       if (_predictor != PREDICTION_NONE) {
+           _columns = columns;
+       }
+       else {
+           throw new PDFFilterException
+               ("Prediction must not be PREDICTION_NONE in order to set Columns");
+       }
+    }
+
+    public int getColumns() 
+    {
+       return _columns;
+    }
+    
+
+}
index 238f936d80b998b988d2e95beaa764f56de0dcc4..cd6e83bde1c72228fa3592d59ae49e1dc37485c9 100644 (file)
@@ -96,6 +96,6 @@ public abstract class PDFAction extends PDFObject {
      *
      * @return the PDF string
      */
-    abstract public String toPDF();
+    abstract public byte[] toPDF();
 
     }
index 66bc794492e24fb48a02b5517fe4321647e343b7..058fd0cc60558c8749e75fd54a4a206b729d0628 100644 (file)
@@ -103,7 +103,7 @@ public class PDFAnnotList extends PDFObject {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        StringBuffer p = new StringBuffer(this.number + " "
                                          + this.generation
                                          + " obj\n[\n"); 
@@ -112,7 +112,7 @@ public class PDFAnnotList extends PDFObject {
                          links.elementAt(i)).referencePDF() + "\n");
        }
        p = p.append("]\nendobj\n");
-       return p.toString();
+       return p.toString().getBytes();
     }
 
     /* example
index 012bd906f7d84fbc54d83eaa8b83bf0d05580cb9..da9a193819e9bd3dad9b14e52926562a089b29a2 100644 (file)
@@ -77,7 +77,7 @@ public class PDFArray extends PDFObject {
         *
         * @return the PDF
         */
-       public String toPDF() {
+       public byte[] toPDF() {
                StringBuffer p = new StringBuffer();
                p.append(this.number + " " + this.generation + " obj\n[");
                for (int i = 0; i < values.length; i++) {
@@ -85,6 +85,6 @@ public class PDFArray extends PDFObject {
                        p.append(values[i]);
                }
                p.append("]\nendobj\n");
-               return p.toString();
+               return p.toString().getBytes();
        }
 }
diff --git a/src/org/apache/fop/pdf/PDFBinaryStream.java b/src/org/apache/fop/pdf/PDFBinaryStream.java
deleted file mode 100644 (file)
index 3383bfc..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-
- ============================================================================
-                                                The Apache Software License, Version 1.1
- ============================================================================
-        Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
- Redistribution and use in source and binary forms, with or without modifica-
- tion, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must        retain the above copyright      notice,
-        this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
-        this list of conditions and the following disclaimer in the documentation
-        and/or other materials provided with the distribution.
- 3. The end-user documentation included with the redistribution, if any, must
-        include  the following  acknowledgment:        "This product includes  software
-        developed      by the  Apache Software Foundation      (http://www.apache.org/)."
-        Alternately, this      acknowledgment may      appear in the software itself,  if
-        and wherever such third-party acknowledgments normally appear.
- 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
-        endorse  or promote  products derived  from this       software without        prior
-        written permission. For written permission, please contact
-        apache@apache.org.
- 5. Products  derived from this software may not  be called "Apache", nor may
-        "Apache" appear        in their name,  without prior written permission  of the
-        Apache Software Foundation.
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS  FOR A PARTICULAR     PURPOSE ARE  DISCLAIMED.        IN NO  EVENT SHALL      THE
- APACHE SOFTWARE       FOUNDATION      OR ITS CONTRIBUTORS     BE LIABLE FOR   ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL,        EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION) HOWEVER CAUSED AND ON
- ANY   THEORY OF LIABILITY,  WHETHER  IN CONTRACT,     STRICT LIABILITY,  OR TORT
- (INCLUDING  NEGLIGENCE OR     OTHERWISE) ARISING IN   ANY WAY OUT OF THE      USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- This software consists of voluntary contributions made  by many individuals
- on  behalf of the Apache Software     Foundation and was      originally created by
- James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
- Software Foundation, please see <http://www.apache.org/>.
- */
-
-//Author:       Eric SCHAEFFER
-//Description:  Encode a binary stream using PDF filters
-
-package org.apache.fop.pdf;
-
-import org.apache.fop.datatypes.ColorSpace;
-
-// Java
-import java.util.Vector;
-import java.lang.reflect.Array;
-
-import java.io.*;
-
-// compression
-import java.util.zip.Deflater;
-
-public class PDFBinaryStream {
-
-       private byte[] m_data = null;
-       private int m_dataSize = 0;
-       private Vector m_filters = null;
-
-       public PDFBinaryStream() {
-               m_filters = new Vector();
-       }
-
-       public void setData(byte[] data) {
-               this.m_data = data;
-               this.m_dataSize = java.lang.reflect.Array.getLength(this.m_data);
-       }
-
-       public void encode(PDFFilter filter) throws PDFFilterException {
-               if (this.m_data == null) throw new PDFFilterException("no data to encode");
-
-               int filterType = filter.getType();
-               if (filterType == PDFFilter.FLATE_DECODE) {
-                       Deflater compressor = new Deflater();
-
-                       // PDFFilter properties ?
-                       compressor.setLevel(Deflater.DEFAULT_COMPRESSION);
-                       compressor.setStrategy(Deflater.DEFAULT_STRATEGY);
-
-                       compressor.setInput(m_data);
-                       compressor.finish();
-                       byte[] compMap = new byte[this.m_dataSize];
-                       int compSize = compressor.deflate(compMap);
-                       compressor.end();
-
-                       this.m_data = new byte[compSize];
-                       for (int i = 0; i < compSize; i++) {
-                               this.m_data[i] = compMap[i];
-                       }
-                       this.m_dataSize = compSize;
-//                     this.m_data = compMap;
-//                     this.m_dataSize = java.lang.reflect.Array.getLength(this.m_data);
-//             } else if (filterType == PDFFilter.LZW_DECODE) {
-               } else if (filterType == PDFFilter.ASCII_HEX_DECODE) {
-                       StringBuffer buffer = new StringBuffer();
-                       for (int i = 0; i < this.m_dataSize; i++) {
-                               int val = (int) (this.m_data[i] & 0xFF);
-                               if (val < 16) buffer.append("0");
-                               buffer.append(Integer.toHexString(val));
-//// TEST ////
-/*
-buffer.append(" ");
-if (i % 75 == 0) buffer.append("\n");
-*/
-//// TEST ////
-                       }
-                       this.m_data = buffer.toString().getBytes();
-                       this.m_dataSize = java.lang.reflect.Array.getLength(this.m_data);
-               } else {
-                       throw new PDFFilterException("filter not supported");
-               }
-
-               this.m_filters.addElement(filter);
-       }
-
-       public String toPDF() {
-               StringBuffer buffer = new StringBuffer();
-
-               buffer.append("<<\n/Length ");
-               buffer.append(this.m_dataSize);
-               buffer.append("\n");
-               buffer.append("/Filter [");
-               for (int i = this.m_filters.size(); i > 0; i--) {
-                       PDFFilter filter = (PDFFilter) this.m_filters.elementAt(i - 1);
-                       buffer.append(filter.toPDF());
-                       if (i > 1) buffer.append(" ");
-               }
-               buffer.append("]\n");
-               buffer.append(">>\n");
-
-               buffer.append("stream\n");
-               buffer.append(this.m_data);
-               buffer.append("\nendstream\n");
-
-               return buffer.toString();
-       }
-
-       public String getPDFDictionary() {
-               StringBuffer buffer = new StringBuffer();
-
-               buffer.append("/Length ");
-//// TEST ////
-               buffer.append(this.m_dataSize);
-//             buffer.append(this.m_dataSize + 1);
-//// TEST ////
-               buffer.append("\n");
-               if (this.m_filters.size() > 0) {
-                       buffer.append("/Filter [");
-                       for (int i = this.m_filters.size(); i > 0; i--) {
-                               PDFFilter filter = (PDFFilter) this.m_filters.elementAt(i - 1);
-                               buffer.append(filter.toPDF());
-                               if (i > 1) buffer.append(" ");
-                       }
-                       buffer.append("]\n");
-               }
-
-               return buffer.toString();
-       }
-
-       public String getPDFStream() {
-               StringBuffer buffer = new StringBuffer();
-
-               buffer.append("stream\n");
-               buffer.append(this.m_data);
-//// TEST ////
-//             buffer.append(">");
-//// TEST ////
-               buffer.append("\nendstream\n");
-
-               return buffer.toString();
-       }
-
-       public int outputPDFStream(PrintWriter writer) throws IOException {
-               int length = 0;
-               String p;
-
-               p = new String("stream\n");
-               writer.write(p);
-               length += p.length();
-
-/*
-               for (int i = 0; i < this.m_dataSize; i++) {
-                       writer.write(Byte.toString(this.m_data[i]));
-               }
-*/
-               writer.write(new String(this.m_data));
-               length += this.m_dataSize;
-//// TEST ////
-//             writer.write(">");
-//             length += (new String(">")).length();
-//// TEST ////
-
-               p = new String("\nendstream\n");
-               writer.write(p);
-               length += p.length();
-
-               return length;
-       }
-
-}
index 66bb33b7526967b64b8cd4e2deaddf5f0cfd96d8..a7e58cb1b364d23e107d23fe890e155a46c0c2ed 100644 (file)
@@ -375,9 +375,9 @@ public class PDFColor extends PDFPathPaint {
                
        }
        
-       String toPDF()
+       byte[] toPDF()
        {
-               return ("");
+               return (new byte[0]);
 
        } //end of toPDF
 }
index a259238a26fd1cfbe7f0a07d9561a324b5387d1a..c69556046e9904c6bcef862a296f1bcd308f61ef 100644 (file)
@@ -67,7 +67,7 @@ import org.apache.fop.layout.FontMetric;
 import org.apache.fop.layout.FontDescriptor;
 // Java
 import java.io.IOException;
-import java.io.PrintWriter;
+import java.io.OutputStream;
 import java.util.Vector;
 import java.util.Hashtable;
 import java.util.Enumeration;
@@ -914,10 +914,13 @@ public class PDFDocument {
         /* create a PDFStream with the next object number and add it
     
            to the list of objects */
-        PDFStream obj = new PDFStream(++this.objectcount);
+       PDFStream obj = new PDFStream(++this.objectcount);
+       obj.addDefaultFilters();
+               
         this.objects.addElement(obj);
         return obj;
     }
+           
 
     /**
      * make an annotation list object
@@ -945,13 +948,13 @@ public class PDFDocument {
     /**
      * write the entire document out
      *
-     * @param writer the PrinterWriter to output the document to
+     * @param writer the OutputStream to output the document to
      */
-    public void output(PrintWriter writer) throws IOException {
+    public void output(OutputStream stream) throws IOException {
 
         /* output the header and increment the character position by
            the header's length */
-        this.position += outputHeader(writer);
+        this.position += outputHeader(stream);
 
         this.resources.setXObjects(xObjects);
 
@@ -967,36 +970,44 @@ public class PDFDocument {
 
             /* output the object and increment the character position
                by the object's length */
-            this.position += object.output(writer);
+            this.position += object.output(stream);
         }
 
         /* output the xref table and increment the character position
            by the table's length */
-        this.position += outputXref(writer);
+        this.position += outputXref(stream);
 
-        /* output the trailer and flush the Writer */
-        outputTrailer(writer);
-        writer.flush();
+        /* output the trailer and flush the Stream */
+        outputTrailer(stream);
+        stream.flush();
     }
 
     /**
      * write the PDF header
      *
-     * @param writer the PrintWriter to write the header to
-     * @return the number of characters written
+     * @param stream the OutputStream to write the header to
+     * @return the number of bytes written
      */
-    protected int outputHeader(PrintWriter writer) throws IOException {
-        String pdf = "%PDF-" + this.pdfVersion + "\n";
-        writer.write(pdf);
-        return pdf.length();
+    protected int outputHeader(OutputStream stream) throws IOException {
+       int length = 0;
+       byte[] pdf = ("%PDF-" + this.pdfVersion + "\n").getBytes();
+       stream.write(pdf);
+       length += pdf.length;
+       
+       // output a binary comment as recommended by the PDF spec (3.4.1)
+       byte[] bin = {(byte)'%', (byte)0xAA, (byte)0xAB, (byte)0xAC, (byte)0xAD, (byte)'\n'};
+       stream.write(bin);
+       length += bin.length;
+       
+       return length;
     }
 
     /**
      * write the trailer
      *
-     * @param writer the PrintWriter to write the trailer to
+     * @param stream the OutputStream to write the trailer to
      */
-    protected void outputTrailer(PrintWriter writer) throws IOException {
+    protected void outputTrailer(OutputStream stream) throws IOException {
 
         /* construct the trailer */
         String pdf = "trailer\n<<\n/Size " + (this.objectcount+1)
@@ -1006,16 +1017,16 @@ public class PDFDocument {
         + "\n%%EOF\n";
 
         /* write the trailer */
-        writer.write(pdf);
+        stream.write(pdf.getBytes());
     }
 
     /**
      * write the xref table
      *
-     * @param writer the PrintWriter to write the xref table to
+     * @param stream the OutputStream to write the xref table to
      * @return the number of characters written
      */
-    private int outputXref(PrintWriter writer) throws IOException {
+    private int outputXref(OutputStream stream) throws IOException {
 
         /* remember position of xref table */
         this.xref = this.position;
@@ -1037,8 +1048,9 @@ public class PDFDocument {
         }
 
         /* write the xref table and return the character length */
-        writer.write(pdf.toString());
-        return pdf.length();
+       byte[] pdfBytes = pdf.toString().getBytes();
+       stream.write(pdfBytes);
+        return pdfBytes.length;
     }    
 
     public void setIDReferences(IDReferences idReferences){
index f5ed80a47ef808d6849edb4dddfeb034a3e8114c..ad937f417cb2093915c392e16b3880cd4dcc839a 100644 (file)
@@ -115,7 +115,7 @@ public class PDFEncoding extends PDFObject {
         *
         * @return the PDF
         */
-       public String toPDF() {
+       public byte[] toPDF() {
                StringBuffer p = new StringBuffer();
                p.append(this.number + " " + this.generation
                                + " obj\n<< /Type /Encoding");
@@ -137,7 +137,7 @@ public class PDFEncoding extends PDFObject {
                        p.append(" ]");
                }
                p.append(" >>\nendobj\n");
-               return p.toString();
+               return p.toString().getBytes();
        }
        /* example (p. 214)
                25 0 obj
index f588b9c4023460eee9b1292fc04c83f53a5a5def..fdfd0ea1ccf4b5bf6b264486364c8444ff7e1910 100644 (file)
@@ -79,12 +79,12 @@ public class PDFFileSpec extends PDFObject {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        String p = new String(this.number + " " + this.generation +
                              " obj\n<<\n/Type /FileSpec\n" +
                              "/F (" + this.filename + ")\n" + 
                              ">>\nendobj\n"); 
-       return p;
+       return p.getBytes();
     }
 
     /* example
index b0adc29c022dcdd0cdf2211794af27e6d01d00c2..5783b829b7b0c272f7bf9a987fb126dd48fccdec 100644 (file)
-/*
+/*-- $Id$ -- 
 
  ============================================================================
-                                                The Apache Software License, Version 1.1
+                   The Apache Software License, Version 1.1
  ============================================================================
  
-        Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  
  Redistribution and use in source and binary forms, with or without modifica-
  tion, are permitted provided that the following conditions are met:
  
- 1. Redistributions of source code must        retain the above copyright      notice,
-        this list of conditions and the following disclaimer.
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
  
  2. Redistributions in binary form must reproduce the above copyright notice,
-        this list of conditions and the following disclaimer in the documentation
-        and/or other materials provided with the distribution.
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
  
  3. The end-user documentation included with the redistribution, if any, must
-        include  the following  acknowledgment:        "This product includes  software
-        developed      by the  Apache Software Foundation      (http://www.apache.org/)."
-        Alternately, this      acknowledgment may      appear in the software itself,  if
-        and wherever such third-party acknowledgments normally appear.
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
  
  4. The names "Fop" and  "Apache Software Foundation"  must not be used to
-        endorse  or promote  products derived  from this       software without        prior
-        written permission. For written permission, please contact
-        apache@apache.org.
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
  
  5. Products  derived from this software may not  be called "Apache", nor may
-        "Apache" appear        in their name,  without prior written permission  of the
-        Apache Software Foundation.
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
  
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS  FOR A PARTICULAR     PURPOSE ARE  DISCLAIMED.        IN NO  EVENT SHALL      THE
- APACHE SOFTWARE       FOUNDATION      OR ITS CONTRIBUTORS     BE LIABLE FOR   ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL,        EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION) HOWEVER CAUSED AND ON
- ANY   THEORY OF LIABILITY,  WHETHER  IN CONTRACT,     STRICT LIABILITY,  OR TORT
- (INCLUDING  NEGLIGENCE OR     OTHERWISE) ARISING IN   ANY WAY OUT OF THE      USE OF
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
- This software consists of voluntary contributions made  by many individuals
- on  behalf of the Apache Software     Foundation and was      originally created by
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
  James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
  Software Foundation, please see <http://www.apache.org/>.
  
-*/
-
-//Author:       Eric SCHAEFFER
-//Description:  represent a PDF filter object
-
-package org.apache.fop.pdf;
-
-public class PDFFilter {
-       public static int ASCII_HEX_DECODE = 1;
-       public static int ASCII_85_DECODE = 2;
-       public static int LZW_DECODE = 3;
-       public static int RUN_LENGTH_DECODE = 4;
-       public static int CCITT_FAX_DECODE = 5;
-       public static int DCT_DECODE = 6;
-       public static int FLATE_DECODE = 7;
-
-       // Filter type
-       private int m_filterType;
-
-       // Properties
-
-       // LZW - Flat
-       private Integer m_predictor = null;
-       // LZW - Flat - CCITT
-       private Integer m_columns = null;
-       // LZW - Flat
-       private Integer m_colors = null;
-       // LZW - Flat
-       private Integer m_bitsPerComponent = null;
-       // LZW
-       private Integer m_earlyChange = null;
-       // CCITT
-       private Integer m_k = null;
-       // CCITT
-       private Boolean m_endOfLine = null;
-       // CCITT
-       private Boolean m_encodedByteAlign = null;
-       // CCITT
-       private Integer m_rows = null;
-       // CCITT
-       private Boolean m_endOfBlock = null;
-       // CCITT
-       private Boolean m_blackls1 = null;
-       // CCITT
-       private Integer m_damagedRowsBeforeError = null;
-
-       public PDFFilter(int filter) throws PDFFilterException {
-               if (    (filter != ASCII_HEX_DECODE) &&
-                               (filter != ASCII_85_DECODE) &&
-                               (filter != LZW_DECODE) &&
-                               (filter != RUN_LENGTH_DECODE) &&
-                               (filter != CCITT_FAX_DECODE) &&
-                               (filter != DCT_DECODE) &&
-                               (filter != FLATE_DECODE)
-                               ) {
-                       throw new PDFFilterException("Filter type not supported");
-               }
-               this.m_filterType = filter;
-       }
-
-       public int getType() {
-               return this.m_filterType;
-       }
-
-       public void setPredictor(Integer value) throws PDFFilterException {
-               if ((this.m_filterType != LZW_DECODE) && (this.m_filterType != FLATE_DECODE)) {
-                       throw new PDFFilterException("No Predictor property for this filter");
-               }
 
-               this.m_predictor = value;
-       }
-
-       public Integer getPredictor() throws PDFFilterException {
-               if ((this.m_filterType != LZW_DECODE) && (this.m_filterType != FLATE_DECODE)) {
-                       throw new PDFFilterException("No Predictor property for this filter");
-               }
-
-               return this.m_predictor;
-       }
-
-// ... etc ... 
-
-       public String toPDF() {
-               String pdf = null;
-/*
-       public static int DCT_DECODE = 6;
 */
-               if (this.m_filterType == ASCII_HEX_DECODE) {
-                       pdf = "/ASCIIHexDecode";
-               } else if (this.m_filterType == ASCII_85_DECODE) {
-                       pdf = "/ASCI85Decode";
-               } else if (this.m_filterType == LZW_DECODE) {
-                       StringBuffer buffer = new StringBuffer();
-                       buffer.append("/LZWDecode");
-
-                       if (this.m_predictor != null) {
-                               buffer.append(" /Predictor ");
-                               buffer.append(this.m_predictor);
-                       }
-                       if (this.m_columns != null) {
-                               buffer.append(" /Columns ");
-                               buffer.append(this.m_columns);
-                       }
-                       if (this.m_colors != null) {
-                               buffer.append(" /Colors ");
-                               buffer.append(this.m_colors);
-                       }
-                       if (this.m_bitsPerComponent != null) {
-                               buffer.append(" /BitsPerComponent ");
-                               buffer.append(this.m_bitsPerComponent);
-                       }
-                       if (this.m_earlyChange != null) {
-                               buffer.append(" /EarlyChange ");
-                               buffer.append(this.m_earlyChange);
-                       }
-
-                       pdf = buffer.toString();
-               } else if (this.m_filterType == FLATE_DECODE) {
-                       StringBuffer buffer = new StringBuffer();
-                       buffer.append("/FlateDecode");
 
-                       if (this.m_predictor != null) {
-                               buffer.append(" /Predictor ");
-                               buffer.append(this.m_predictor);
-                       }
-                       if (this.m_columns != null) {
-                               buffer.append(" /Columns ");
-                               buffer.append(this.m_columns);
-                       }
-                       if (this.m_colors != null) {
-                               buffer.append(" /Colors ");
-                               buffer.append(this.m_colors);
-                       }
-                       if (this.m_bitsPerComponent != null) {
-                               buffer.append(" /BitsPerComponent ");
-                               buffer.append(this.m_bitsPerComponent);
-                       }
 
-                       pdf = buffer.toString();
-               } else if (this.m_filterType == RUN_LENGTH_DECODE) {
-                       pdf = "/RunLengthDecode";
-               } else if (this.m_filterType == CCITT_FAX_DECODE) {
-                       StringBuffer buffer = new StringBuffer();
-                       buffer.append("/CCITTFaxDecode");
-
-                       if (this.m_k != null) {
-                               buffer.append(" /K ");
-                               buffer.append(this.m_k);
-                       }
-                       if (this.m_endOfLine != null) {
-                               buffer.append(" /EndOfLine ");
-                               buffer.append(this.m_endOfLine);
-                       }
-                       if (this.m_encodedByteAlign != null) {
-                               buffer.append(" /EncodedByteAlign ");
-                               buffer.append(this.m_encodedByteAlign);
-                       }
-                       if (this.m_columns != null) {
-                               buffer.append(" /Columns ");
-                               buffer.append(this.m_columns);
-                       }
-                       if (this.m_rows != null) {
-                               buffer.append(" /Rows ");
-                               buffer.append(this.m_rows);
-                       }
-                       if (this.m_endOfBlock != null) {
-                               buffer.append(" /EndOfBlock ");
-                               buffer.append(this.m_endOfBlock);
-                       }
-                       if (this.m_blackls1 != null) {
-                               buffer.append(" /Blackls1 ");
-                               buffer.append(this.m_blackls1);
-                       }
-                       if (this.m_damagedRowsBeforeError != null) {
-                               buffer.append(" /DamagedRowsBeforeError ");
-                               buffer.append(this.m_damagedRowsBeforeError);
-                       }
-
-                       pdf = buffer.toString();
-               } else if (this.m_filterType == DCT_DECODE) {
-                       pdf = "/DCTDecode";
-               }
+//Author:       Eric SCHAEFFER, Kelly A. Campbell
+//Description:  represent a PDF filter object
 
-               return pdf;
-       }
+package org.apache.fop.pdf;
 
+public abstract class PDFFilter {
+    /* These are no longer needed, but are here as a reminder about what 
+       filters pdf supports.
+
+       public static final int ASCII_HEX_DECODE = 1;
+       public static final int ASCII_85_DECODE = 2;
+       public static final int LZW_DECODE = 3;
+       public static final int RUN_LENGTH_DECODE = 4;
+       public static final int CCITT_FAX_DECODE = 5;
+       public static final int DCT_DECODE = 6;
+       public static final int FLATE_DECODE = 7;
+
+    */
+
+    /** Marker to know if this filter has already been applied to the data */
+    private boolean _applied = false;
+    
+    public boolean isApplied() 
+    {
+       return _applied;
+    }
+    
+    /**
+     * Set the applied attribute to the given value. This attribute is
+     * used to determine if this filter is just a placeholder for the
+     * decodeparms and dictionary entries, or if the filter needs to
+     * actually encode the data. For example if the raw data is copied
+     * out of an image file in it's compressed format, then this
+     * should be set to true and the filter options should be set to
+     * those which the raw data was encoded with.  
+     */
+    public void setApplied(boolean b) 
+    {
+       _applied = b;
+    }
+    
+    
+    /** return a PDF string representation of the filter, e.g. /FlateDecode */
+    public abstract String getName();
+    
+    /** return a parameter dictionary for this filter, or null */
+    public abstract String getDecodeParms();
+     
+    /** encode the given data with the filter */
+    public abstract byte[] encode(byte[] data);
+    
+    
 }
index a1226bb1948489327f0c95611676a72696a8c46e..9b11c5f02054f40535a97b96a6c4ef5d9e482507 100644 (file)
@@ -209,7 +209,7 @@ public class PDFFont extends PDFObject {
      *
      * @return the PDF
      */
-    public String toPDF() {
+    public byte[] toPDF() {
         StringBuffer p = new StringBuffer();
         p.append(this.number + " " + this.generation
                 + " obj\n<< /Type /Font\n/Subtype /" + TYPE_NAMES[this.subtype]
@@ -226,7 +226,7 @@ public class PDFFont extends PDFObject {
         }
         fillInPDF(p);
         p.append(" >>\nendobj\n");
-        return p.toString();
+        return p.toString().getBytes();
     }
 
     /**
index 3f9f38d4524285829cd252c0bebd52a9eef0c982..23c6a60f9dd5b82b85b9e5ad659557f5817b4074 100644 (file)
@@ -139,7 +139,7 @@ public class PDFFontDescriptor extends PDFObject {
         *
         * @return the PDF
         */
-    public String toPDF() {
+    public byte[] toPDF() {
                StringBuffer p = new StringBuffer(
                                this.number + " " + this.generation
                                + " obj\n<< /Type /FontDescriptor"
@@ -188,7 +188,7 @@ public class PDFFontDescriptor extends PDFObject {
                // CID optional field
                fillInPDF(p);
                p.append("\n >>\nendobj\n");
-               return p.toString();
+               return p.toString().getBytes();
     }
 
        /**
index 674c8676153c30e096f03a3167c4591d4f1071bb..848166fe53ab01df510ef955225c6b5b2e49a5f7 100644 (file)
@@ -373,7 +373,7 @@ public class PDFFunction extends PDFObject {
          * 
          * @return the PDF string.
          */ 
-       public String toPDF() {
+       public byte[] toPDF() {
                int vectorSize=0;
                int numberOfFunctions=0;
                int tempInt=0;
@@ -752,7 +752,7 @@ public class PDFFunction extends PDFObject {
                        
                }
                
-               return (p.toString());
+               return (p.toString().getBytes());
                
        }
 }
index 0a8c1aae3ca341a81be547b9c984953e0a75eb1a..60862d0248f1b8f476e95e80d1d969d880bb89c5 100644 (file)
@@ -119,12 +119,12 @@ public class PDFGoTo extends PDFObject {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        String p = new String(this.number + " " + this.generation +
                              " obj\n<<\n/S /GoTo\n" +
                              "/D [" + this.pageReference + " /XYZ "+xPosition+" "+yPosition+" null]\n" + 
                              ">>\nendobj\n"); 
-       return p;
+       return p.getBytes();
     }
 
     /* example
index 917aa43805b0b5a24f2ca75f6b9d007cb4811462..9164186f2fe98def941e38a93a3aa7f1fc15460f 100644 (file)
@@ -88,14 +88,14 @@ public class PDFGoToRemote extends PDFAction {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        String p = new String(this.number + " " + this.generation +
                              " obj\n" +
                              "<<\n/S /GoToR\n" +
                              "/F " + pdfFileSpec.referencePDF() + "\n" +
                              "/D [ 0 /XYZ null null null ]" +
                              " \n>>\nendobj\n"); 
-       return p;
+       return p.getBytes();
     }
 
     
index 89f8b3ec75d558fd14fc4c9c028b0bf3e78598fd..ad9aba808d0d18b73cfd0555a72d9ef636210076 100644 (file)
@@ -85,10 +85,10 @@ public class PDFInfo extends PDFObject {
      *
      * @return the PDF
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        String p = this.number + " " + this.generation
            + " obj\n<< /Type /Info\n/Producer (" + this.producer
            + ") >>\nendobj\n";
-       return p;
+       return p.getBytes();
     }
 }
index f4405464cc7450f770df0afc68c35f5322e36503..d715b91c304c595eefb7472c1f58dc55dba447de 100644 (file)
@@ -84,8 +84,8 @@ public class PDFInternalLink extends PDFAction {
      *
      * @return an empty string
      */
-    public String toPDF() {    
-       return "";
+    public byte[] toPDF() {    
+       return new byte[0];
     } 
     
 }
index 2fc56e67515d5ce948a1b9cdbb7d2b6922eb0675..b8caaae860736f4c0c7222b375b20552671a4ff7 100644 (file)
@@ -93,7 +93,7 @@ public class PDFLink extends PDFObject {
      *
      * @return the PDF
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        String p = this.number + " " + this.generation + " obj\n" +
            "<< /Type /Annot\n" +
            "/Subtype /Link\n" +
@@ -103,7 +103,7 @@ public class PDFLink extends PDFObject {
            "/Border [ 0 0 0 ]\n" +
            "/A " + this.action.getAction() + "\n" +
            "/H /I\n>>\nendobj\n";
-       return p;
+       return p.getBytes();
     }
 
     /* example
index 3bf9ab6e7570f7f5f89cfea5de8ffd01c4228878..573923a6f202892413936de10c1760ef5c423b37 100644 (file)
@@ -52,7 +52,7 @@ package org.apache.fop.pdf;
 
 // Java
 import java.io.IOException;
-import java.io.PrintWriter;
+import java.io.OutputStream;
 
 /**
  * generic PDF object.
@@ -89,13 +89,13 @@ public abstract class PDFObject {
     /**
      * write the PDF represention of this object
      *
-     * @param writer the PrintWriter to write the PDF to
-     * @return the number of characters written
+     * @param stream the stream to write the PDF to
+     * @return the number of bytes written
      */
-    protected int output(PrintWriter writer) throws IOException {
-       String pdf = this.toPDF();
-       writer.write(pdf);
-       return pdf.length();
+    protected int output(OutputStream stream) throws IOException {
+       byte[] pdf = this.toPDF();
+       stream.write(pdf);
+       return pdf.length;
     }
 
     /**
@@ -113,5 +113,5 @@ public abstract class PDFObject {
      *
      * @return PDF string
      */
-    abstract String toPDF();
+    abstract byte[] toPDF();
 }
index c3cfc632693dc9696ff803cc12208f6f6b569407..e6838c1fd09aeddffd3f47a12b07bcf4e8511595 100644 (file)
@@ -138,7 +138,7 @@ public class PDFPage extends PDFObject {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        StringBuffer sb = new StringBuffer();
 
        sb = sb.append(this.number + " " + this.generation + " obj\n" +
@@ -155,6 +155,6 @@ public class PDFPage extends PDFObject {
 
        sb = sb.append(">>\nendobj\n");
 
-       return sb.toString();
+       return sb.toString().getBytes();
     }
 }
index b707660dcb86f97378876dd038638ed0d065514b..3c099dacb2507eb1a7517efc1a043da235c1869d 100644 (file)
@@ -116,7 +116,7 @@ public class PDFPages extends PDFObject {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        StringBuffer p = new StringBuffer(this.number + " "
                                          + this.generation
                                          + " obj\n<< /Type /Pages\n/Count " 
@@ -125,6 +125,6 @@ public class PDFPages extends PDFObject {
            p = p.append(((PDFObject)kids.elementAt(i)).referencePDF() + " ");
        }
        p = p.append("] >>\nendobj\n");
-       return p.toString();
+       return p.toString().getBytes();
     }
 }
index a5b9d5f1a088a76e61cbed5724f5a0ec63bcb1f1..02055358e60aad3c8f27e1d8743eccafd86c9fca 100644 (file)
@@ -241,7 +241,7 @@ public class PDFPattern extends PDFPathPaint {
          *
          * @return the PDF string.
          */
-       public String toPDF() {
+       public byte[] toPDF() {
 
 
                int vectorSize=0;
@@ -357,7 +357,7 @@ public class PDFPattern extends PDFPathPaint {
 
                
 
-               return (p.toString());
+               return (p.toString().getBytes());
 
        }
 }
index 5c5a563d6d907ec8e5fc9deb250baa8f8b7cdaf8..d0efca90a832b031a81e5c9c06e0a23d755d14aa 100644 (file)
@@ -97,7 +97,7 @@ public class PDFRectangle {
         *
         * @return the PDF
         */
-    public String toPDF() {
-               return " [" + llx + " " + lly + " " + urx + " " + ury + "] ";
+    public byte[] toPDF() {
+               return (" [" + llx + " " + lly + " " + urx + " " + ury + "] ").getBytes();
        }
 }
index 30ee840ddfd66e15ab98b85f6a145d169cdd0fdd..b4612b7041d75405697c2e448a3201e97fbe9364 100644 (file)
@@ -107,7 +107,7 @@ public class PDFResources extends PDFObject {
      *
      * @return the PDF
      */
-       public String toPDF() {
+       public byte[] toPDF() {
                StringBuffer p = new StringBuffer(this.number + " "
                                                + this.generation
                                                + " obj\n<< \n");
@@ -187,6 +187,6 @@ public class PDFResources extends PDFObject {
 
                p = p.append(">> \nendobj\n");
 
-               return p.toString();
+               return p.toString().getBytes();
        }    
 }
index a1f309a31d2353ec03f38d3c85b5029618c9144f..92a8a78399567fa7677adf91a2c0eaeb1efd1cd8 100644 (file)
@@ -94,10 +94,10 @@ public class PDFRoot extends PDFObject {
      *
      * @return the PDF string
      */
-    public String toPDF() {
+    public byte[] toPDF() {
        String p = this.number + " " + this.generation
            + " obj\n<< /Type /Catalog\n/Pages " 
            + this.rootPages.referencePDF() + " >>\nendobj\n";
-       return p;
+       return p.getBytes();
     }
 }
index 948b9279849af7220155779b27eca03fb200c8d5..a9aeea1cf180202066e7497b1da244195bf43f77 100644 (file)
@@ -349,7 +349,7 @@ public class PDFShading extends PDFObject {
          * 
          * @return the PDF string.
          */ 
-       public String toPDF() {
+       public byte[] toPDF() {
                int vectorSize;
                int tempInt;
                StringBuffer p = new StringBuffer();
@@ -591,6 +591,6 @@ public class PDFShading extends PDFObject {
 
                p.append(">> \nendobj\n");
        
-               return(p.toString());
+               return(p.toString().getBytes());
        }
 }
index f1e1ca76f5194aa85bac6bc964308418e3ad583f..4ac8b75e2ac863b5e59a4b99aba3f151915dd3cb 100644 (file)
  */
 package org.apache.fop.pdf;
 
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.Vector;
+import java.util.Enumeration;
+import org.apache.fop.configuration.Configuration;
+import org.apache.fop.messaging.MessageHandler;
+
 /**
  * class representing a PDF stream.
  * 
@@ -61,8 +69,11 @@ package org.apache.fop.pdf;
 public class PDFStream extends PDFObject {
 
     /** the stream of PDF commands */
-    protected StringBuffer data = new StringBuffer();
+    private ByteArrayOutputStream _data;
 
+    /** the filters that should be applied */
+    private Vector _filters;
+    
     /**
      * create an empty stream object
      *
@@ -70,6 +81,8 @@ public class PDFStream extends PDFObject {
      */
     public PDFStream(int number) {
        super(number);
+       _data = new ByteArrayOutputStream();
+       _filters = new Vector();
     }
 
     /**
@@ -78,8 +91,71 @@ public class PDFStream extends PDFObject {
      * @param s the string of PDF to add
      */
     public void add(String s) {
-       this.data = this.data.append(s);
+       try {
+           _data.write(s.getBytes());
+       }
+       catch (IOException ex) {
+           ex.printStackTrace();
+       }
+       
+    }
+
+    /**
+     * Add a filter for compression of the stream. Filters are
+     * applied in the order they are added. This should always be a 
+     * new instance of the particular filter of choice. The applied
+     * flag in the filter is marked true after it has been applied to the
+     * data.
+     */
+    public void addFilter(PDFFilter filter) 
+    {
+       if (filter != null) {
+           _filters.add(filter);
+       }
+
+    }
+
+    public void addFilter(String filterType) 
+    {
+       if (filterType.equals("flate")) {
+           addFilter(new FlateFilter());
+       }
+       else if (filterType.equals("ascii-85")) {
+           addFilter(new ASCII85Filter());
+       }
+       else if (filterType.equals("ascii-hex")) {
+           addFilter(new ASCIIHexFilter());
+       }
+       else {
+           MessageHandler.errorln("Unsupported filter type in stream-filter-list: "+filterType);
+       }
+    }
+    
+
+    protected void addDefaultFilters() 
+    {
+       Vector filters = Configuration.getListValue("stream-filter-list",
+                                                   Configuration.PDF);
+       if (filters == null) {
+           // try getting it as a String
+           String filter = Configuration.getStringValue("stream-filter-list",
+                                                        Configuration.PDF);
+           if (filter == null) {
+               // built-in default to flate
+               addFilter(new FlateFilter());
+           }
+           else {
+               addFilter(filter);
+           }
+       }
+       else {
+           for (int i=0; i < filters.size(); i++) {
+               String v = (String)filters.elementAt(i);
+               addFilter(v);
+           }
+       }
     }
+    
 
     /**
      * append an array of xRGB pixels, ASCII Hex Encoding it first
@@ -89,39 +165,204 @@ public class PDFStream extends PDFObject {
      * @param height the height of the image in pixels
      */
     public void addImageArray(int[] pixels, int width, int height) {
-       for (int i = 0; i < height; i++) {
-           for (int j = 0; j < width; j++) {
-               int p = pixels[i * width + j];
-               int r = (p >> 16) & 0xFF;
-               int g = (p >>  8) & 0xFF;
-               int b = (p      ) & 0xFF;
-               if (r < 16) {
-                   this.data = this.data.append(0);
-               }
-               this.data = this.data.append(Integer.toHexString(r));
-               if (g < 16) {
-                   this.data = this.data.append(0);
+       try {
+           for (int i = 0; i < height; i++) {
+               for (int j = 0; j < width; j++) {
+                   int p = pixels[i * width + j];
+                   int r = (p >> 16) & 0xFF;
+                   int g = (p >>  8) & 0xFF;
+                   int b = (p      ) & 0xFF;
+                   if (r < 16) {
+                       _data.write('0');
+                   }
+                   _data.write(Integer.toHexString(r).getBytes());
+                   if (g < 16) {
+                       _data.write('0');
+                   }
+                   _data.write(Integer.toHexString(g).getBytes());
+                   if (b < 16) {
+                       _data.write('0');
+                   }
+                   _data.write(Integer.toHexString(b).getBytes());
+                   _data.write(' ');
                }
-               this.data = this.data.append(Integer.toHexString(g));
-               if (b < 16) {
-                   this.data = this.data.append(0);
-               }
-               this.data = this.data.append(Integer.toHexString(b));
-               this.data = this.data.append(" ");
            }
+           _data.write(">\n".getBytes());
+       }
+       catch (IOException ex) {
+           ex.printStackTrace();
        }
-       this.data = this.data.append(">\n");
+       
     }
 
+    public void setData(byte[] data) 
+       throws IOException
+    {
+       _data.reset();
+       _data.write(data);
+    }
+    
+    public byte[] getData() 
+    {
+       return _data.toByteArray();
+    }
+    
+    public int getDataLength() 
+    {
+       return _data.size();
+    }
+    
+    
+
     /**
      * represent as PDF.
      *
      * @return the PDF string.
      */ 
-    public String toPDF() {
-       String p = this.number + " " + this.generation
-           + " obj\n<< /Length " + (this.data.length()+1)
-           + " >>\nstream\n" + this.data + "\nendstream\nendobj\n";
-       return p;
+    /*
+    public byte[] toPDF() {
+       byte[] d = _data.toByteArray();
+       ByteArrayOutputStream s = new ByteArrayOutputStream();
+               String p = this.number + " " + this.generation
+           + " obj\n<< /Length " + (d.length+1)
+           + " >>\nstream\n";
+       s.write(p.getBytes());
+       s.write(d);
+       s.write("\nendstream\nendobj\n".getBytes());
+       return s.toByteArray();
+    }
+    */
+    public byte[] toPDF() {
+       throw new UnsupportedOperationException();
+    }
+    
+
+    // overload the base object method so we don't have to copy 
+    // byte arrays around so much
+    protected int output(OutputStream stream) throws IOException 
+    {
+       int length = 0;
+       String filterEntry = applyFilters();
+       byte[] p = (this.number + " " + this.generation
+                   + " obj\n<< /Length " + (_data.size()+1) + " "
+                   + filterEntry + " >>\n").getBytes();
+       
+       stream.write(p);
+       length += p.length;
+       length += outputStreamData(stream);
+       p = "endobj\n".getBytes();
+       stream.write(p);
+       length += p.length;
+       return length;
+       
+    }
+
+    /**
+     * Output just the stream data enclosed by stream/endstream markers
+     */
+    protected int outputStreamData(OutputStream stream) throws IOException
+    {
+       int length = 0;
+       byte[] p ="stream\n".getBytes();
+       stream.write(p);
+       length += p.length;
+       _data.writeTo(stream);
+       length += _data.size();
+       p = "\nendstream\n".getBytes();
+       stream.write(p);
+       length += p.length;
+       return length;
+       
     }
+    
+    
+    /**
+     * Apply the filters to the data
+     * in the order given and return the /Filter and /DecodeParms
+     * entries for the stream dictionary. If the filters have already
+     * been applied to the data (either externally, or internally)
+     * then the dictionary entries are built and returned.
+     */
+    protected String applyFilters() throws IOException
+    {
+       if (_filters.size() > 0) {
+           Vector names = new Vector();
+           Vector parms = new Vector();
+           
+           // run the filters
+           Enumeration e = _filters.elements();
+           while (e.hasMoreElements()) {
+               PDFFilter filter = (PDFFilter)e.nextElement();
+               // apply the filter encoding if neccessary
+               if (!filter.isApplied()) {
+                   byte[] tmp = filter.encode(_data.toByteArray());
+                   _data.reset();
+                   _data.write(tmp);
+                   filter.setApplied(true);
+               }
+               // place the names in our local vector in reverse order
+               names.add(0, filter.getName()); 
+               parms.add(0, filter.getDecodeParms());
+           }
+                   
+           // now build up the filter entries for the dictionary
+           return buildFilterEntries(names) + buildDecodeParms(parms);
+       }    
+       return "";
+       
+    }
+    
+    private String buildFilterEntries(Vector names) 
+    {
+       StringBuffer sb = new StringBuffer();
+       sb.append("/Filter ");
+       if (names.size() > 1) {
+           sb.append("[ ");
+       }
+       Enumeration e = names.elements();
+       while (e.hasMoreElements()) {
+           sb.append((String)e.nextElement());
+           sb.append(" ");
+       }
+       if (names.size() > 1) {
+           sb.append("]");
+       }
+       sb.append("\n");
+       return sb.toString();
+    }
+
+    private String buildDecodeParms(Vector parms) 
+    {
+       StringBuffer sb = new StringBuffer();
+       boolean needParmsEntry = false;
+       sb.append("/DecodeParms ");
+       
+       if (parms.size() > 1) {
+           sb.append("[ ");
+       }
+       Enumeration e = parms.elements();
+       while (e.hasMoreElements()) {
+           String s = (String)e.nextElement();
+           if (s != null) {
+               sb.append(s);
+               needParmsEntry = true;
+           }
+           else {
+               sb.append("null");
+           }
+           sb.append(" ");
+       }
+       if (parms.size() > 1) {
+           sb.append("]");
+       }
+       sb.append("\n");
+       if (needParmsEntry) {
+           return sb.toString();
+       }
+       else {
+           return "";
+       }
+    }
+    
+
 }
index 4c8cf703939de1eface45ade82749bb24773646a..9709fa6848c68f27b3d38d08ac98165716ccbf12 100644 (file)
@@ -84,8 +84,8 @@ public class PDFUri extends PDFAction {
      *
      * @return an empty string
      */
-    public String toPDF() {    
-       return "";
+    public byte[] toPDF() {    
+       return new byte[0];
     } 
     
 }
index 039f28ea19169f03a9b4ae0193841b52fb7485b4..0009c75fea55a70abae9a027c40f7470fc0526d9 100644 (file)
@@ -56,7 +56,7 @@ package org.apache.fop.pdf;
 // Java
 import java.io.IOException;
 import org.apache.fop.messaging.MessageHandler;
-import java.io.PrintWriter;
+import java.io.OutputStream;
 
 // FOP
 import org.apache.fop.datatypes.ColorSpace;
@@ -98,21 +98,24 @@ public class PDFXObject extends PDFObject {
     /**
      * represent as PDF
      */
-    protected int output(PrintWriter writer) throws IOException {
+    protected int output(OutputStream stream) throws IOException {
        int length=0;
        int i=0;
        int x,y;
 
        try {
-               PDFBinaryStream imgStream = new PDFBinaryStream();
+           // delegate the stream work to PDFStream
+           PDFStream imgStream = new PDFStream(0);
+           
                imgStream.setData(fopimage.getBitmaps());
-               imgStream.encode(new PDFFilter(PDFFilter.FLATE_DECODE));
-               imgStream.encode(new PDFFilter(PDFFilter.ASCII_HEX_DECODE));
+               imgStream.addFilter(new FlateFilter());
+               String dictEntries = imgStream.applyFilters();
 
                String p = this.number + " " + this.generation + " obj\n";
                p = p + "<</Type /XObject\n";
                p = p + "/Subtype /Image\n";
                p = p + "/Name /Im" + Xnum + "\n";
+               p = p + "/Length " + imgStream.getDataLength();
                p = p + "/Width " + fopimage.getWidth() + "\n";
                p = p + "/Height " + fopimage.getHeight() + "\n";
                p = p + "/BitsPerComponent " + fopimage.getBitsPerPixel() + "\n";
@@ -122,30 +125,30 @@ public class PDFXObject extends PDFObject {
                        PDFColor transp = fopimage.getTransparentColor();
                        p = p + "/Mask [" + transp.red255() + " " + transp.red255() + " " + transp.green255() + " " + transp.green255() + " " + transp.blue255() + " " + transp.blue255() + "]\n";
                }
-               p = p + imgStream.getPDFDictionary();
+               p = p + dictEntries;
                p = p + ">>\n";
 
                // don't know if it's the good place (other objects can have references to it)
                fopimage.close();
 
                // push the pdf dictionary on the writer
-               writer.write(p);
-               length += p.length();
+               byte[] pdfBytes = p.getBytes();
+               stream.write(pdfBytes);
+               length += pdfBytes.length;
                // push all the image data on  the writer and takes care of length for trailer
-               length += imgStream.outputPDFStream(writer);
+               length += imgStream.outputStreamData(stream);
 
-               p = "endobj\n";
-               writer.write(p);
-               length += p.length();
+               pdfBytes = ("endobj\n").getBytes();
+               stream.write(pdfBytes);
+               length += pdfBytes.length;
        } catch (FopImageException imgex) {
-MessageHandler.errorln("Error in XObject : " + imgex.getMessage());
-       } catch (PDFFilterException filterex) {
-MessageHandler.errorln("Error in XObject : " + filterex.getMessage());
+           MessageHandler.errorln("Error in XObject : " + imgex.getMessage());
        }
+
        return length;
     }
     
-    String toPDF() {
+    byte[] toPDF() {
 /* Not used any more
        String p = this.number + " " + this.generation + " obj\n";
        p = p + "<</Type /XObject\n";
index 8afac542dcf84d8fc35ff2fa0e05e03fa507c4e9..b78ca0d7abfe9af619d48c68abbfb0bac168000a 100644 (file)
@@ -57,7 +57,7 @@ import org.apache.fop.apps.FOPException;
 import org.apache.fop.layout.*;
 
 // Java
-import java.io.PrintWriter;
+import java.io.OutputStream;
 import java.io.IOException;
 
 /**
@@ -75,7 +75,7 @@ public interface Renderer {
     public void setProducer(String producer);
 
     /** render the given area tree to the given writer */
-    public void render(AreaTree areaTree, PrintWriter writer) throws IOException, FOPException;
+    public void render(AreaTree areaTree, OutputStream stream) throws IOException, FOPException;
  
     /** render the given area container */
     public void renderAreaContainer(AreaContainer area);
index ce0559d77b01d652d83fbf03ca20fefe70802176..a6803c243ff9406471c6c61c810755e5b018469c 100644 (file)
@@ -258,7 +258,7 @@ public class AWTRenderer implements Renderer, Printable, Pageable {
     }
 
     public void render(AreaTree areaTree,
-                       PrintWriter writer) throws IOException {
+                       OutputStream stream) throws IOException {
         tree = areaTree;
         render(areaTree, 0);
     }
index 293e3cf0b9f88d63ac120b3690cce6cf27663c01..ebf79ba88b50afb0b0c51882e0c725ecdd24afa1 100644 (file)
@@ -78,7 +78,7 @@ import org.apache.fop.dom.svg.SVGArea;
 
 // Java
 import java.io.IOException;
-import java.io.PrintWriter;
+import java.io.OutputStream;
 import java.util.Enumeration;
 import java.awt.Rectangle;
 import java.util.Vector;
@@ -160,10 +160,10 @@ public class PDFRenderer implements Renderer {
        * render the areas into PDF
        *
        * @param areaTree the laid-out area tree
-       * @param writer the PrintWriter to write the PDF with
+       * @param stream the OutputStream to write the PDF to
        */
     public void render(AreaTree areaTree,
-                       PrintWriter writer) throws IOException, FOPException {
+                       OutputStream stream) throws IOException, FOPException {
         MessageHandler.logln("rendering areas to PDF");
         idReferences = areaTree.getIDReferences();
         this.pdfResources = this.pdfDoc.getResources();
@@ -181,7 +181,7 @@ public class PDFRenderer implements Renderer {
         }
 
         MessageHandler.logln("writing out PDF");
-        this.pdfDoc.output(writer);
+        this.pdfDoc.output(stream);
     }
 
     /**
index 85b83f45915b9edfe36ddb036be46ffc2cf801e5..6330db0fc4b121ced118a9f2fd5afbfc1515406f 100644 (file)
@@ -64,6 +64,7 @@ import org.apache.fop.fo.properties.LeaderPattern;
 // Java
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.OutputStream;
 import java.util.Enumeration;
 
 /**
@@ -95,10 +96,10 @@ public class XMLRenderer implements Renderer {
      * @param areaTree the laid-out area tree
      * @param writer the PrintWriter to give the XML to
      */
-    public void render(AreaTree areaTree, PrintWriter writer)
+    public void render(AreaTree areaTree, OutputStream stream)
        throws IOException {
        MessageHandler.logln("rendering areas to XML");
-       this.writer = writer;
+       this.writer = new PrintWriter(stream);
        this.writer.write("<?xml version=\"1.0\"?>\n<!-- produced by "
                          + this.producer + " -->\n");
        writeStartTag("<AreaTree>");