aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/pdf/PDFObject.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/pdf/PDFObject.java')
-rw-r--r--src/java/org/apache/fop/pdf/PDFObject.java91
1 files changed, 67 insertions, 24 deletions
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()));
}
}