diff options
Diffstat (limited to 'src')
25 files changed, 561 insertions, 453 deletions
diff --git a/src/java/org/apache/fop/pdf/AbstractPDFStream.java b/src/java/org/apache/fop/pdf/AbstractPDFStream.java index 0ade68f89..16190da99 100644 --- a/src/java/org/apache/fop/pdf/AbstractPDFStream.java +++ b/src/java/org/apache/fop/pdf/AbstractPDFStream.java @@ -21,8 +21,10 @@ package org.apache.fop.pdf; import java.io.IOException; import java.io.OutputStream; +import java.io.Writer; import org.apache.commons.io.output.CountingOutputStream; + import org.apache.fop.util.CloseBlockerOutputStream; /** @@ -169,8 +171,12 @@ public abstract class AbstractPDFStream extends PDFDictionary { * {@inheritDoc} */ protected int output(OutputStream stream) throws IOException { - int length = 0; setupFilterList(); + + CountingOutputStream cout = new CountingOutputStream(stream); + Writer writer = PDFDocument.getWriterFor(cout); + writer.write(getObjectID()); + //int length = 0; StreamCache encodedStream = null; PDFNumber refLength = null; @@ -184,38 +190,21 @@ public abstract class AbstractPDFStream extends PDFDictionary { lengthEntry = new Integer(encodedStream.getSize() + 1); } - byte[] p = encode(buildStreamDict(lengthEntry)); - stream.write(p); - length += p.length; + populateStreamDict(lengthEntry); + writeDictionary(cout, writer); //Send encoded stream to target OutputStream + writer.flush(); if (encodedStream == null) { - int bytesWritten = encodeAndWriteStream(stream, refLength); - length += bytesWritten; + encodeAndWriteStream(cout, refLength); } else { - length += outputStreamData(encodedStream, stream); + outputStreamData(encodedStream, cout); encodedStream.clear(); //Encoded stream can now be discarded } - p = encode("\nendobj\n"); - stream.write(p); - length += p.length; - return length; - } - - /** - * Constructs the dictionary for the stream. Override this method if you - * need additional entries. - * @param lengthEntry value for the /Length entry - * @return the newly constructed dictionary - */ - protected String buildStreamDict(Object lengthEntry) { - StringBuffer sb = new StringBuffer(); - sb.append(getObjectID()); - populateStreamDict(lengthEntry); - - writeDictionary(sb); - return sb.toString(); + writer.write("\nendobj\n"); + writer.flush(); + return cout.getCount(); } /** diff --git a/src/java/org/apache/fop/pdf/BitmapImage.java b/src/java/org/apache/fop/pdf/BitmapImage.java index 461ec0a64..34c78ffe3 100644 --- a/src/java/org/apache/fop/pdf/BitmapImage.java +++ b/src/java/org/apache/fop/pdf/BitmapImage.java @@ -163,15 +163,6 @@ public class BitmapImage implements PDFImage { return null; } - /** - * Get the soft mask reference for this image. - * - * @return the soft mask reference if any - */ - public String getSoftMask() { - return maskRef.toInlinePDFString(); - } - /** {@inheritDoc} */ public PDFReference getSoftMaskReference() { return maskRef; diff --git a/src/java/org/apache/fop/pdf/PDFArray.java b/src/java/org/apache/fop/pdf/PDFArray.java index 2dd68ad8b..2cb2adb1d 100644 --- a/src/java/org/apache/fop/pdf/PDFArray.java +++ b/src/java/org/apache/fop/pdf/PDFArray.java @@ -19,9 +19,14 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; import java.util.Collection; import java.util.List; +import org.apache.commons.io.output.CountingOutputStream; + /** * Class representing an array object. */ @@ -33,20 +38,21 @@ public class PDFArray extends PDFObject { /** * Create a new, empty array object + * @param parent the array's parent if any */ - public PDFArray() { + public PDFArray(PDFObject parent) { /* generic creation of PDF object */ - super(); + super(parent); } /** - * Create the array object - * + * Create an array object. + * @param parent the array's parent if any * @param values the actual array wrapped by this object */ - public PDFArray(int[] values) { + public PDFArray(PDFObject parent, int[] values) { /* generic creation of PDF object */ - super(); + super(parent); for (int i = 0, c = values.length; i < c; i++) { this.values.add(new Integer(values[i])); @@ -54,25 +60,25 @@ public class PDFArray extends PDFObject { } /** - * Create the array object - * + * Create an array object. + * @param parent the array's parent if any * @param values the actual values wrapped by this object */ - public PDFArray(Collection values) { + public PDFArray(PDFObject parent, Collection values) { /* generic creation of PDF object */ - super(); + super(parent); this.values.addAll(values); } /** * Create the array object - * + * @param parent the array's parent if any * @param values the actual array wrapped by this object */ - public PDFArray(Object[] values) { + public PDFArray(PDFObject parent, Object[] values) { /* generic creation of PDF object */ - super(); + super(parent); for (int i = 0, c = values.length; i < c; i++) { this.values.add(values[i]); @@ -118,6 +124,17 @@ public class PDFArray extends PDFObject { * Adds a new value to the array. * @param obj the value */ + public void add(PDFObject obj) { + if (obj != null) { + obj.setParent(this); + } + this.values.add(obj); + } + + /** + * Adds a new value to the array. + * @param obj the value + */ public void add(Object obj) { this.values.add(obj); } @@ -130,27 +147,30 @@ public class PDFArray extends PDFObject { this.values.add(new Double(value)); } - /** - * {@inheritDoc} - */ - public String toPDFString() { - StringBuffer p = new StringBuffer(64); + /** {@inheritDoc} */ + protected int output(OutputStream stream) throws IOException { + CountingOutputStream cout = new CountingOutputStream(stream); + Writer writer = PDFDocument.getWriterFor(cout); if (hasObjectNumber()) { - p.append(getObjectID()); + writer.write(getObjectID()); } - p.append("["); + + writer.write('['); for (int i = 0; i < values.size(); i++) { if (i > 0) { - p.append(" "); + writer.write(' '); } Object obj = this.values.get(i); - formatObject(obj, p); + formatObject(obj, cout, writer); } - p.append("]"); + writer.write(']'); + if (hasObjectNumber()) { - p.append("\nendobj\n"); + writer.write("\nendobj\n"); } - return p.toString(); + + writer.flush(); + return cout.getCount(); } - + } diff --git a/src/java/org/apache/fop/pdf/PDFDestination.java b/src/java/org/apache/fop/pdf/PDFDestination.java index c59b20cfc..eaf38449d 100644 --- a/src/java/org/apache/fop/pdf/PDFDestination.java +++ b/src/java/org/apache/fop/pdf/PDFDestination.java @@ -19,6 +19,12 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +import org.apache.commons.io.output.CountingOutputStream; + /** * class representing a named destination */ @@ -40,30 +46,24 @@ public class PDFDestination extends PDFObject { * @param goToRef Object reference to the GoTo Action */ public PDFDestination(String idRef, Object goToRef) { + super(); this.goToReference = goToRef; this.idRef = idRef; } - /** - * Creates the key/value pair for this destination entry for the name tree. - * @return the formatted key/value pair - */ - public String toKeyValuePair() { - StringBuffer sb = new StringBuffer(); - sb.append("(").append(getIDRef()).append(") "); - if (goToReference instanceof PDFWritable) { - sb.append(((PDFWritable)goToReference).toInlinePDFString()); - } else { - sb.append(goToReference); - } - return sb.toString(); - } - /** {@inheritDoc} */ - protected String toPDFString() { - return toKeyValuePair(); + protected int output(OutputStream stream) throws IOException { + CountingOutputStream cout = new CountingOutputStream(stream); + Writer writer = PDFDocument.getWriterFor(cout); + + formatObject(getIDRef(), cout, writer); + writer.write(' '); + formatObject(goToReference, cout, writer); + + writer.flush(); + return cout.getCount(); } - + /** * Sets the GoToReference in the associated DestinationData object. * @@ -124,9 +124,7 @@ public class PDFDestination extends PDFObject { return false; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public int hashCode() { return getIDRef().hashCode(); } diff --git a/src/java/org/apache/fop/pdf/PDFDests.java b/src/java/org/apache/fop/pdf/PDFDests.java index 463ef8d7e..ff2d6a237 100644 --- a/src/java/org/apache/fop/pdf/PDFDests.java +++ b/src/java/org/apache/fop/pdf/PDFDests.java @@ -40,7 +40,7 @@ public class PDFDests extends PDFNameTreeNode { */ public PDFDests(List destinationList) { this(); - setNames(new PDFArray(destinationList)); + setNames(new PDFArray(this, destinationList)); } } diff --git a/src/java/org/apache/fop/pdf/PDFDictionary.java b/src/java/org/apache/fop/pdf/PDFDictionary.java index c183871b5..49d48312c 100644 --- a/src/java/org/apache/fop/pdf/PDFDictionary.java +++ b/src/java/org/apache/fop/pdf/PDFDictionary.java @@ -19,10 +19,15 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.apache.commons.io.output.CountingOutputStream; + /** * Class representing a PDF dictionary object */ @@ -40,14 +45,21 @@ public class PDFDictionary extends PDFObject { protected List order = new java.util.ArrayList(); /** - * Create the dictionary object + * Create a new dictionary object. */ public PDFDictionary() { - /* generic creation of PDF object */ super(); } /** + * Create a new dictionary object. + * @param parent the object's parent if any + */ + public PDFDictionary(PDFObject parent) { + super(parent); + } + + /** * Puts a new name/value pair. * @param name the name * @param value the value @@ -80,47 +92,53 @@ public class PDFDictionary extends PDFObject { return this.entries.get(name); } - /** - * {@inheritDoc} - */ - public String toPDFString() { - StringBuffer p = new StringBuffer(64); + /** {@inheritDoc} */ + protected int output(OutputStream stream) throws IOException { + CountingOutputStream cout = new CountingOutputStream(stream); + Writer writer = PDFDocument.getWriterFor(cout); if (hasObjectNumber()) { - p.append(getObjectID()); + writer.write(getObjectID()); } - writeDictionary(p); + + writeDictionary(cout, writer); + if (hasObjectNumber()) { - p.append("endobj\n"); + writer.write("\nendobj\n"); } - return p.toString(); + + writer.flush(); + return cout.getCount(); } - + /** * Writes the contents of the dictionary to a StringBuffer. - * @param sb the target StringBuffer + * @param out the OutputStream (for binary content) + * @param writer the Writer (for text content, wraps the above OutputStream) + * @throws IOException if an I/O error occurs */ - protected void writeDictionary(StringBuffer sb) { - sb.append("<<"); + protected void writeDictionary(OutputStream out, Writer writer) throws IOException { + writer.write("<<"); boolean compact = (this.order.size() <= 2); Iterator iter = this.order.iterator(); while (iter.hasNext()) { String key = (String)iter.next(); if (compact) { - sb.append(' '); + writer.write(' '); } else { - sb.append("\n "); + writer.write("\n "); } - sb.append('/').append(key); - sb.append(' '); + writer.write('/'); + writer.write(key); + writer.write(' '); Object obj = this.entries.get(key); - formatObject(obj, sb); + formatObject(obj, out, writer); } if (compact) { - sb.append(' '); + writer.write(' '); } else { - sb.append('\n'); + writer.write('\n'); } - sb.append(">>\n"); + writer.write(">>\n"); } } diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java index 045d52173..bd44595fb 100644 --- a/src/java/org/apache/fop/pdf/PDFDocument.java +++ b/src/java/org/apache/fop/pdf/PDFDocument.java @@ -24,15 +24,16 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.io.Writer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Iterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -317,6 +318,22 @@ public class PDFDocument { } /** + * Creates and returns a Writer object wrapping the given OutputStream. The Writer is + * buffered to reduce the number of calls to the encoding converter so don't forget + * to <code>flush()</code> the Writer after use or before writing directly to the + * underlying OutputStream. + * @param out the OutputStream to write to + * @return the requested Writer + */ + public static Writer getWriterFor(OutputStream out) { + try { + return new java.io.BufferedWriter(new java.io.OutputStreamWriter(out, ENCODING)); + } catch (UnsupportedEncodingException uee) { + throw new Error("JVM doesn't support " + ENCODING + " encoding!"); + } + } + + /** * set the producer of the document * * @param producer string indicating application producing the PDF diff --git a/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java b/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java index 203ca90e1..5da37076c 100644 --- a/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java +++ b/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java @@ -20,20 +20,20 @@ package org.apache.fop.pdf; // Java +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; +import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.InvalidKeyException; +import java.util.Random; + +import javax.crypto.BadPaddingException; import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; import javax.crypto.CipherOutputStream; import javax.crypto.IllegalBlockSizeException; -import javax.crypto.BadPaddingException; import javax.crypto.NoSuchPaddingException; - -import java.util.Random; +import javax.crypto.spec.SecretKeySpec; /** * class representing a /Filter /Standard object. @@ -358,17 +358,20 @@ public class PDFEncryptionJCE extends PDFObject implements PDFEncryption { if (this.encryptionKey == null) { throw new IllegalStateException("PDF Encryption has not been initialized"); } - log.debug("encrypting with for " + number + " " + generation); - byte[] hash = calcHash(number, generation); return encryptWithHash(data, hash, hash.length); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public byte[] encrypt(byte[] data, PDFObject refObj) { - return encryptData(data, refObj.getObjectNumber(), refObj.getGeneration()); + PDFObject o = refObj; + while (o != null && !o.hasObjectNumber()) { + o = o.getParent(); + } + if (o == null) { + throw new IllegalStateException("No object number could be obtained for a PDF object"); + } + return encryptData(data, o.getObjectNumber(), o.getGeneration()); } private byte[] calcHash(int number, int generation) { diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index f851abae7..f3069e85e 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -39,6 +39,9 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.xmp.Metadata; + import org.apache.fop.fonts.CIDFont; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.FontDescriptor; @@ -51,7 +54,6 @@ import org.apache.fop.fonts.truetype.FontFileReader; import org.apache.fop.fonts.truetype.TTFSubSetFile; import org.apache.fop.fonts.type1.PFBData; import org.apache.fop.fonts.type1.PFBParser; -import org.apache.xmlgraphics.xmp.Metadata; /** * This class provides method to create and register PDF objects. @@ -872,7 +874,7 @@ public class PDFFactory { //true for a "deep" structure (one node per entry), true for a "flat" structure if (deep) { dests = new PDFDests(); - PDFArray kids = new PDFArray(); + PDFArray kids = new PDFArray(dests); Iterator iter = destinationList.iterator(); while (iter.hasNext()) { PDFDestination dest = (PDFDestination)iter.next(); @@ -880,8 +882,9 @@ public class PDFFactory { getDocument().registerObject(node); node.setLowerLimit(dest.getIDRef()); node.setUpperLimit(dest.getIDRef()); - node.setNames(new PDFArray()); - node.getNames().add(dest); + node.setNames(new PDFArray(node)); + PDFArray names = node.getNames(); + names.add(dest); kids.add(node); } dests.setLowerLimit(((PDFNameTreeNode)kids.get(0)).getLowerLimit()); @@ -1527,7 +1530,7 @@ public class PDFFactory { * @return the PDF Array with the int values */ public PDFArray makeArray(int[] values) { - PDFArray array = new PDFArray(values); + PDFArray array = new PDFArray(null, values); getDocument().registerObject(array); return array; diff --git a/src/java/org/apache/fop/pdf/PDFFilterList.java b/src/java/org/apache/fop/pdf/PDFFilterList.java index e866fc88e..607ae174b 100644 --- a/src/java/org/apache/fop/pdf/PDFFilterList.java +++ b/src/java/org/apache/fop/pdf/PDFFilterList.java @@ -277,7 +277,7 @@ public class PDFFilterList { } private void putFilterEntries(PDFDictionary dict, List names) { - PDFArray array = new PDFArray(); + PDFArray array = new PDFArray(dict); for (int i = 0, c = names.size(); i < c; i++) { final String name = (String)names.get(i); if (name.length() > 0) { @@ -323,7 +323,7 @@ public class PDFFilterList { private void putDecodeParams(PDFDictionary dict, List parms) { boolean needParmsEntry = false; - PDFArray array = new PDFArray(); + PDFArray array = new PDFArray(dict); for (int i = 0, c = parms.size(); i < c; i++) { Object obj = parms.get(i); if (obj != null) { diff --git a/src/java/org/apache/fop/pdf/PDFFormXObject.java b/src/java/org/apache/fop/pdf/PDFFormXObject.java index 456419f80..6ccf76c6c 100644 --- a/src/java/org/apache/fop/pdf/PDFFormXObject.java +++ b/src/java/org/apache/fop/pdf/PDFFormXObject.java @@ -63,7 +63,7 @@ public class PDFFormXObject extends PDFXObject { public void setBBox(Rectangle2D bbox) { PDFArray array = (PDFArray)get("BBox"); if (array == null) { - array = new PDFArray(); + array = new PDFArray(this); array.add(bbox.getX()); array.add(bbox.getY()); array.add(bbox.getWidth()); @@ -105,7 +105,7 @@ public class PDFFormXObject extends PDFXObject { double[] m = new double[6]; at.getMatrix(m); if (array == null) { - array = new PDFArray(); + array = new PDFArray(this); array.add(m[0]); array.add(m[1]); array.add(m[2]); @@ -170,7 +170,7 @@ public class PDFFormXObject extends PDFXObject { /** {@inheritDoc} */ protected void populateStreamDict(Object lengthEntry) { if (get("Matrix") == null) { - put("Matrix", new PDFArray(new int[] {1, 0, 0, 1, 0, 0})); + put("Matrix", new PDFArray(this, new int[] {1, 0, 0, 1, 0, 0})); } put("Resources", resRef); super.populateStreamDict(lengthEntry); diff --git a/src/java/org/apache/fop/pdf/PDFImage.java b/src/java/org/apache/fop/pdf/PDFImage.java index dd24240b5..f880fa6ac 100644 --- a/src/java/org/apache/fop/pdf/PDFImage.java +++ b/src/java/org/apache/fop/pdf/PDFImage.java @@ -105,11 +105,8 @@ public interface PDFImage { /** * Get the PDF reference for a soft mask. - * - * @return the PDF reference for a soft mask image + * @return the PDF reference for a soft mask image (or null if there's no soft mask) */ - String getSoftMask(); - PDFReference getSoftMaskReference(); /** @return true for CMYK images generated by Adobe Photoshop */ diff --git a/src/java/org/apache/fop/pdf/PDFImageXObject.java b/src/java/org/apache/fop/pdf/PDFImageXObject.java index 4cc174100..35f3e543d 100644 --- a/src/java/org/apache/fop/pdf/PDFImageXObject.java +++ b/src/java/org/apache/fop/pdf/PDFImageXObject.java @@ -94,7 +94,8 @@ public class PDFImageXObject extends PDFXObject { PDFICCStream pdfICCStream = pdfimage.getICCStream(); if (pdfICCStream != null) { - put("ColorSpace", new PDFArray(new Object[] {new PDFName("ICCBased"), pdfICCStream})); + put("ColorSpace", new PDFArray(this, + new Object[] {new PDFName("ICCBased"), pdfICCStream})); } else { PDFDeviceColorSpace cs = pdfimage.getColorSpace(); put("ColorSpace", new PDFName(cs.getName())); @@ -107,7 +108,7 @@ public class PDFImageXObject extends PDFXObject { */ final Float zero = new Float(0.0f); final Float one = new Float(1.0f); - PDFArray decode = new PDFArray(); + PDFArray decode = new PDFArray(this); for (int i = 0, c = pdfimage.getColorSpace().getNumComponents(); i < c; i++) { decode.add(one); decode.add(zero); @@ -117,7 +118,7 @@ public class PDFImageXObject extends PDFXObject { if (pdfimage.isTransparent()) { PDFColor transp = pdfimage.getTransparentColor(); - PDFArray mask = new PDFArray(); + PDFArray mask = new PDFArray(this); mask.add(new Integer(transp.red255())); mask.add(new Integer(transp.red255())); mask.add(new Integer(transp.green255())); diff --git a/src/java/org/apache/fop/pdf/PDFName.java b/src/java/org/apache/fop/pdf/PDFName.java index 4c3c3d003..8c626d53f 100644 --- a/src/java/org/apache/fop/pdf/PDFName.java +++ b/src/java/org/apache/fop/pdf/PDFName.java @@ -19,6 +19,10 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + /** * Class representing a PDF name object. */ @@ -65,15 +69,14 @@ public class PDFName implements PDFWritable { sb.append(DIGITS[ch & 0x0F]); } - /** {@inheritDoc} */ - public String toInlinePDFString() { + public String toString() { return this.name; } - + /** {@inheritDoc} */ - public String toString() { - return toInlinePDFString(); + public void outputInline(OutputStream out, Writer writer) throws IOException { + writer.write(toString()); } } diff --git a/src/java/org/apache/fop/pdf/PDFNameTreeNode.java b/src/java/org/apache/fop/pdf/PDFNameTreeNode.java index 476cfc7a2..4dcf0e03e 100644 --- a/src/java/org/apache/fop/pdf/PDFNameTreeNode.java +++ b/src/java/org/apache/fop/pdf/PDFNameTreeNode.java @@ -108,7 +108,7 @@ public class PDFNameTreeNode extends PDFDictionary { private PDFArray prepareLimitsArray() { PDFArray limits = (PDFArray)get(LIMITS); if (limits == null) { - limits = new PDFArray(new Object[2]); + limits = new PDFArray(this, new Object[2]); put(LIMITS, limits); } if (limits.length() != 2) { diff --git a/src/java/org/apache/fop/pdf/PDFNull.java b/src/java/org/apache/fop/pdf/PDFNull.java index e3fb44a8d..b1af30dc0 100644 --- a/src/java/org/apache/fop/pdf/PDFNull.java +++ b/src/java/org/apache/fop/pdf/PDFNull.java @@ -19,6 +19,10 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + /** * Class representing a PDF name object. */ @@ -35,13 +39,13 @@ public final class PDFNull implements PDFWritable { } /** {@inheritDoc} */ - public String toInlinePDFString() { + public String toString() { return "null"; } /** {@inheritDoc} */ - public String toString() { - return toInlinePDFString(); + public void outputInline(OutputStream out, Writer writer) throws IOException { + writer.write(toString()); } } diff --git a/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java b/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java index 4e69c01d4..ef1ccb452 100644 --- a/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java +++ b/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java @@ -1,121 +1,121 @@ -/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.pdf;
-
-/**
- * Class representing a PDF number tree node.
- */
-public class PDFNumberTreeNode extends PDFDictionary {
-
- private static final String KIDS = "Kids";
- private static final String NUMS = "Nums";
- private static final String LIMITS = "Limits";
-
- /**
- * create a named destination
- */
- public PDFNumberTreeNode() {
- /* generic creation of PDF object */
- super();
- }
-
- /**
- * Sets the Kids array.
- * @param kids the Kids array
- */
- public void setKids(PDFArray kids) {
- put(KIDS, kids);
- }
-
- /**
- * Returns the Kids array.
- * @return the Kids array
- */
- public PDFArray getKids() {
- return (PDFArray)get(KIDS);
- }
-
- /**
- * Sets the Nums array.
- * @param nums the Nums array
- */
- public void setNums(PDFNumsArray nums) {
- put(NUMS, nums);
- }
-
- /**
- * Returns the Nums array.
- * @return the Nums array
- */
- public PDFNumsArray getNums() {
- return (PDFNumsArray)get(NUMS);
- }
-
- /**
- * Sets the lower limit value of the Limits array.
- * @param key the lower limit value
- */
- public void setLowerLimit(Integer key) {
- PDFArray limits = prepareLimitsArray();
- limits.set(0, key);
- }
-
- /**
- * Returns the lower limit value of the Limits array.
- * @return the lower limit value
- */
- public Integer getLowerLimit() {
- PDFArray limits = prepareLimitsArray();
- return (Integer)limits.get(0);
- }
-
- /**
- * Sets the upper limit value of the Limits array.
- * @param key the upper limit value
- */
- public void setUpperLimit(Integer key) {
- PDFArray limits = prepareLimitsArray();
- limits.set(1, key);
- }
-
- /**
- * Returns the upper limit value of the Limits array.
- * @return the upper limit value
- */
- public Integer getUpperLimit() {
- PDFArray limits = prepareLimitsArray();
- return (Integer)limits.get(1);
- }
-
-
- private PDFArray prepareLimitsArray() {
- PDFArray limits = (PDFArray)get(LIMITS);
- if (limits == null) {
- limits = new PDFArray(new Object[2]);
- put(LIMITS, limits);
- }
- if (limits.length() != 2) {
- throw new IllegalStateException("Limits array must have 2 entries");
- }
- return limits;
- }
-
-}
-
+/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +/** + * Class representing a PDF number tree node. + */ +public class PDFNumberTreeNode extends PDFDictionary { + + private static final String KIDS = "Kids"; + private static final String NUMS = "Nums"; + private static final String LIMITS = "Limits"; + + /** + * create a named destination + */ + public PDFNumberTreeNode() { + /* generic creation of PDF object */ + super(); + } + + /** + * Sets the Kids array. + * @param kids the Kids array + */ + public void setKids(PDFArray kids) { + put(KIDS, kids); + } + + /** + * Returns the Kids array. + * @return the Kids array + */ + public PDFArray getKids() { + return (PDFArray)get(KIDS); + } + + /** + * Sets the Nums array. + * @param nums the Nums array + */ + public void setNums(PDFNumsArray nums) { + put(NUMS, nums); + } + + /** + * Returns the Nums array. + * @return the Nums array + */ + public PDFNumsArray getNums() { + return (PDFNumsArray)get(NUMS); + } + + /** + * Sets the lower limit value of the Limits array. + * @param key the lower limit value + */ + public void setLowerLimit(Integer key) { + PDFArray limits = prepareLimitsArray(); + limits.set(0, key); + } + + /** + * Returns the lower limit value of the Limits array. + * @return the lower limit value + */ + public Integer getLowerLimit() { + PDFArray limits = prepareLimitsArray(); + return (Integer)limits.get(0); + } + + /** + * Sets the upper limit value of the Limits array. + * @param key the upper limit value + */ + public void setUpperLimit(Integer key) { + PDFArray limits = prepareLimitsArray(); + limits.set(1, key); + } + + /** + * Returns the upper limit value of the Limits array. + * @return the upper limit value + */ + public Integer getUpperLimit() { + PDFArray limits = prepareLimitsArray(); + return (Integer)limits.get(1); + } + + + private PDFArray prepareLimitsArray() { + PDFArray limits = (PDFArray)get(LIMITS); + if (limits == null) { + limits = new PDFArray(this, new Object[2]); + put(LIMITS, limits); + } + if (limits.length() != 2) { + throw new IllegalStateException("Limits array must have 2 entries"); + } + return limits; + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFNumsArray.java b/src/java/org/apache/fop/pdf/PDFNumsArray.java index 55f973ccd..0a86754e8 100644 --- a/src/java/org/apache/fop/pdf/PDFNumsArray.java +++ b/src/java/org/apache/fop/pdf/PDFNumsArray.java @@ -1,94 +1,104 @@ -/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id: PDFArray.java 588547 2007-10-26 07:48:14Z jeremias $ */
-
-package org.apache.fop.pdf;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.SortedMap;
-
-/**
- * Class representing an "Nums" array object (for Number Trees).
- */
-public class PDFNumsArray extends PDFObject {
-
- /** Sorted Map holding the values of this array. */
- protected SortedMap map = new java.util.TreeMap();
-
- /**
- * Create a new, empty array object
- */
- public PDFNumsArray() {
- /* generic creation of PDF object */
- super();
- }
-
- /**
- * Returns the length of the array
- * @return the length of the array
- */
- public int length() {
- return this.map.size();
- }
-
- /**
- * Sets an entry.
- * @param key the key of the value to set
- * @param obj the new value
- */
- public void put(int key, Object obj) {
- this.map.put(new Integer(key), obj);
- }
-
- /**
- * Gets an entry.
- * @param key the key of requested value
- * @return the requested value
- */
- public Object get(int key) {
- return this.map.get(new Integer(key));
- }
-
- /** {@inheritDoc} */
- public String toPDFString() {
- StringBuffer p = new StringBuffer(64);
- if (hasObjectNumber()) {
- p.append(getObjectID());
- }
- p.append("[");
- boolean first = true;
- Iterator iter = this.map.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry entry = (Map.Entry)iter.next();
- if (!first) {
- p.append(" ");
- }
- first = false;
- formatObject(entry.getKey(), p);
- p.append(" ");
- formatObject(entry.getValue(), p);
- }
- p.append("]");
- if (hasObjectNumber()) {
- p.append("\nendobj\n");
- }
- return p.toString();
- }
-
-}
+/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.util.Iterator; +import java.util.Map; +import java.util.SortedMap; + +import org.apache.commons.io.output.CountingOutputStream; + +/** + * Class representing an "Nums" array object (for Number Trees). + */ +public class PDFNumsArray extends PDFObject { + + /** Sorted Map holding the values of this array. */ + protected SortedMap map = new java.util.TreeMap(); + + /** + * Create a new, empty array object. + * @param parent the object's parent if any + */ + public PDFNumsArray(PDFObject parent) { + super(parent); + } + + /** + * Returns the length of the array + * @return the length of the array + */ + public int length() { + return this.map.size(); + } + + /** + * Sets an entry. + * @param key the key of the value to set + * @param obj the new value + */ + public void put(int key, Object obj) { + this.map.put(new Integer(key), obj); + } + + /** + * Gets an entry. + * @param key the key of requested value + * @return the requested value + */ + public Object get(int key) { + return this.map.get(new Integer(key)); + } + + /** {@inheritDoc} */ + protected int output(OutputStream stream) throws IOException { + CountingOutputStream cout = new CountingOutputStream(stream); + Writer writer = PDFDocument.getWriterFor(cout); + if (hasObjectNumber()) { + writer.write(getObjectID()); + } + + writer.write('['); + boolean first = true; + Iterator iter = this.map.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry)iter.next(); + if (!first) { + writer.write(" "); + } + first = false; + formatObject(entry.getKey(), cout, writer); + writer.write(" "); + formatObject(entry.getValue(), cout, writer); + } + writer.write(']'); + + if (hasObjectNumber()) { + writer.write("\nendobj\n"); + } + + writer.flush(); + return cout.getCount(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFObject.java b/src/java/org/apache/fop/pdf/PDFObject.java index cab6b75f2..f53183574 100644 --- a/src/java/org/apache/fop/pdf/PDFObject.java +++ b/src/java/org/apache/fop/pdf/PDFObject.java @@ -22,6 +22,7 @@ package org.apache.fop.pdf; // Java import java.io.IOException; import java.io.OutputStream; +import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @@ -57,6 +58,9 @@ public abstract class PDFObject implements PDFWritable { */ private PDFDocument document; + /** the parent PDFObject (may be null and may not always be set, needed for encryption) */ + private PDFObject parent; + /** * Returns the object's number. * @return the PDF Object number @@ -69,6 +73,21 @@ public abstract class PDFObject implements PDFWritable { } /** + * Default constructor. + */ + public PDFObject() { + //nop + } + + /** + * Constructor for direct objects. + * @param parent the containing PDFObject instance + */ + public PDFObject(PDFObject parent) { + setParent(parent); + } + + /** * Indicates whether this PDFObject has already been assigned an * object number. * @return True if it has an object number @@ -102,7 +121,13 @@ public abstract class PDFObject implements PDFWritable { * has not been assigned) */ public final PDFDocument getDocument() { - return this.document; + if (this.document != null) { + return this.document; + } else if (getParent() != null) { + return getParent().getDocument(); + } else { + return null; + } } /** @@ -128,6 +153,22 @@ public abstract class PDFObject implements PDFWritable { } /** + * Returns this objects's parent. The parent is null if it is a "direct object". + * @return the parent or null if there's no parent (or it hasn't been set) + */ + public PDFObject getParent() { + return this.parent; + } + + /** + * Sets the direct parent object. + * @param parent the direct parent + */ + public void setParent(PDFObject parent) { + this.parent = parent; + } + + /** * Returns the PDF representation of the Object ID. * @return the Object ID */ @@ -169,6 +210,16 @@ public abstract class PDFObject implements PDFWritable { return pdf.length; } + /** {@inheritDoc} */ + public void outputInline(OutputStream out, Writer writer) throws IOException { + if (hasObjectNumber()) { + writer.write(referencePDF()); + } else { + writer.flush(); + output(out); + } + } + /** * Encodes the object as a byte array for output to a PDF file. * @@ -184,7 +235,9 @@ public abstract class PDFObject implements PDFWritable { * is normally converted/encoded to a byte array by toPDF(). Only use * this method to implement the serialization if the object can be fully * represented as text. If the PDF representation of the object contains - * binary content use toPDF() or output(OutputStream) instead. + * binary content use toPDF() or output(OutputStream) instead. This applies + * to any object potentially containing a string object because string object + * are encrypted and therefore need to be binary. * @return String the String representation */ protected String toPDFString() { @@ -193,20 +246,6 @@ public abstract class PDFObject implements PDFWritable { } /** - * Returns a representation of this object for in-object placement, i.e. if the object - * has an object number its reference is returned. Otherwise, its PDF representation is - * returned. - * @return the String representation - */ - public String toInlinePDFString() { - if (hasObjectNumber()) { - return referencePDF(); - } else { - return toPDFString(); - } - } - - /** * Converts text to a byte array for writing to a PDF file. * @param text text to convert/encode * @return byte[] the resulting byte array @@ -250,23 +289,27 @@ public abstract class PDFObject implements PDFWritable { /** * Formats an object for serialization to PDF. * @param obj the object - * @param sb the StringBuffer to write to + * @param out the OutputStream to write to + * @param writer a Writer for text content (will always be a wrapper around the above + * OutputStream. Make sure <code>flush</code> is called when mixing calls) + * @throws IOException If an I/O error occurs */ - protected void formatObject(Object obj, StringBuffer sb) { + protected void formatObject(Object obj, OutputStream out, Writer writer) throws IOException { if (obj == null) { - sb.append("null"); + writer.write("null"); } else if (obj instanceof PDFWritable) { - sb.append(((PDFWritable)obj).toInlinePDFString()); + ((PDFWritable)obj).outputInline(out, writer); } else if (obj instanceof Number) { if (obj instanceof Double || obj instanceof Float) { - sb.append(PDFNumber.doubleOut(((Number)obj).doubleValue())); + writer.write(PDFNumber.doubleOut(((Number)obj).doubleValue())); } else { - sb.append(obj); + writer.write(obj.toString()); } } else if (obj instanceof Boolean) { - sb.append(obj); + writer.write(obj.toString()); } else { - sb.append("(").append(obj).append(")"); + writer.flush(); + out.write(encodeText(obj.toString())); } } diff --git a/src/java/org/apache/fop/pdf/PDFPageLabels.java b/src/java/org/apache/fop/pdf/PDFPageLabels.java index bb02a3c7e..1a51c4155 100644 --- a/src/java/org/apache/fop/pdf/PDFPageLabels.java +++ b/src/java/org/apache/fop/pdf/PDFPageLabels.java @@ -1,48 +1,48 @@ -/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.pdf;
-
-/**
- * Class representing a PDF /PageLabels dictionary.
- */
-public class PDFPageLabels extends PDFNumberTreeNode {
-
- /**
- * Create the /PageLabels dictionary
- */
- public PDFPageLabels() {
- super();
- }
-
- /**
- * Returns the Nums object
- * @return the Nums object (an empty PDFNumsArray for the "/Nums" entry is created
- * if it doesn't exist)
- */
- public PDFNumsArray getNums() {
- PDFNumsArray nums = super.getNums();
- if (nums == null) {
- nums = new PDFNumsArray();
- setNums(nums);
- }
- return nums;
- }
-
-}
+/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +/** + * Class representing a PDF /PageLabels dictionary. + */ +public class PDFPageLabels extends PDFNumberTreeNode { + + /** + * Create the /PageLabels dictionary + */ + public PDFPageLabels() { + super(); + } + + /** + * Returns the Nums object + * @return the Nums object (an empty PDFNumsArray for the "/Nums" entry is created + * if it doesn't exist) + */ + public PDFNumsArray getNums() { + PDFNumsArray nums = super.getNums(); + if (nums == null) { + nums = new PDFNumsArray(this); + setNums(nums); + } + return nums; + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFReference.java b/src/java/org/apache/fop/pdf/PDFReference.java index ed1a8c016..3b615735a 100644 --- a/src/java/org/apache/fop/pdf/PDFReference.java +++ b/src/java/org/apache/fop/pdf/PDFReference.java @@ -19,6 +19,9 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -68,13 +71,13 @@ public class PDFReference implements PDFWritable { } /** {@inheritDoc} */ - public String toInlinePDFString() { + public String toString() { return this.indirectReference; } /** {@inheritDoc} */ - public String toString() { - return toInlinePDFString(); + public void outputInline(OutputStream out, Writer writer) throws IOException { + writer.write(toString()); } } diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java index 1a54a209f..54cadf616 100644 --- a/src/java/org/apache/fop/pdf/PDFRoot.java +++ b/src/java/org/apache/fop/pdf/PDFRoot.java @@ -225,7 +225,7 @@ public class PDFRoot extends PDFDictionary { if (getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) { PDFArray outputIntents = getOutputIntents(); if (outputIntents == null) { - outputIntents = new PDFArray(); + outputIntents = new PDFArray(this); put("OutputIntents", outputIntents); } outputIntents.add(outputIntent); diff --git a/src/java/org/apache/fop/pdf/PDFWritable.java b/src/java/org/apache/fop/pdf/PDFWritable.java index 23bcf9ad8..4f024fb92 100644 --- a/src/java/org/apache/fop/pdf/PDFWritable.java +++ b/src/java/org/apache/fop/pdf/PDFWritable.java @@ -19,6 +19,10 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + /** * This interface is implemented by classes that can be serialized to a PDF file either by * serializing the object or by writing a indirect reference to the actual object. @@ -26,11 +30,13 @@ package org.apache.fop.pdf; public interface PDFWritable { /** - * Returns a representation of this object for in-object placement, i.e. if the object - * has an object number its reference is returned. Otherwise, its PDF representation is - * returned. - * @return the String representation + * Writes a "direct object" (inline object) representation to the stream. A Writer is given + * for optimized encoding of text content. Since the Writer is buffered, make sure + * <code>flush()</code> is called before any direct calls to <code>out</code> are made. + * @param out the OutputStream (for binary content) + * @param writer the Writer (for text content, wraps the above OutputStream) + * @throws IOException if an I/O error occurs */ - String toInlinePDFString(); + void outputInline(OutputStream out, Writer writer) throws IOException; } diff --git a/src/java/org/apache/fop/render/pdf/FopPDFImage.java b/src/java/org/apache/fop/render/pdf/FopPDFImage.java index c9b0e3a7b..e60c207d6 100644 --- a/src/java/org/apache/fop/render/pdf/FopPDFImage.java +++ b/src/java/org/apache/fop/render/pdf/FopPDFImage.java @@ -25,6 +25,7 @@ import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.image.EPSImage; import org.apache.fop.image.FopImage; import org.apache.fop.image.TIFFImage; @@ -238,11 +239,6 @@ public class FopPDFImage implements PDFImage { } /** {@inheritDoc} */ - public String getSoftMask() { - return softMask.toInlinePDFString(); - } - - /** {@inheritDoc} */ public PDFReference getSoftMaskReference() { return softMask; } diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 2d8e7d5ba..f4aa5ee90 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -37,7 +37,15 @@ import java.util.Map; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; +import org.w3c.dom.Document; + import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.CountingOutputStream; + +import org.apache.xmlgraphics.xmp.Metadata; +import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; +import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; @@ -86,6 +94,7 @@ import org.apache.fop.pdf.PDFInfo; import org.apache.fop.pdf.PDFLink; import org.apache.fop.pdf.PDFMetadata; import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFNumsArray; import org.apache.fop.pdf.PDFOutline; import org.apache.fop.pdf.PDFOutputIntent; import org.apache.fop.pdf.PDFPage; @@ -102,10 +111,6 @@ import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.util.CharUtilities; import org.apache.fop.util.ColorProfileUtil; -import org.apache.xmlgraphics.xmp.Metadata; -import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; -import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; -import org.w3c.dom.Document; /** * Renderer that renders areas to PDF. @@ -357,7 +362,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { this.pdfDoc.getInfo().setTitle(userAgent.getTitle()); this.pdfDoc.getInfo().setKeywords(userAgent.getKeywords()); this.pdfDoc.setFilterMap(filterMap); - this.pdfDoc.outputHeader(stream); + this.pdfDoc.outputHeader(ostream); //Setup encryption if necessary PDFEncryptionManager.setupPDFEncryption(encryptionParams, this.pdfDoc); @@ -725,11 +730,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { pageLabels = this.pdfDoc.getFactory().makePageLabels(); this.pdfDoc.getRoot().setPageLabels(pageLabels); } - PDFDictionary dict = new PDFDictionary(); + PDFNumsArray nums = pageLabels.getNums(); + PDFDictionary dict = new PDFDictionary(nums); dict.put("P", page.getPageNumberString()); //TODO If the sequence of generated page numbers were inspected, this could be //expressed in a more space-efficient way - pageLabels.getNums().put(page.getPageIndex(), dict); + nums.put(page.getPageIndex(), dict); } /** |