--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id: PDFLink.java 426576 2006-07-28 15:44:37Z jeremias $ */\r
+\r
+package org.apache.fop.pdf;\r
+\r
+import org.apache.fop.area.DestinationData;\r
+import org.apache.fop.area.PageViewport;\r
+\r
+/**\r
+ * class representing a named destination\r
+ */\r
+public class PDFDestination extends PDFObject {\r
+\r
+ /**\r
+ * PDFReference (object reference) for this destination\r
+ */\r
+ private String goToReference;\r
+\r
+ /**\r
+ * ID Reference for this destination\r
+ */\r
+ private String idRef;\r
+\r
+ /**\r
+ * PageViewport to which the idRef item refers\r
+ */\r
+ private PageViewport pageViewport = null;\r
+\r
+ /**\r
+ * create a named destination\r
+ */\r
+ public PDFDestination(DestinationData destinationData) {\r
+ /* generic creation of PDF object */\r
+ super();\r
+ this.goToReference = destinationData.getGoToReference();\r
+ this.idRef = destinationData.getIDRef();\r
+ this.pageViewport = destinationData.getPageViewport();\r
+ }\r
+\r
+ /**\r
+ * @see org.apache.fop.pdf.PDFObject#toPDFString()\r
+ */\r
+ public String toPDFString() {\r
+ String s = getObjectID()\r
+ + "<<"\r
+ + "/Limits [(" + idRef + ") (" + idRef + ")]\n"\r
+ + "/Names [(" + idRef + ") " + goToReference + "]"\r
+ + "\n>>\nendobj\n";\r
+ return s;\r
+ }\r
+\r
+ /*\r
+ * example:\r
+ *\r
+ * 249 0 obj\r
+ * <<\r
+ * /Limits [(drivervariables) (drivervariables)]\r
+ * /Names [(drivervariables) 73 0 R]\r
+ * >>\r
+ * endobj\r
+ */\r
+\r
+ /**\r
+ * Sets the GoToReference in the associated DestinationData object.\r
+ *\r
+ * @param the GoToReference to set in the associated DestinationData object.\r
+ */\r
+ public void setGoToReference(String goToReference) {\r
+ this.goToReference = goToReference;\r
+ }\r
+\r
+ /**\r
+ * Returns the GoToReference from the associated DestinationData object.\r
+ *\r
+ * @return the GoToReference from the associated DestinationData object.\r
+ */\r
+ public String getGoToReference()\r
+ {\r
+ return this.goToReference;\r
+ }\r
+\r
+ /**\r
+ * Get the PageViewport object that this destination refers to\r
+ *\r
+ * @return the PageViewport that this destination points to\r
+ */\r
+ public PageViewport getPageViewport() {\r
+ return this.pageViewport;\r
+ }\r
+\r
+ /**\r
+ * Returns the RefID from the associated DestinationData object.\r
+ *\r
+ * @return the RefID from the associated DestinationData object.\r
+ */\r
+ public String getIDRef()\r
+ {\r
+ return this.idRef;\r
+ }\r
+\r
+ /**\r
+ * Check if this equals another object.\r
+ *\r
+ * @param obj the object to compare\r
+ * @return true if this equals other object\r
+ */\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+\r
+ if (obj == null || !(obj instanceof PDFDestination)) {\r
+ return false;\r
+ }\r
+\r
+ PDFDestination dest = (PDFDestination)obj;\r
+ if (dest.getIDRef() == this.getIDRef()) {\r
+ return true;\r
+ }\r
+ \r
+ return true;\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id: PDFLink.java 426576 2006-07-28 15:44:37Z jeremias $ */\r
+\r
+package org.apache.fop.pdf;\r
+\r
+import org.apache.fop.area.DestinationData;\r
+\r
+/**\r
+ * class representing an /Dests object (part of a name dictionary)\r
+ */\r
+public class PDFDests extends PDFObject {\r
+\r
+ private String limitsRef;\r
+\r
+ /**\r
+ * create a named destination\r
+ */\r
+ public PDFDests(String limitsRef) {\r
+ /* generic creation of PDF object */\r
+ super();\r
+ this.limitsRef = limitsRef;\r
+ }\r
+\r
+ /**\r
+ * @see org.apache.fop.pdf.PDFObject#toPDFString()\r
+ */\r
+ public String toPDFString() {\r
+ String s = getObjectID()\r
+ + "<<\n"\r
+ + "/Dests " + limitsRef\r
+ + "\n>>\nendobj\n";\r
+ return s;\r
+ }\r
+\r
+ /*\r
+ * example:\r
+ *\r
+ * 262 0 obj\r
+ * <<\r
+ * /Dests 260 0 R\r
+ * >>\r
+ * endobj\r
+ */\r
+\r
+ /**\r
+ * Check if this equals another object.\r
+ *\r
+ * @param obj the object to compare\r
+ * @return true if this equals other object\r
+ */\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+\r
+ if (obj == null || !(obj instanceof PDFDests)) {\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+ }\r
+}\r
+\r
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;
/**
* 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();
*/
protected List links = new java.util.ArrayList();
+ /**
+ * List of Destinations.
+ */
+ protected List destinations = new java.util.ArrayList();
+
/**
* List of FileSpecs.
*/
*/
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;
if (obj instanceof PDFLink) {
this.links.add(obj);
}
+ if (obj instanceof PDFDestination) {
+ this.destinations.add(obj);
+ }
if (obj instanceof PDFFileSpec) {
this.filespecs.add(obj);
}
return (PDFFont)fontMap.get(fontname);
}
+ /**
+ * 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 xObject;
}
+ /**
+ * 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.
* @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);
* 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.
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;
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.
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;
} 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));
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 ===================================== */
/**
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);
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);
public PDFICCBasedColorSpace makeICCBasedColorSpace(PDFResourceContext res,
String explicitName, PDFICCStream iccStream) {
PDFICCBasedColorSpace cs = new PDFICCBasedColorSpace(explicitName, iccStream);
-
+
getDocument().registerObject(cs);
if (res != null) {
} else {
getDocument().getResources().addColorSpace(cs);
}
-
+
return cs;
}
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id: PDFLink.java 426576 2006-07-28 15:44:37Z jeremias $ */\r
+\r
+package org.apache.fop.pdf;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.apache.fop.pdf.PDFDestination;\r
+\r
+/**\r
+ * class representing a Limits object (part of the names dictionary for named destinations)\r
+ */\r
+public class PDFLimits extends PDFObject {\r
+\r
+ private ArrayList destinationList;\r
+\r
+ /**\r
+ * create a named destination\r
+ */\r
+ public PDFLimits(ArrayList destinationList) {\r
+ /* generic creation of PDF object */\r
+ super();\r
+ this.destinationList = destinationList;\r
+ }\r
+\r
+ /**\r
+ * @see org.apache.fop.pdf.PDFObject#toPDFString()\r
+ */\r
+ public String toPDFString() {\r
+ String[] idRefs = new String[destinationList.size()];\r
+ String kidsString = "";\r
+ for(int i = 0; i < destinationList.size(); i++) {\r
+ PDFDestination dest = (PDFDestination)destinationList.get(i);\r
+ idRefs[i] = dest.getIDRef();\r
+ kidsString += dest.referencePDF();\r
+ if (!(i == destinationList.size() - 1)) {\r
+ kidsString += " ";\r
+ }\r
+ }\r
+ String s = getObjectID()\r
+ + "<<\n"\r
+ + "/Limits [(" + idRefs[0] + ") (" + idRefs[destinationList.size() - 1] + ")]\n"\r
+ + "/Kids [" + kidsString + "]"\r
+ + "\n>>\nendobj\n";\r
+ return s;\r
+ }\r
+\r
+ /*\r
+ * example:\r
+ *\r
+ * 260 0 obj\r
+ * <<\r
+ * /Limits [(Annotate) (thumbnails)]\r
+ * /Kids [248 0 R 253 0 R 254 0 R 259 0 R]\r
+ * >>\r
+ * endobj\r
+ */\r
+\r
+ /**\r
+ * Check if this equals another object.\r
+ *\r
+ * @param obj the object to compare\r
+ * @return true if this equals other object\r
+ */\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+\r
+ if (obj == null || !(obj instanceof PDFLimits)) {\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+ }\r
+}\r
+\r
package org.apache.fop.pdf;
import java.util.List;
+import java.util.ArrayList;
/**
* class representing a Root (/Catalog) object
/** 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;
/**
return outline;
}
+ /**
+ * Set the optional Metadata object.
+ * @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
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");