diff options
author | Jay Bryant <jbryant@apache.org> | 2007-04-01 14:50:36 +0000 |
---|---|---|
committer | Jay Bryant <jbryant@apache.org> | 2007-04-01 14:50:36 +0000 |
commit | fdb46ddc0d5825898e684527a43c0732b7b2339d (patch) | |
tree | 92453b5090e3aa3d926a19f2a14db61a5b8a0a69 | |
parent | 44ab9b9f94b9d3f0f04608a84fb47eada068eac4 (diff) | |
download | xmlgraphics-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.java | 140 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFDests.java | 79 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFDocument.java | 89 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFFactory.java | 71 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFLimits.java | 93 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFRoot.java | 19 |
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"); |