Added compression filters for PDF renderer. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193888 13f79535-47bb-0310-9956-ffa450edef68pull/32/head
@@ -8,4 +8,22 @@ | |||
<value>Fop 0.16.0 dev</value> | |||
</entry> | |||
</configuration> | |||
<!-- 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> |
@@ -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(); |
@@ -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()); |
@@ -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); | |||
} | |||
/** |
@@ -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(); |
@@ -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(); |
@@ -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()); |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -96,6 +96,6 @@ public abstract class PDFAction extends PDFObject { | |||
* | |||
* @return the PDF string | |||
*/ | |||
abstract public String toPDF(); | |||
abstract public byte[] toPDF(); | |||
} |
@@ -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 |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -375,9 +375,9 @@ public class PDFColor extends PDFPathPaint { | |||
} | |||
String toPDF() | |||
byte[] toPDF() | |||
{ | |||
return (""); | |||
return (new byte[0]); | |||
} //end of toPDF | |||
} |
@@ -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){ |
@@ -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 |
@@ -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 |
@@ -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 <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); | |||
} |
@@ -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(); | |||
} | |||
/** |
@@ -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(); | |||
} | |||
/** |
@@ -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()); | |||
} | |||
} |
@@ -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 |
@@ -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(); | |||
} | |||
@@ -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(); | |||
} | |||
} |
@@ -84,8 +84,8 @@ public class PDFInternalLink extends PDFAction { | |||
* | |||
* @return an empty string | |||
*/ | |||
public String toPDF() { | |||
return ""; | |||
public byte[] toPDF() { | |||
return new byte[0]; | |||
} | |||
} |
@@ -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 |
@@ -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(); | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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 ""; | |||
} | |||
} | |||
} |
@@ -84,8 +84,8 @@ public class PDFUri extends PDFAction { | |||
* | |||
* @return an empty string | |||
*/ | |||
public String toPDF() { | |||
return ""; | |||
public byte[] toPDF() { | |||
return new byte[0]; | |||
} | |||
} |
@@ -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"; |
@@ -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); |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
/** |
@@ -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>"); |