aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Bryant <jbryant@apache.org>2007-04-01 14:50:36 +0000
committerJay Bryant <jbryant@apache.org>2007-04-01 14:50:36 +0000
commitfdb46ddc0d5825898e684527a43c0732b7b2339d (patch)
tree92453b5090e3aa3d926a19f2a14db61a5b8a0a69
parent44ab9b9f94b9d3f0f04608a84fb47eada068eac4 (diff)
downloadxmlgraphics-fop-fdb46ddc0d5825898e684527a43c0732b7b2339d.tar.gz
xmlgraphics-fop-fdb46ddc0d5825898e684527a43c0732b7b2339d.zip
changes to support named destinations
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@524606 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/pdf/PDFDestination.java140
-rw-r--r--src/java/org/apache/fop/pdf/PDFDests.java79
-rw-r--r--src/java/org/apache/fop/pdf/PDFDocument.java89
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java71
-rw-r--r--src/java/org/apache/fop/pdf/PDFLimits.java93
-rw-r--r--src/java/org/apache/fop/pdf/PDFRoot.java19
6 files changed, 481 insertions, 10 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFDestination.java b/src/java/org/apache/fop/pdf/PDFDestination.java
new file mode 100644
index 000000000..e8228acfd
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/PDFDestination.java
@@ -0,0 +1,140 @@
+/*
+ * 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: PDFLink.java 426576 2006-07-28 15:44:37Z jeremias $ */
+
+package org.apache.fop.pdf;
+
+import org.apache.fop.area.DestinationData;
+import org.apache.fop.area.PageViewport;
+
+/**
+ * class representing a named destination
+ */
+public class PDFDestination extends PDFObject {
+
+ /**
+ * PDFReference (object reference) for this destination
+ */
+ private String goToReference;
+
+ /**
+ * ID Reference for this destination
+ */
+ private String idRef;
+
+ /**
+ * PageViewport to which the idRef item refers
+ */
+ private PageViewport pageViewport = null;
+
+ /**
+ * create a named destination
+ */
+ public PDFDestination(DestinationData destinationData) {
+ /* generic creation of PDF object */
+ super();
+ this.goToReference = destinationData.getGoToReference();
+ this.idRef = destinationData.getIDRef();
+ this.pageViewport = destinationData.getPageViewport();
+ }
+
+ /**
+ * @see org.apache.fop.pdf.PDFObject#toPDFString()
+ */
+ public String toPDFString() {
+ String s = getObjectID()
+ + "<<"
+ + "/Limits [(" + idRef + ") (" + idRef + ")]\n"
+ + "/Names [(" + idRef + ") " + goToReference + "]"
+ + "\n>>\nendobj\n";
+ return s;
+ }
+
+ /*
+ * example:
+ *
+ * 249 0 obj
+ * <<
+ * /Limits [(drivervariables) (drivervariables)]
+ * /Names [(drivervariables) 73 0 R]
+ * >>
+ * endobj
+ */
+
+ /**
+ * Sets the GoToReference in the associated DestinationData object.
+ *
+ * @param the GoToReference to set in the associated DestinationData object.
+ */
+ public void setGoToReference(String goToReference) {
+ this.goToReference = goToReference;
+ }
+
+ /**
+ * Returns the GoToReference from the associated DestinationData object.
+ *
+ * @return the GoToReference from the associated DestinationData object.
+ */
+ public String getGoToReference()
+ {
+ return this.goToReference;
+ }
+
+ /**
+ * Get the PageViewport object that this destination refers to
+ *
+ * @return the PageViewport that this destination points to
+ */
+ public PageViewport getPageViewport() {
+ return this.pageViewport;
+ }
+
+ /**
+ * Returns the RefID from the associated DestinationData object.
+ *
+ * @return the RefID from the associated DestinationData object.
+ */
+ public String getIDRef()
+ {
+ return this.idRef;
+ }
+
+ /**
+ * Check if this equals another object.
+ *
+ * @param obj the object to compare
+ * @return true if this equals other object
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || !(obj instanceof PDFDestination)) {
+ return false;
+ }
+
+ PDFDestination dest = (PDFDestination)obj;
+ if (dest.getIDRef() == this.getIDRef()) {
+ return true;
+ }
+
+ return true;
+ }
+}
+
diff --git a/src/java/org/apache/fop/pdf/PDFDests.java b/src/java/org/apache/fop/pdf/PDFDests.java
new file mode 100644
index 000000000..3989b397a
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/PDFDests.java
@@ -0,0 +1,79 @@
+/*
+ * 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: PDFLink.java 426576 2006-07-28 15:44:37Z jeremias $ */
+
+package org.apache.fop.pdf;
+
+import org.apache.fop.area.DestinationData;
+
+/**
+ * class representing an /Dests object (part of a name dictionary)
+ */
+public class PDFDests extends PDFObject {
+
+ private String limitsRef;
+
+ /**
+ * create a named destination
+ */
+ public PDFDests(String limitsRef) {
+ /* generic creation of PDF object */
+ super();
+ this.limitsRef = limitsRef;
+ }
+
+ /**
+ * @see org.apache.fop.pdf.PDFObject#toPDFString()
+ */
+ public String toPDFString() {
+ String s = getObjectID()
+ + "<<\n"
+ + "/Dests " + limitsRef
+ + "\n>>\nendobj\n";
+ return s;
+ }
+
+ /*
+ * example:
+ *
+ * 262 0 obj
+ * <<
+ * /Dests 260 0 R
+ * >>
+ * endobj
+ */
+
+ /**
+ * Check if this equals another object.
+ *
+ * @param obj the object to compare
+ * @return true if this equals other object
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || !(obj instanceof PDFDests)) {
+ return false;
+ }
+
+ return true;
+ }
+}
+
diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java
index 4ce82fab9..042d3d00b 100644
--- a/src/java/org/apache/fop/pdf/PDFDocument.java
+++ b/src/java/org/apache/fop/pdf/PDFDocument.java
@@ -32,6 +32,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
+import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -85,7 +86,7 @@ public class PDFDocument {
/**
* the character position of each object
*/
- protected List location = new java.util.ArrayList();
+ protected List location = new ArrayList();
/** List of objects to write in the trailer */
private List trailerObjects = new java.util.ArrayList();
@@ -202,6 +203,11 @@ public class PDFDocument {
protected List links = new java.util.ArrayList();
/**
+ * List of Destinations.
+ */
+ protected List destinations = new java.util.ArrayList();
+
+ /**
* List of FileSpecs.
*/
protected List filespecs = new java.util.ArrayList();
@@ -216,6 +222,25 @@ public class PDFDocument {
*/
protected List gotos = new java.util.ArrayList();
+ /**
+ * The PDFDests object for the name dictionary.
+ * Note: This object is not a list.
+ */
+ private PDFDests dests;
+
+ /**
+ * The PDFLimits object for the name dictionary.
+ * Note: This object is not a list.
+ */
+ private PDFLimits limits;
+
+ /**
+ * Whether this PDFDocument has named destinations
+ * (and thus needs PDFDestinations, PDFLimits, and
+ * PDFDests)
+ */
+ private boolean hasDestinations = false;
+
private PDFFactory factory;
private boolean encodingOnTheFly = true;
@@ -460,6 +485,9 @@ public class PDFDocument {
if (obj instanceof PDFLink) {
this.links.add(obj);
}
+ if (obj instanceof PDFDestination) {
+ this.destinations.add(obj);
+ }
if (obj instanceof PDFFileSpec) {
this.filespecs.add(obj);
}
@@ -578,6 +606,15 @@ public class PDFDocument {
}
/**
+ * Finds a named destination.
+ * @param compare reference object to use as search template
+ * @return the link if found, null otherwise
+ */
+ protected PDFDestination findDestination(PDFDestination compare) {
+ return (PDFDestination)findPDFObject(destinations, compare);
+ }
+
+ /**
* Finds a link.
* @param compare reference object to use as search template
* @return the link if found, null otherwise
@@ -702,6 +739,51 @@ public class PDFDocument {
}
/**
+ * Gets the PDFDests object (which represents the /Dests entry).
+ *
+ * @return the PDFDests object (which represents the /Dests entry).
+ */
+ public PDFDests getDests() {
+ return dests;
+ }
+
+ /**
+ * Gets the list of named destinations.
+ *
+ * @return the list of named destinations.
+ */
+ public ArrayList getDestinationList() {
+ return (ArrayList)destinations;
+ }
+
+ /**
+ * Sets whether the document has named destinations.
+ *
+ * @param whether the document has named destinations.
+ */
+ public void setHasDestinations(boolean hasDestinations) {
+ this.hasDestinations = hasDestinations;
+ }
+
+ /**
+ * Gets whether the document has named destinations.
+ *
+ * @return whether the document has named destinations.
+ */
+ public boolean getHasDestinations() {
+ return this.hasDestinations;
+ }
+
+ /**
+ * Gets the PDFLimits object (part of the name dictionary).
+ *
+ * @return the PDFLimits object (part of the name dictionary).
+ */
+ public PDFLimits getLimits() {
+ return limits;
+ }
+
+ /**
* Add an image to the PDF document.
* This adds an image to the PDF objects.
* If an image with the same key already exists it will return the
@@ -893,6 +975,11 @@ public class PDFDocument {
* @throws IOException if there is an exception writing to the output stream
*/
public void outputTrailer(OutputStream stream) throws IOException {
+ if (hasDestinations) {
+ limits = getFactory().makeLimits((ArrayList)destinations);
+ dests = getFactory().makeDests(limits.referencePDF());
+ this.root.setNames(dests.referencePDF());
+ }
output(stream);
for (int count = 0; count < trailerObjects.size(); count++) {
PDFObject o = (PDFObject)trailerObjects.get(count);
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index 4ab6ebd7b..3005f2018 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -5,9 +5,9 @@
* 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.
@@ -31,6 +31,7 @@ import java.util.List;
import java.util.Map;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
+import java.util.ArrayList;
// Apache libs
import org.apache.commons.io.IOUtils;
@@ -52,6 +53,8 @@ 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;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.DestinationData;
/**
* This class provides method to create and register PDF objects.
@@ -731,7 +734,7 @@ public class PDFFactory {
PDFPattern myPattern;
//PDFColorSpace theColorSpace;
double interpolation = (double)1.000;
- List theFunctions = new java.util.ArrayList();
+ List theFunctions = new ArrayList();
int currentPosition;
int lastPosition = theColors.size() - 1;
@@ -782,7 +785,7 @@ public class PDFFactory {
} else { // if the center x, center y, and radius specifiy
// the gradient, then assume the same center x, center y,
// and radius of zero for the other necessary component
- List newCoords = new java.util.ArrayList();
+ List newCoords = new ArrayList();
newCoords.add(theCoords.get(0));
newCoords.add(theCoords.get(1));
newCoords.add(theCoords.get(2));
@@ -809,6 +812,56 @@ public class PDFFactory {
return (myPattern);
}
+ /* ============= named destinations and the name dictionary ============ */
+
+ /**
+ * Make a named destination.
+ *
+ * @param destinationData the DestinationData object that holds the info about this named destination
+ * @return the new PDF named destination object
+ */
+ public PDFDestination makeDestination(DestinationData destinationData) {
+ PageViewport pv = destinationData.getPageViewport();
+ if (pv == null) {
+ log.warn("Unresolved destination item received: " + destinationData.getIDRef());
+ }
+ PDFDestination destination = new PDFDestination(destinationData);
+
+ PDFDestination oldDestination = getDocument().findDestination(destination);
+ if (destination == oldDestination) {
+ destination = oldDestination;
+ } else {
+ getDocument().registerObject(destination);
+ getDocument().setHasDestinations(true);
+ }
+
+ return destination;
+ }
+
+ /**
+ * Make a the head object of the name dictionary (the /Dests object).
+ *
+ * @return the new PDFDests object
+ */
+ public PDFDests makeDests(String limitsRef) {
+ PDFDests dests = new PDFDests(limitsRef);
+ getDocument().registerObject(dests);
+
+ return dests;
+ }
+
+ /**
+ * Make a the limits object of the name dictionary (the /Limits object).
+ *
+ * @return the new PDFLimits object
+ */
+ public PDFLimits makeLimits(ArrayList destinationList) {
+ PDFLimits limits = new PDFLimits(destinationList);
+ getDocument().registerObject(limits);
+
+ return limits;
+ }
+
/* ========================= links ===================================== */
/**
@@ -888,7 +941,7 @@ public class PDFFactory {
return link;
}
- private String getGoToReference(String destination, float yoffset) {
+ public String getGoToReference(String destination, float yoffset) {
getDocument().getProfile().verifyActionAllowed();
String goToReference = null;
PDFGoTo gt = new PDFGoTo(destination);
@@ -1153,9 +1206,9 @@ public class PDFFactory {
int value = 0;
for (int i = 0, c = cidSubset.length(); i < c; i++) {
int shift = i % 8;
- boolean b = cidSubset.get(i);
+ boolean b = cidSubset.get(i);
if (b) {
- value |= 1 << 7 - shift;
+ value |= 1 << 7 - shift;
}
if (shift == 7) {
baout.write(value);
@@ -1335,7 +1388,7 @@ public class PDFFactory {
public PDFICCBasedColorSpace makeICCBasedColorSpace(PDFResourceContext res,
String explicitName, PDFICCStream iccStream) {
PDFICCBasedColorSpace cs = new PDFICCBasedColorSpace(explicitName, iccStream);
-
+
getDocument().registerObject(cs);
if (res != null) {
@@ -1343,7 +1396,7 @@ public class PDFFactory {
} else {
getDocument().getResources().addColorSpace(cs);
}
-
+
return cs;
}
diff --git a/src/java/org/apache/fop/pdf/PDFLimits.java b/src/java/org/apache/fop/pdf/PDFLimits.java
new file mode 100644
index 000000000..ece7a3dfb
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/PDFLimits.java
@@ -0,0 +1,93 @@
+/*
+ * 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: PDFLink.java 426576 2006-07-28 15:44:37Z jeremias $ */
+
+package org.apache.fop.pdf;
+
+import java.util.ArrayList;
+
+import org.apache.fop.pdf.PDFDestination;
+
+/**
+ * class representing a Limits object (part of the names dictionary for named destinations)
+ */
+public class PDFLimits extends PDFObject {
+
+ private ArrayList destinationList;
+
+ /**
+ * create a named destination
+ */
+ public PDFLimits(ArrayList destinationList) {
+ /* generic creation of PDF object */
+ super();
+ this.destinationList = destinationList;
+ }
+
+ /**
+ * @see org.apache.fop.pdf.PDFObject#toPDFString()
+ */
+ public String toPDFString() {
+ String[] idRefs = new String[destinationList.size()];
+ String kidsString = "";
+ for(int i = 0; i < destinationList.size(); i++) {
+ PDFDestination dest = (PDFDestination)destinationList.get(i);
+ idRefs[i] = dest.getIDRef();
+ kidsString += dest.referencePDF();
+ if (!(i == destinationList.size() - 1)) {
+ kidsString += " ";
+ }
+ }
+ String s = getObjectID()
+ + "<<\n"
+ + "/Limits [(" + idRefs[0] + ") (" + idRefs[destinationList.size() - 1] + ")]\n"
+ + "/Kids [" + kidsString + "]"
+ + "\n>>\nendobj\n";
+ return s;
+ }
+
+ /*
+ * example:
+ *
+ * 260 0 obj
+ * <<
+ * /Limits [(Annotate) (thumbnails)]
+ * /Kids [248 0 R 253 0 R 254 0 R 259 0 R]
+ * >>
+ * endobj
+ */
+
+ /**
+ * Check if this equals another object.
+ *
+ * @param obj the object to compare
+ * @return true if this equals other object
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || !(obj instanceof PDFLimits)) {
+ return false;
+ }
+
+ return true;
+ }
+}
+
diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java
index ffe9611ba..60fe6b390 100644
--- a/src/java/org/apache/fop/pdf/PDFRoot.java
+++ b/src/java/org/apache/fop/pdf/PDFRoot.java
@@ -20,6 +20,7 @@
package org.apache.fop.pdf;
import java.util.List;
+import java.util.ArrayList;
/**
* class representing a Root (/Catalog) object
@@ -62,6 +63,12 @@ public class PDFRoot extends PDFObject {
/** The array of OutputIntents */
private List outputIntents;
+ /**
+ * The referencePDF value of the /Dests object,
+ * if this PDF has a Name Dictionary
+ */
+ private String namesReferencePDF = null;
+
private int pageMode = PAGEMODE_USENONE;
/**
@@ -130,6 +137,15 @@ public class PDFRoot extends PDFObject {
* @param meta the Metadata object
* @since PDF 1.4
*/
+ public void setNames(String referencePDF) {
+ this.namesReferencePDF = referencePDF;
+ }
+
+ /**
+ * Set the optional Metadata object.
+ * @param meta the Metadata object
+ * @since PDF 1.4
+ */
public void setMetadata(PDFMetadata meta) {
this.metadata = meta;
}
@@ -181,6 +197,9 @@ public class PDFRoot extends PDFObject {
break;
}
}
+ if (getDocumentSafely().getHasDestinations() && namesReferencePDF != null) {
+ p.append(" /Names " + namesReferencePDF + "\n");
+ }
if (getMetadata() != null
&& getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) {
p.append("/Metadata " + getMetadata().referencePDF() + "\n");