From 6fd5d987513c63d6165216bff1a1dc931c881d7f Mon Sep 17 00:00:00 2001 From: Kelly Campbell Date: Mon, 18 Dec 2000 02:28:40 +0000 Subject: [PATCH] Changed output from Writer to OutputStream to allow for binary output. Added compression filters for PDF renderer. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193888 13f79535-47bb-0310-9956-ffa450edef68 --- conf/config.xml | 20 +- lib/Fop.class | Bin 4103 -> 4052 bytes lib/Fop.java | 9 +- src/org/apache/fop/apps/CommandLine.java | 10 +- src/org/apache/fop/apps/Driver.java | 25 +- src/org/apache/fop/apps/PrintCommandLine.java | 4 +- src/org/apache/fop/apps/XTCommandLine.java | 9 +- src/org/apache/fop/apps/XalanCommandLine.java | 20 +- .../fop/layout/hyphenation/Hyphenator.java | 2 +- src/org/apache/fop/pdf/ASCII85Filter.java | 185 +++++++++++ src/org/apache/fop/pdf/ASCIIHexFilter.java | 86 +++++ src/org/apache/fop/pdf/FlateFilter.java | 201 ++++++++++++ src/org/apache/fop/pdf/PDFAction.java | 2 +- src/org/apache/fop/pdf/PDFAnnotList.java | 4 +- src/org/apache/fop/pdf/PDFArray.java | 4 +- src/org/apache/fop/pdf/PDFBinaryStream.java | 214 ------------- src/org/apache/fop/pdf/PDFColor.java | 4 +- src/org/apache/fop/pdf/PDFDocument.java | 58 ++-- src/org/apache/fop/pdf/PDFEncoding.java | 4 +- src/org/apache/fop/pdf/PDFFileSpec.java | 4 +- src/org/apache/fop/pdf/PDFFilter.java | 281 +++++------------ src/org/apache/fop/pdf/PDFFont.java | 4 +- src/org/apache/fop/pdf/PDFFontDescriptor.java | 4 +- src/org/apache/fop/pdf/PDFFunction.java | 4 +- src/org/apache/fop/pdf/PDFGoTo.java | 4 +- src/org/apache/fop/pdf/PDFGoToRemote.java | 4 +- src/org/apache/fop/pdf/PDFInfo.java | 4 +- src/org/apache/fop/pdf/PDFInternalLink.java | 4 +- src/org/apache/fop/pdf/PDFLink.java | 4 +- src/org/apache/fop/pdf/PDFObject.java | 16 +- src/org/apache/fop/pdf/PDFPage.java | 4 +- src/org/apache/fop/pdf/PDFPages.java | 4 +- src/org/apache/fop/pdf/PDFPattern.java | 4 +- src/org/apache/fop/pdf/PDFRectangle.java | 4 +- src/org/apache/fop/pdf/PDFResources.java | 4 +- src/org/apache/fop/pdf/PDFRoot.java | 4 +- src/org/apache/fop/pdf/PDFShading.java | 4 +- src/org/apache/fop/pdf/PDFStream.java | 293 ++++++++++++++++-- src/org/apache/fop/pdf/PDFUri.java | 4 +- src/org/apache/fop/pdf/PDFXObject.java | 35 ++- src/org/apache/fop/render/Renderer.java | 4 +- .../apache/fop/render/awt/AWTRenderer.java | 2 +- .../apache/fop/render/pdf/PDFRenderer.java | 8 +- .../apache/fop/render/xml/XMLRenderer.java | 5 +- 44 files changed, 974 insertions(+), 599 deletions(-) create mode 100644 src/org/apache/fop/pdf/ASCII85Filter.java create mode 100644 src/org/apache/fop/pdf/ASCIIHexFilter.java create mode 100644 src/org/apache/fop/pdf/FlateFilter.java delete mode 100644 src/org/apache/fop/pdf/PDFBinaryStream.java diff --git a/conf/config.xml b/conf/config.xml index 076b7ca7d..d0243ed01 100644 --- a/conf/config.xml +++ b/conf/config.xml @@ -8,4 +8,22 @@ Fop 0.16.0 dev - \ No newline at end of file + + + stream-filter-list + + + flate + + + + + + + + + diff --git a/lib/Fop.class b/lib/Fop.class index d48961ea4f018bb8c21868db64fe233247085037..3efe0e708d9f8fa979b64481425a95c4df9b0078 100644 GIT binary patch delta 1244 zcmZ9L`%_g_6vsd3o_p`!95&EUQ}Kgk+BgIWjs0ZhR5M8y78;>J553aWK#TIDTzn z?C-%5T&D7y$6TT*%we&GC7LHZDyY;fRaAK>qMB-ZFSAhNQA?diJq;FOinwCAW`%ve zQt_l_m14DKjp8XyqaxvvMU#c6HP3jgWt~T2EzerB+2&lYcuw)W<^_*Qyl6pWuA@oO zqS&C>=#g!`O&+;KEo}DKLaWBtv}s&v4B6;)9OT~Je-R~cCzF_bXR@Bqbz2PyWO0#}9m4FeqXw+Bil3^HVR zpJBy_;RDJPhYTNb*zgfY{0z6qJxZA$aR+ZIq0DfMVTbg^B9Ye+t&P-2Vm0-OQNwXg z7{)kh_?T0MK|b*dgVWp+KJ}Y|@zm2c^BKcu47Y}6xSuob-x0dieS}B-#!$I?mM{Es zp=S3>zVfTXIquhdvPVOlxZ`#$iqx_1ReA{GEJXRZz702qMk!r*D z{9t&D1%@B_$?&sn`WNQ;+tkhBUk&FN?j2XRyEkMsL}M2-9kQ}#|CjdS7k*)CA~8p{ z69RH%fP&Z=3Wjm)Tm|QgH$iSk?oduYPLCK44_yd?BJoNo6SSd|B$-VY&dEJM;Qv_f z{L}e_gz50`h4}nS2=1kX1wvSeMh0mG{FP>Ox|Pns6Reavmx@(I8q1hW9eKo<#R?X& znl&`iMib}9_AfiFL75<;;*C%rNaQi7pa(8Z4P@KR3vy$ACo8(?Ogr1_!t;vuFU*BNELb?=zh){@^cWi?l6t71s!M$N+Y589T{j7gw^IyXch9 zQ`aSx?IF%y3G61pe%8sa(@auQ9i&~hw1XiDACa_&*vDb|WbFqzBHmHi^<$i6RJQ0i fzjH!lPdX`_a?&{MWO9axNC%~mMRLl;4)FLt3fC1r delta 1334 zcmZvbTU1q56o$WjHs`FxW=jlI6dwe|(IBYfgAZxusK!XtqEZQvI#h@U!q9_q znuW%{Nb!(nvEpIP5=Bh2RPl&II?D_!*Q{_@Ns~itC9912sNsA}@wnm%&1#3yJZV76 zjAEJMDaF&8H4fS4Ypp{rl?K*1c&yhnYc^;$8un*2n>3ppIm8ytvzq6UxPs>uTQx6e zUNonANwdwQZ!gg7Fh+}}RkPEWFKb>=>{9G@$TJO3W{>gjHH`a=^{Rn31N#;2nhu8p z#5J9YF2!r@(=268?zV6WBK6Voa9&k)*g{uCYJzji8p>RXndNdPg)T)DTBJszmBGe& z)xp}b#$ZiZv^E@7^timvL9f|YnAyuAm&5ca-f(%7km4jeS4o5A9dS|VnUWR?G zeTl)+{IW2+)#r$?*i*A+*r>cUYOz-6zQ z)J3Nm($_BE@U6>z$jrXudzT-~;C^J5w?vH#{N!?uzV=RagFSw5cK&6Ki}@3;DzZqd z4gXzZ_&*WA>z}N+(m}Ov_DAkZ)fXx5T+M zH%`8++gi!G&fkM7=|rdA5ywgQ$C)mBoTM&N6S}xQbw(F%n^bCIjr22tR(|6=w@U}6 z-$jfR+%6N@K?*IT%KtQWHgYq&x;8zjFc}`j>B8VZJw$kP8mrLmcX=IM9u-HB-{sMwv BGI0O^ diff --git a/lib/Fop.java b/lib/Fop.java index 4a67db973..d304cc3ed 100644 --- a/lib/Fop.java +++ b/lib/Fop.java @@ -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(); diff --git a/src/org/apache/fop/apps/CommandLine.java b/src/org/apache/fop/apps/CommandLine.java index 021b70cba..e8b0889d8 100644 --- a/src/org/apache/fop/apps/CommandLine.java +++ b/src/org/apache/fop/apps/CommandLine.java @@ -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()); diff --git a/src/org/apache/fop/apps/Driver.java b/src/org/apache/fop/apps/Driver.java index f76b1786c..e9a86c9b4 100644 --- a/src/org/apache/fop/apps/Driver.java +++ b/src/org/apache/fop/apps/Driver.java @@ -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.*; + /** *

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); } /** diff --git a/src/org/apache/fop/apps/PrintCommandLine.java b/src/org/apache/fop/apps/PrintCommandLine.java index 124e0f0eb..199568d13 100755 --- a/src/org/apache/fop/apps/PrintCommandLine.java +++ b/src/org/apache/fop/apps/PrintCommandLine.java @@ -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(); diff --git a/src/org/apache/fop/apps/XTCommandLine.java b/src/org/apache/fop/apps/XTCommandLine.java index b11aed2d4..863f7836c 100644 --- a/src/org/apache/fop/apps/XTCommandLine.java +++ b/src/org/apache/fop/apps/XTCommandLine.java @@ -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(); diff --git a/src/org/apache/fop/apps/XalanCommandLine.java b/src/org/apache/fop/apps/XalanCommandLine.java index fc6ad454e..a126e305c 100644 --- a/src/org/apache/fop/apps/XalanCommandLine.java +++ b/src/org/apache/fop/apps/XalanCommandLine.java @@ -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()); diff --git a/src/org/apache/fop/layout/hyphenation/Hyphenator.java b/src/org/apache/fop/layout/hyphenation/Hyphenator.java index 73231724d..137707d63 100644 --- a/src/org/apache/fop/layout/hyphenation/Hyphenator.java +++ b/src/org/apache/fop/layout/hyphenation/Hyphenator.java @@ -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 index 000000000..13368c4ee --- /dev/null +++ b/src/org/apache/fop/pdf/ASCII85Filter.java @@ -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 . For more information on the Apache + Software Foundation, please see . + + */ +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 index 000000000..e1a103127 --- /dev/null +++ b/src/org/apache/fop/pdf/ASCIIHexFilter.java @@ -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 . For more information on the Apache + Software Foundation, please see . + + */ +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 index 000000000..d3994aecf --- /dev/null +++ b/src/org/apache/fop/pdf/FlateFilter.java @@ -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 . For more information on the Apache + Software Foundation, please see . + + */ +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; + } + + +} diff --git a/src/org/apache/fop/pdf/PDFAction.java b/src/org/apache/fop/pdf/PDFAction.java index 238f936d8..cd6e83bde 100644 --- a/src/org/apache/fop/pdf/PDFAction.java +++ b/src/org/apache/fop/pdf/PDFAction.java @@ -96,6 +96,6 @@ public abstract class PDFAction extends PDFObject { * * @return the PDF string */ - abstract public String toPDF(); + abstract public byte[] toPDF(); } diff --git a/src/org/apache/fop/pdf/PDFAnnotList.java b/src/org/apache/fop/pdf/PDFAnnotList.java index 66bc79449..058fd0cc6 100644 --- a/src/org/apache/fop/pdf/PDFAnnotList.java +++ b/src/org/apache/fop/pdf/PDFAnnotList.java @@ -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 diff --git a/src/org/apache/fop/pdf/PDFArray.java b/src/org/apache/fop/pdf/PDFArray.java index 012bd906f..da9a19381 100644 --- a/src/org/apache/fop/pdf/PDFArray.java +++ b/src/org/apache/fop/pdf/PDFArray.java @@ -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 index 3383bfc28..000000000 --- a/src/org/apache/fop/pdf/PDFBinaryStream.java +++ /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 . For more information on the Apache - Software Foundation, please see . - - */ - -//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; - } - -} diff --git a/src/org/apache/fop/pdf/PDFColor.java b/src/org/apache/fop/pdf/PDFColor.java index 66bb33b75..a7e58cb1b 100644 --- a/src/org/apache/fop/pdf/PDFColor.java +++ b/src/org/apache/fop/pdf/PDFColor.java @@ -375,9 +375,9 @@ public class PDFColor extends PDFPathPaint { } - String toPDF() + byte[] toPDF() { - return (""); + return (new byte[0]); } //end of toPDF } diff --git a/src/org/apache/fop/pdf/PDFDocument.java b/src/org/apache/fop/pdf/PDFDocument.java index a259238a2..c69556046 100644 --- a/src/org/apache/fop/pdf/PDFDocument.java +++ b/src/org/apache/fop/pdf/PDFDocument.java @@ -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){ diff --git a/src/org/apache/fop/pdf/PDFEncoding.java b/src/org/apache/fop/pdf/PDFEncoding.java index f5ed80a47..ad937f417 100644 --- a/src/org/apache/fop/pdf/PDFEncoding.java +++ b/src/org/apache/fop/pdf/PDFEncoding.java @@ -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 diff --git a/src/org/apache/fop/pdf/PDFFileSpec.java b/src/org/apache/fop/pdf/PDFFileSpec.java index f588b9c40..fdfd0ea1c 100644 --- a/src/org/apache/fop/pdf/PDFFileSpec.java +++ b/src/org/apache/fop/pdf/PDFFileSpec.java @@ -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 diff --git a/src/org/apache/fop/pdf/PDFFilter.java b/src/org/apache/fop/pdf/PDFFilter.java index b0adc29c0..5783b829b 100644 --- a/src/org/apache/fop/pdf/PDFFilter.java +++ b/src/org/apache/fop/pdf/PDFFilter.java @@ -1,236 +1,107 @@ -/* +/*-- $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 . For more information on the Apache Software Foundation, please see . -*/ - -//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); + + + } diff --git a/src/org/apache/fop/pdf/PDFFont.java b/src/org/apache/fop/pdf/PDFFont.java index a1226bb19..9b11c5f02 100644 --- a/src/org/apache/fop/pdf/PDFFont.java +++ b/src/org/apache/fop/pdf/PDFFont.java @@ -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(); } /** diff --git a/src/org/apache/fop/pdf/PDFFontDescriptor.java b/src/org/apache/fop/pdf/PDFFontDescriptor.java index 3f9f38d45..23c6a60f9 100644 --- a/src/org/apache/fop/pdf/PDFFontDescriptor.java +++ b/src/org/apache/fop/pdf/PDFFontDescriptor.java @@ -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(); } /** diff --git a/src/org/apache/fop/pdf/PDFFunction.java b/src/org/apache/fop/pdf/PDFFunction.java index 674c86761..848166fe5 100644 --- a/src/org/apache/fop/pdf/PDFFunction.java +++ b/src/org/apache/fop/pdf/PDFFunction.java @@ -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()); } } diff --git a/src/org/apache/fop/pdf/PDFGoTo.java b/src/org/apache/fop/pdf/PDFGoTo.java index 0a8c1aae3..60862d024 100644 --- a/src/org/apache/fop/pdf/PDFGoTo.java +++ b/src/org/apache/fop/pdf/PDFGoTo.java @@ -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 diff --git a/src/org/apache/fop/pdf/PDFGoToRemote.java b/src/org/apache/fop/pdf/PDFGoToRemote.java index 917aa4380..9164186f2 100644 --- a/src/org/apache/fop/pdf/PDFGoToRemote.java +++ b/src/org/apache/fop/pdf/PDFGoToRemote.java @@ -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(); } diff --git a/src/org/apache/fop/pdf/PDFInfo.java b/src/org/apache/fop/pdf/PDFInfo.java index 89f8b3ec7..ad9aba808 100644 --- a/src/org/apache/fop/pdf/PDFInfo.java +++ b/src/org/apache/fop/pdf/PDFInfo.java @@ -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(); } } diff --git a/src/org/apache/fop/pdf/PDFInternalLink.java b/src/org/apache/fop/pdf/PDFInternalLink.java index f4405464c..d715b91c3 100644 --- a/src/org/apache/fop/pdf/PDFInternalLink.java +++ b/src/org/apache/fop/pdf/PDFInternalLink.java @@ -84,8 +84,8 @@ public class PDFInternalLink extends PDFAction { * * @return an empty string */ - public String toPDF() { - return ""; + public byte[] toPDF() { + return new byte[0]; } } diff --git a/src/org/apache/fop/pdf/PDFLink.java b/src/org/apache/fop/pdf/PDFLink.java index 2fc56e675..b8caaae86 100644 --- a/src/org/apache/fop/pdf/PDFLink.java +++ b/src/org/apache/fop/pdf/PDFLink.java @@ -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 diff --git a/src/org/apache/fop/pdf/PDFObject.java b/src/org/apache/fop/pdf/PDFObject.java index 3bf9ab6e7..573923a6f 100644 --- a/src/org/apache/fop/pdf/PDFObject.java +++ b/src/org/apache/fop/pdf/PDFObject.java @@ -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(); } diff --git a/src/org/apache/fop/pdf/PDFPage.java b/src/org/apache/fop/pdf/PDFPage.java index c3cfc6326..e6838c1fd 100644 --- a/src/org/apache/fop/pdf/PDFPage.java +++ b/src/org/apache/fop/pdf/PDFPage.java @@ -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(); } } diff --git a/src/org/apache/fop/pdf/PDFPages.java b/src/org/apache/fop/pdf/PDFPages.java index b707660dc..3c099dacb 100644 --- a/src/org/apache/fop/pdf/PDFPages.java +++ b/src/org/apache/fop/pdf/PDFPages.java @@ -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(); } } diff --git a/src/org/apache/fop/pdf/PDFPattern.java b/src/org/apache/fop/pdf/PDFPattern.java index a5b9d5f1a..02055358e 100644 --- a/src/org/apache/fop/pdf/PDFPattern.java +++ b/src/org/apache/fop/pdf/PDFPattern.java @@ -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()); } } diff --git a/src/org/apache/fop/pdf/PDFRectangle.java b/src/org/apache/fop/pdf/PDFRectangle.java index 5c5a563d6..d0efca90a 100644 --- a/src/org/apache/fop/pdf/PDFRectangle.java +++ b/src/org/apache/fop/pdf/PDFRectangle.java @@ -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(); } } diff --git a/src/org/apache/fop/pdf/PDFResources.java b/src/org/apache/fop/pdf/PDFResources.java index 30ee840dd..b4612b704 100644 --- a/src/org/apache/fop/pdf/PDFResources.java +++ b/src/org/apache/fop/pdf/PDFResources.java @@ -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(); } } diff --git a/src/org/apache/fop/pdf/PDFRoot.java b/src/org/apache/fop/pdf/PDFRoot.java index a1f309a31..92a8a7839 100644 --- a/src/org/apache/fop/pdf/PDFRoot.java +++ b/src/org/apache/fop/pdf/PDFRoot.java @@ -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(); } } diff --git a/src/org/apache/fop/pdf/PDFShading.java b/src/org/apache/fop/pdf/PDFShading.java index 948b92798..a9aeea1cf 100644 --- a/src/org/apache/fop/pdf/PDFShading.java +++ b/src/org/apache/fop/pdf/PDFShading.java @@ -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()); } } diff --git a/src/org/apache/fop/pdf/PDFStream.java b/src/org/apache/fop/pdf/PDFStream.java index f1e1ca76f..4ac8b75e2 100644 --- a/src/org/apache/fop/pdf/PDFStream.java +++ b/src/org/apache/fop/pdf/PDFStream.java @@ -50,6 +50,14 @@ */ 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 ""; + } + } + + } diff --git a/src/org/apache/fop/pdf/PDFUri.java b/src/org/apache/fop/pdf/PDFUri.java index 4c8cf7039..9709fa684 100644 --- a/src/org/apache/fop/pdf/PDFUri.java +++ b/src/org/apache/fop/pdf/PDFUri.java @@ -84,8 +84,8 @@ public class PDFUri extends PDFAction { * * @return an empty string */ - public String toPDF() { - return ""; + public byte[] toPDF() { + return new byte[0]; } } diff --git a/src/org/apache/fop/pdf/PDFXObject.java b/src/org/apache/fop/pdf/PDFXObject.java index 039f28ea1..0009c75fe 100644 --- a/src/org/apache/fop/pdf/PDFXObject.java +++ b/src/org/apache/fop/pdf/PDFXObject.java @@ -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 + "<>\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 + "<\n\n"); writeStartTag(""); -- 2.39.5