Browse Source

Removed newly introduced dependency from the PDF library to the area tree.

Removed PDFDocument.setHasDestinations() (PDFDocument knows that already).
Started to add some generic PDF data structures (array, dictionary).

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@535883 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_94
Jeremias Maerki 17 years ago
parent
commit
b222b4dcad

+ 1
- 2
src/java/org/apache/fop/area/BookmarkData.java View File

@@ -19,7 +19,6 @@
package org.apache.fop.area;

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;

@@ -32,7 +31,7 @@ import org.apache.fop.fo.pagination.bookmarks.Bookmark;
* child bookmark-items under it.
*/
public class BookmarkData extends AbstractOffDocumentItem implements Resolvable {
private ArrayList subData = new ArrayList();
private List subData = new java.util.ArrayList();

// bookmark-title for this fo:bookmark
private String bookmarkTitle = null;

+ 0
- 21
src/java/org/apache/fop/area/DestinationData.java View File

@@ -28,9 +28,6 @@ import org.apache.fop.area.PageViewport;
*/
public class DestinationData extends AbstractOffDocumentItem implements Resolvable {

// PDFReference (object reference) for this destination
private String goToReference;

// ID Reference for this bookmark
private String idRef;

@@ -78,24 +75,6 @@ public class DestinationData extends AbstractOffDocumentItem implements Resolvab
return pageRef;
}

/**
* Set the GoToReference for this destination
*
* @param goToReference the GoToReference to associate with this destination
*/
public void setGoToReference(String goToReference) {
this.goToReference = goToReference;
}

/**
* Get the GoToReference for this destination
*
* @return the GoToReference associated with this destination
*/
public String getGoToReference() {
return goToReference;
}

/**
* Check if this resolvable object has been resolved.
* For now, just return true.

+ 4
- 5
src/java/org/apache/fop/fo/pagination/Root.java View File

@@ -21,7 +21,6 @@ package org.apache.fop.fo.pagination;

// java
import java.util.List;
import java.util.ArrayList;

import org.xml.sax.Locator;

@@ -45,7 +44,7 @@ public class Root extends FObj {
private LayoutMasterSet layoutMasterSet;
private Declarations declarations;
private BookmarkTree bookmarkTree = null;
private ArrayList destinationList;
private List destinationList;
private List pageSequences;

// temporary until above list populated
@@ -67,7 +66,7 @@ public class Root extends FObj {
*/
public Root(FONode parent) {
super(parent);
pageSequences = new ArrayList();
pageSequences = new java.util.ArrayList();
if (parent != null) {
//throw new FOPException("root must be root element");
}
@@ -260,7 +259,7 @@ public class Root extends FObj {
*/
public void addDestination(Destination destination) {
if (destinationList == null) {
destinationList = new ArrayList();
destinationList = new java.util.ArrayList();
}
destinationList.add(destination);
}
@@ -269,7 +268,7 @@ public class Root extends FObj {
* Public accessor for the list of Destination objects for this FO
* @return the Destination object
*/
public ArrayList getDestinationList() {
public List getDestinationList() {
return destinationList;
}


+ 96
- 12
src/java/org/apache/fop/pdf/PDFArray.java View File

@@ -19,40 +19,124 @@
package org.apache.fop.pdf;

import java.util.Collection;
import java.util.List;

/**
* class representing an array object
* Class representing an array object.
*/
public class PDFArray extends PDFObject {
/**
* Array of calues for this pdf object.
* List holding the values of this array
*/
protected int[] values;
protected List values = new java.util.ArrayList();

/**
* Create a new, empty array object
*/
public PDFArray() {
/* generic creation of PDF object */
super();
}

/**
* create the array object
* Create the array object
*
* @param values the actual array wrapped by this object
*/
public PDFArray(int[] values) {

/* generic creation of PDF object */
super();

/* set fields using paramaters */
this.values = values;
for (int i = 0, c = values.length; i < c; i++) {
this.values.add(new Integer(values[i]));
}
}

/**
* Create the array object
*
* @param values the actual values wrapped by this object
*/
public PDFArray(Collection values) {
/* generic creation of PDF object */
super();
this.values.addAll(values);
}
/**
* Create the array object
*
* @param values the actual array wrapped by this object
*/
public PDFArray(Object[] values) {
/* generic creation of PDF object */
super();
for (int i = 0, c = values.length; i < c; i++) {
this.values.add(values[i]);
}
}
/**
* Returns the length of the array
* @return the length of the array
*/
public int length() {
return this.values.size();
}
/**
* Sets an entry at a given location.
* @param index the index of the value to set
* @param obj the new value
*/
public void set(int index, Object obj) {
this.values.set(index, obj);
}
/**
* Gets an entry at a given location.
* @param index the index of the value to set
* @return the requested value
*/
public Object get(int index) {
return this.values.get(index);
}
/**
* Adds a new value to the array.
* @param obj the value
*/
public void add(Object obj) {
this.values.add(obj);
}
/**
* @see org.apache.fop.pdf.PDFObject#toPDFString()
*/
public String toPDFString() {
StringBuffer p = new StringBuffer(64);
p.append(getObjectID() + "[");
for (int i = 0; i < values.length; i++) {
p.append(" ");
p.append(values[i]);
if (hasObjectNumber()) {
p.append(getObjectID());
}
p.append("[");
for (int i = 0; i < values.size(); i++) {
if (i > 0) {
p.append(" ");
}
Object obj = this.values.get(i);
if (obj instanceof PDFWritable) {
p.append(((PDFWritable)obj).toInlinePDFString());
} else {
p.append("(").append(obj).append(")");
}
}
p.append("]");
if (hasObjectNumber()) {
p.append("\nendobj\n");
}
p.append("]\nendobj\n");
return p.toString();
}


+ 40
- 57
src/java/org/apache/fop/pdf/PDFDestination.java View File

@@ -19,102 +19,77 @@

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
* PDFReference (object reference) for this destination
*/
public PDFDestination(DestinationData destinationData) {
/* generic creation of PDF object */
super();
this.goToReference = destinationData.getGoToReference();
this.idRef = destinationData.getIDRef();
this.pageViewport = destinationData.getPageViewport();
}
private Object goToReference;

/**
* create a named destination
*
* @param idRef The ID reference for this destination - will be used as the name
* @param goToRef A PDF reference to a /GoTo pointing to the target area
* @param pv The PageViewport of the target area (merely informational)
* Create a named destination
* @param idRef ID Reference for this destination (the name of the destination)
* @param goToRef Object reference to the GoTo Action
*/
public PDFDestination(String idRef, String goToRef, PageViewport pv) {
super();
this.idRef = idRef;
public PDFDestination(String idRef, Object goToRef) {
this.goToReference = goToRef;
this.pageViewport = pv;
this.idRef = idRef;
}

/**
* @see org.apache.fop.pdf.PDFObject#toPDFString()
* Creates the key/value pair for this destination entry for the name tree.
* @return the formatted key/value pair
*/
public String toPDFString() {
String s = getObjectID()
+ "<<\n"
+ "/Limits [(" + idRef + ") (" + idRef + ")]\n"
+ "/Names [(" + idRef + ") " + goToReference + "]"
+ "\n>>\nendobj\n";
return s;
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();
}
/** @see org.apache.fop.pdf.PDFObject#toPDFString() */
protected String toPDFString() {
return toKeyValuePair();
}

/*
* example:
*
* 249 0 obj
* <<
* /Limits [(drivervariables) (drivervariables)]
* /Names [(drivervariables) 73 0 R]
* >>
* endobj
*/

/**
* Sets the GoToReference in the associated DestinationData object.
*
* @param goToReference the reference to set in the associated DestinationData object.
* @deprecated use setGoToReference(Object) instead
*/
public void setGoToReference(String goToReference) {
this.goToReference = goToReference;
}

/**
* Returns the GoToReference from the associated DestinationData object.
* Sets the GoToReference in the associated DestinationData object.
*
* @return the GoToReference from the associated DestinationData object.
* @param goToReference the reference to set in the associated DestinationData object.
*/
public String getGoToReference() {
return this.goToReference;
public void setGoToReference(Object goToReference) {
this.goToReference = goToReference;
}

/**
* Get the PageViewport object that this destination refers to
* Returns the GoToReference from the associated DestinationData object.
*
* @return the PageViewport that this destination points to
* @return the GoToReference from the associated DestinationData object.
*/
public PageViewport getPageViewport() {
return this.pageViewport;
public Object getGoToReference() {
return this.goToReference;
}

/**
@@ -148,5 +123,13 @@ public class PDFDestination extends PDFObject {
return false;
}

/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return getIDRef().hashCode();
}

}


+ 10
- 42
src/java/org/apache/fop/pdf/PDFDests.java View File

@@ -19,61 +19,29 @@

package org.apache.fop.pdf;

import org.apache.fop.area.DestinationData;
import java.util.List;

/**
* class representing an /Dests object (part of a name dictionary)
* class representing an /Dests dictionary object
*/
public class PDFDests extends PDFObject {

private String limitsRef;
public class PDFDests extends PDFNameTreeNode {

/**
* create a named destination
* Create a named destination
*/
public PDFDests(String limitsRef) {
public PDFDests() {
/* generic creation of PDF object */
super();
this.limitsRef = limitsRef;
}

/**
* @see org.apache.fop.pdf.PDFObject#toPDFString()
* Create a named destination
* @param destinationList a list of destinations
*/
public String toPDFString() {
String s = getObjectID()
+ "<<\n"
+ "/Dests " + limitsRef
+ "\n>>\nendobj\n";
return s;
public PDFDests(List destinationList) {
this();
setNames(new PDFArray(destinationList));
}

/*
* 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;
}
}


+ 100
- 0
src/java/org/apache/fop/pdf/PDFDictionary.java View File

@@ -0,0 +1,100 @@
/*
* 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.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* Class representing a PDF dictionary object
*/
public class PDFDictionary extends PDFObject {
/**
* the entry map
*/
protected Map entries = new java.util.HashMap();

/**
* maintains the order of the entries added to the entry map. Whenever you modify
* "entries", always make sure you adjust this list accordingly.
*/
protected List order = new java.util.ArrayList();
/**
* Create the dictionary object
*/
public PDFDictionary() {
/* generic creation of PDF object */
super();
}

/**
* Puts a new name/value pair.
* @param name the name
* @param value the value
*/
public void put(String name, Object value) {
if (!entries.containsKey(name)) {
this.order.add(name);
}
this.entries.put(name, value);
}
/**
* Returns the value given a name.
* @param name the name of the value
* @return the value or null, if there's no value with the given name.
*/
public Object get(String name) {
return this.entries.get(name);
}
/**
* @see org.apache.fop.pdf.PDFObject#toPDFString()
*/
public String toPDFString() {
StringBuffer p = new StringBuffer(64);
if (hasObjectNumber()) {
p.append(getObjectID());
}
p.append("<<");
Iterator iter = this.order.iterator();
while (iter.hasNext()) {
String key = (String)iter.next();
p.append("\n /");
p.append(key);
p.append(" ");
Object obj = this.entries.get(key);
if (obj instanceof PDFWritable) {
p.append(((PDFWritable)obj).toInlinePDFString());
} else {
p.append("(").append(obj).append(")");
}
}
p.append("\n>>\n");
if (hasObjectNumber()) {
p.append("endobj\n");
}
return p.toString();
}

}

+ 47
- 62
src/java/org/apache/fop/pdf/PDFDocument.java View File

@@ -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.
@@ -19,7 +19,7 @@

package org.apache.fop.pdf;

/// Java
// Java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -28,18 +28,15 @@ 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.List;
import java.util.Map;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collections;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.pdf.DestinationComparator;

/* image support modified from work of BoBoGi */
/* font support based on work by Takayuki Takeuchi */

@@ -67,13 +64,13 @@ import org.apache.fop.pdf.DestinationComparator;
public class PDFDocument {

private static final Integer LOCATION_PLACEHOLDER = new Integer(0);
/** Integer constant to represent PDF 1.3 */
public static final int PDF_VERSION_1_3 = 3;

/** Integer constant to represent PDF 1.4 */
public static final int PDF_VERSION_1_4 = 4;
/**
* the encoding to use when converting strings to PDF commandos.
*/
@@ -89,7 +86,7 @@ public class PDFDocument {
/**
* the character position of each object
*/
protected List location = new ArrayList();
protected List location = new java.util.ArrayList();

/** List of objects to write in the trailer */
private List trailerObjects = new java.util.ArrayList();
@@ -111,12 +108,12 @@ public class PDFDocument {

/** Indicates what PDF version is active */
protected int pdfVersion = PDF_VERSION_1_4;
/**
* Indicates which PDF profiles are active (PDF/A, PDF/X etc.)
*/
protected PDFProfile pdfProfile = new PDFProfile(this);
/**
* the /Root object
*/
@@ -208,7 +205,7 @@ public class PDFDocument {
/**
* List of Destinations.
*/
protected List destinations = new java.util.ArrayList();
protected List destinations;

/**
* List of FileSpecs.
@@ -231,19 +228,6 @@ public class PDFDocument {
*/
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;
@@ -283,7 +267,7 @@ public class PDFDocument {
public int getPDFVersion() {
return this.pdfVersion;
}
/** @return the String representing the active PDF version */
public String getPDFVersionString() {
switch (getPDFVersion()) {
@@ -300,7 +284,7 @@ public class PDFDocument {
public PDFProfile getProfile() {
return this.pdfProfile;
}
/**
* Returns the factory for PDF objects.
* @return PDFFactory the factory
@@ -343,7 +327,7 @@ public class PDFDocument {

/**
* Set the creation date of the document.
*
*
* @param date Date to be stored as creation date in the PDF.
*/
public void setCreationDate(Date date) {
@@ -488,9 +472,6 @@ 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);
}
@@ -614,7 +595,12 @@ public class PDFDocument {
* @return the link if found, null otherwise
*/
protected PDFDestination findDestination(PDFDestination compare) {
return (PDFDestination)findPDFObject(destinations, compare);
int index = getDestinationList().indexOf(compare);
if (index >= 0) {
return (PDFDestination)getDestinationList().get(index);
} else {
return null;
}
}

/**
@@ -751,21 +737,27 @@ public class PDFDocument {
}

/**
* Gets the list of named destinations.
*
* @return the list of named destinations.
* Adds a destination to the document.
* @param destination the destination object
*/
public ArrayList getDestinationList() {
return (ArrayList)destinations;
public void addDestination(PDFDestination destination) {
if (this.destinations == null) {
this.destinations = new java.util.ArrayList();
}
this.destinations.add(destination);
}

/**
* Sets whether the document has named destinations.
* Gets the list of named destinations.
*
* @param hasDestinations whether the document has named destinations.
* @return the list of named destinations.
*/
public void setHasDestinations(boolean hasDestinations) {
this.hasDestinations = hasDestinations;
public List getDestinationList() {
if (hasDestinations()) {
return destinations;
} else {
return Collections.EMPTY_LIST;
}
}

/**
@@ -773,17 +765,8 @@ public class PDFDocument {
*
* @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;
public boolean hasDestinations() {
return this.destinations != null && !this.destinations.isEmpty();
}

/**
@@ -933,7 +916,7 @@ public class PDFDocument {
this.position = 0;

getProfile().verifyPDFVersion();
byte[] pdf = encode("%PDF-" + getPDFVersionString() + "\n");
stream.write(pdf);
this.position += pdf.length;
@@ -970,7 +953,7 @@ public class PDFDocument {
}
}
}
/**
* write the trailer
*
@@ -978,11 +961,13 @@ public class PDFDocument {
* @throws IOException if there is an exception writing to the output stream
*/
public void outputTrailer(OutputStream stream) throws IOException {
if (hasDestinations) {
Collections.sort((ArrayList)destinations, new DestinationComparator());
limits = getFactory().makeLimits((ArrayList)destinations);
dests = getFactory().makeDests(limits.referencePDF());
this.root.setNames(dests.referencePDF());
if (hasDestinations()) {
Collections.sort(destinations, new DestinationComparator());
dests = getFactory().makeDests(destinations);
if (this.root.getNames() == null) {
this.root.setNames(getFactory().makeNames());
}
this.root.getNames().setDests(dests);
}
output(stream);
for (int count = 0; count < trailerObjects.size(); count++) {
@@ -1061,4 +1046,4 @@ public class PDFDocument {
return pdfBytes.length;
}

}
}

+ 56
- 50
src/java/org/apache/fop/pdf/PDFFactory.java View File

@@ -54,8 +54,6 @@ 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.
@@ -747,13 +745,11 @@ public class PDFFactory {

for (currentPosition = 0; currentPosition < lastPosition;
currentPosition++) { // for every consecutive color pair
PDFColor currentColor =
(PDFColor)theColors.get(currentPosition);
PDFColor currentColor = (PDFColor)theColors.get(currentPosition);
PDFColor nextColor = (PDFColor)theColors.get(currentPosition
+ 1);
// colorspace must be consistant
if (getDocument().getColorSpace()
!= currentColor.getColorSpace()) {
if (getDocument().getColorSpace() != currentColor.getColorSpace()) {
currentColor.setColorSpace(
getDocument().getColorSpace());
}
@@ -827,8 +823,7 @@ public class PDFFactory {
if (existing != null) {
return existing;
} else {
getDocument().registerObject(newdest);
getDocument().setHasDestinations(true);
getDocument().addDestination(newdest);
return newdest;
}
}
@@ -836,58 +831,72 @@ public class PDFFactory {
/**
* Make a named destination.
*
* @param destinationData the DestinationData object that holds the info about this named destination
* @return the new PDF named destination object
* @param idRef ID Reference for this destination (the name of the destination)
* @param goToRef Object reference to the GoTo Action
* @return the newly created destrination
*/
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);
public PDFDestination makeDestination(String idRef, Object goToRef) {
PDFDestination destination = new PDFDestination(idRef, goToRef);
return getUniqueDestination(destination);
}

/**
* Create/find a named destination object.
*
* @param idRef The ID of this destination. This will be used for the name.
* @param goToRef A PDF reference to the associated /GoTo
* @param pv The PageViewport of the destination area. Only for informational purposes.
*
* @return The new or existing named destination
* Make a names dictionary (the /Names object).
* @return the new PDFNames object
*/
public PDFDestination makeDestination(String idRef, String goToRef, PageViewport pv) {
PDFDestination destination = new PDFDestination(idRef, goToRef, pv);
return getUniqueDestination(destination);
public PDFNames makeNames() {
PDFNames names = new PDFNames();
getDocument().registerObject(names);
return names;
}

/**
* Make a the head object of the name dictionary (the /Dests object).
*
* @param destinationList a list of PDFDestination instances
* @return the new PDFDests object
*/
public PDFDests makeDests(String limitsRef) {
PDFDests dests = new PDFDests(limitsRef);
public PDFDests makeDests(List destinationList) {
PDFDests dests;
final boolean deep = true;
//true for a "deep" structure (one node per entry), true for a "flat" structure
if (deep) {
dests = new PDFDests();
PDFArray kids = new PDFArray();
Iterator iter = destinationList.iterator();
while (iter.hasNext()) {
PDFDestination dest = (PDFDestination)iter.next();
PDFNameTreeNode node = new PDFNameTreeNode();
getDocument().registerObject(node);
node.setLowerLimit(dest.getIDRef());
node.setUpperLimit(dest.getIDRef());
node.setNames(new PDFArray());
node.getNames().add(dest);
kids.add(node);
}
dests.setLowerLimit(((PDFNameTreeNode)kids.get(0)).getLowerLimit());
dests.setUpperLimit(((PDFNameTreeNode)kids.get(kids.length() - 1)).getUpperLimit());
dests.setKids(kids);
} else {
dests = new PDFDests(destinationList);
}
getDocument().registerObject(dests);

return dests;
}

/**
* Make a the limits object of the name dictionary (the /Limits object).
* Make a name tree node.
*
* @return the new PDFLimits object
* @return the new name tree node
*/
public PDFLimits makeLimits(ArrayList destinationList) {
PDFLimits limits = new PDFLimits(destinationList);
getDocument().registerObject(limits);

return limits;
}

public PDFNameTreeNode makeNameTreeNode() {
PDFNameTreeNode node = new PDFNameTreeNode();
getDocument().registerObject(node);
return node;
}
/* ========================= links ===================================== */

// Some of the "yoffset-only" functions in this part are obsolete and can
// possibly be removed or deprecated. Some are still called by PDFGraphics2D
// (although that could be changed, they don't need the yOffset param anyway).
@@ -1182,15 +1191,12 @@ public class PDFFactory {
* cmap.addContents();
* this.objects.add(cmap);
*/
font =
(PDFFontNonBase14)PDFFont.createFont(fontname, fonttype,
basefont,
"Identity-H");
font = (PDFFontNonBase14)PDFFont.createFont(fontname, fonttype,
basefont, "Identity-H");
} else {

font =
(PDFFontNonBase14)PDFFont.createFont(fontname, fonttype,
basefont, encoding);
font = (PDFFontNonBase14)PDFFont.createFont(fontname, fonttype,
basefont, encoding);
}
getDocument().registerObject(font);

@@ -1203,12 +1209,12 @@ public class PDFFactory {
} else {
cidMetrics = (CIDFont)metrics;
}
PDFCIDSystemInfo sysInfo =
new PDFCIDSystemInfo(cidMetrics.getRegistry(),
PDFCIDSystemInfo sysInfo
= new PDFCIDSystemInfo(cidMetrics.getRegistry(),
cidMetrics.getOrdering(),
cidMetrics.getSupplement());
PDFCIDFont cidFont =
new PDFCIDFont(basefont,
PDFCIDFont cidFont
= new PDFCIDFont(basefont,
cidMetrics.getCIDType(),
cidMetrics.getDefaultWidth(),
getSubsetWidths(cidMetrics), sysInfo,

+ 0
- 93
src/java/org/apache/fop/pdf/PDFLimits.java View File

@@ -1,93 +0,0 @@
/*
* 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.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;
}
}


+ 121
- 0
src/java/org/apache/fop/pdf/PDFNameTreeNode.java View File

@@ -0,0 +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 name tree node.
*/
public class PDFNameTreeNode extends PDFDictionary {

private static final String KIDS = "Kids";
private static final String NAMES = "Names";
private static final String LIMITS = "Limits";

/**
* create a named destination
*/
public PDFNameTreeNode() {
/* 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 Names array.
* @param names the Names array
*/
public void setNames(PDFArray names) {
put(NAMES, names);
}
/**
* Returns the Names array.
* @return the Names array
*/
public PDFArray getNames() {
return (PDFArray)get(NAMES);
}
/**
* Sets the lower limit value of the Limits array.
* @param key the lower limit value
*/
public void setLowerLimit(String key) {
PDFArray limits = prepareLimitsArray();
limits.set(0, key);
}

/**
* Returns the lower limit value of the Limits array.
* @return the lower limit value
*/
public String getLowerLimit() {
PDFArray limits = prepareLimitsArray();
return (String)limits.get(0);
}

/**
* Sets the upper limit value of the Limits array.
* @param key the upper limit value
*/
public void setUpperLimit(String key) {
PDFArray limits = prepareLimitsArray();
limits.set(1, key);
}

/**
* Returns the upper limit value of the Limits array.
* @return the upper limit value
*/
public String getUpperLimit() {
PDFArray limits = prepareLimitsArray();
return (String)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;
}
}


+ 51
- 0
src/java/org/apache/fop/pdf/PDFNames.java View File

@@ -0,0 +1,51 @@
/*
* 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 Names object
*/
public class PDFNames extends PDFDictionary {
/**
* Create the Names object
*/
public PDFNames() {
/* generic creation of PDF object */
super();
}

/**
* Returns the Dests object
* @return the Dests object, or null if it's not used
*/
public PDFDests getDests() {
return (PDFDests)get("Dests");
}
/**
* Set the Dests object
* @param dests the Dests object
*/
public void setDests(PDFDests dests) {
put("Dests", dests);
}
}

+ 26
- 1
src/java/org/apache/fop/pdf/PDFObject.java View File

@@ -37,7 +37,7 @@ import org.apache.commons.logging.LogFactory;
* Object has a number and a generation (although the generation will always
* be 0 in new documents).
*/
public abstract class PDFObject {
public abstract class PDFObject implements PDFWritable {

/** logger for all PDFObjects (and descendants) */
protected static Log log = LogFactory.getLog(PDFObject.class.getName());
@@ -138,10 +138,22 @@ public abstract class PDFObject {
* @return the reference string
*/
public String referencePDF() {
if (!hasObjectNumber()) {
throw new IllegalArgumentException(
"Cannot reference this object. It doesn't have an object number");
}
String ref = getObjectNumber() + " " + getGeneration() + " R";
return ref;
}

/**
* Creates and returns a reference to this object.
* @return the object reference
*/
public PDFReference makeReference() {
return new PDFReference(this);
}
/**
* Write the PDF represention of this object
*
@@ -178,6 +190,19 @@ public abstract class PDFObject {
+ "Use output(OutputStream) instead.");
}
/**
* 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.

+ 67
- 0
src/java/org/apache/fop/pdf/PDFReference.java View File

@@ -0,0 +1,67 @@
/*
* 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.lang.ref.Reference;
import java.lang.ref.SoftReference;

/**
* Class representing a PDF object reference. The object holds a soft reference to the actual
* PDF object so the garbage collector can free the object if it's not referenced elsewhere. The
* important thing about the class is the reference information to the actual PDF object in the
* PDF file.
*/
public class PDFReference implements PDFWritable {
private String indirectReference;
private Reference objReference;
/**
* Creates a new PDF reference.
* @param obj the object to be referenced
*/
public PDFReference(PDFObject obj) {
this.indirectReference = obj.referencePDF();
this.objReference = new SoftReference(obj);
}

/**
* Returns the PDF object
* @return the PDF object, or null if it has been released
*/
public PDFObject getObject() {
if (this.objReference != null) {
PDFObject obj = (PDFObject)this.objReference.get();
if (obj == null) {
this.objReference = null;
}
return obj;
} else {
return null;
}
}
/** @see org.apache.fop.pdf.PDFWritable#toInlinePDFString() */
public String toInlinePDFString() {
return this.indirectReference;
}
}

+ 20
- 16
src/java/org/apache/fop/pdf/PDFRoot.java View File

@@ -20,7 +20,6 @@
package org.apache.fop.pdf;

import java.util.List;
import java.util.ArrayList;

/**
* class representing a Root (/Catalog) object
@@ -63,11 +62,8 @@ 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;
/** the /Dests object, if this PDF has a Names Dictionary */
private PDFNames names;

private int pageMode = PAGEMODE_USENONE;

@@ -133,12 +129,20 @@ public class PDFRoot extends PDFObject {
}
/**
* Set the optional Metadata object.
* @param meta the Metadata object
* @since PDF 1.4
* Set the Names object.
* @param names the Names object
* @since PDF 1.2
*/
public void setNames(PDFNames names) {
this.names = names;
}
/**
* @return the Names object if set, null otherwise.
* @since PDF 1.2
*/
public void setNames(String referencePDF) {
this.namesReferencePDF = referencePDF;
public PDFNames getNames() {
return this.names;
}
/**
@@ -175,7 +179,7 @@ public class PDFRoot extends PDFObject {
public String toPDFString() {
StringBuffer p = new StringBuffer(128);
p.append(getObjectID());
p.append("<< /Type /Catalog\n/Pages "
p.append("<< /Type /Catalog\n /Pages "
+ this.rootPages.referencePDF()
+ "\n");
if (outline != null) {
@@ -197,17 +201,17 @@ public class PDFRoot extends PDFObject {
break;
}
}
if (getDocumentSafely().getHasDestinations() && namesReferencePDF != null) {
p.append(" /Names " + namesReferencePDF + "\n");
if (getDocumentSafely().hasDestinations() && getNames() != null) {
p.append(" /Names " + getNames().referencePDF() + "\n");
}
if (getMetadata() != null
&& getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) {
p.append("/Metadata " + getMetadata().referencePDF() + "\n");
p.append(" /Metadata " + getMetadata().referencePDF() + "\n");
}
if (this.outputIntents != null
&& this.outputIntents.size() > 0
&& getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) {
p.append("/OutputIntents [");
p.append(" /OutputIntents [");
for (int i = 0, c = this.outputIntents.size(); i < c; i++) {
PDFOutputIntent outputIntent = (PDFOutputIntent)this.outputIntents.get(i);
if (i > 0) {

+ 36
- 0
src/java/org/apache/fop/pdf/PDFWritable.java View File

@@ -0,0 +1,36 @@
/*
* 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;

/**
* 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.
*/
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
*/
String toInlinePDFString();
}

+ 1
- 1
src/java/org/apache/fop/render/AbstractRenderer.java View File

@@ -165,7 +165,7 @@ public abstract class AbstractRenderer
/**
* @see org.apache.fop.render.Renderer#processOffDocumentItem(OffDocumentItem)
*/
public void processOffDocumentItem(OffDocumentItem oDI) { }
public void processOffDocumentItem(OffDocumentItem odi) { }

/** @see org.apache.fop.render.Renderer#getGraphics2DAdapter() */
public Graphics2DAdapter getGraphics2DAdapter() {

+ 2
- 2
src/java/org/apache/fop/render/Renderer.java View File

@@ -113,9 +113,9 @@ public interface Renderer {
* document (e.g., PDF bookmarks). Note - not all renderers will process
* all off-document items.
*
* @param ext The extension element to be rendered
* @param odi The off-document item to be rendered
*/
void processOffDocumentItem(OffDocumentItem ext);
void processOffDocumentItem(OffDocumentItem odi);

/**
* @return the adapter for painting Java2D images (or null if not supported)

+ 8
- 10
src/java/org/apache/fop/render/pdf/PDFRenderer.java View File

@@ -83,6 +83,7 @@ import org.apache.fop.pdf.PDFEncryptionManager;
import org.apache.fop.pdf.PDFEncryptionParams;
import org.apache.fop.pdf.PDFFactory;
import org.apache.fop.pdf.PDFFilterList;
import org.apache.fop.pdf.PDFGoTo;
import org.apache.fop.pdf.PDFICCBasedColorSpace;
import org.apache.fop.pdf.PDFICCStream;
import org.apache.fop.pdf.PDFGoTo;
@@ -570,11 +571,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
* @see org.apache.fop.render.Renderer#processOffDocumentItem(OffDocumentItem)
*/
public void processOffDocumentItem(OffDocumentItem odi) {
// render Destinations
if (odi instanceof DestinationData) {
// render Destinations
renderDestination((DestinationData) odi);
// render Bookmark-Tree
} else if (odi instanceof BookmarkData) {
// render Bookmark-Tree
renderBookmarkTree((BookmarkData) odi);
} else if (odi instanceof OffDocumentExtensionAttachment) {
ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)odi).getAttachment();
@@ -588,15 +589,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
String targetID = dd.getIDRef();
if (targetID != null && targetID.length() > 0) {
PageViewport pv = dd.getPageViewport();
if (pv != null) {
String pvKey = pv.getKey();
PDFGoTo gt = getPDFGoToForID(targetID, pvKey);
// create/find and register PDFDestination object:
pdfDoc.getFactory().makeDestination(targetID, gt.referencePDF(), pv);
} else {
log.warn("DestinationData item with IDRef \""
+ targetID + "\" has a null PageViewport.");
if (pv == null) {
log.warn("Unresolved destination item received: " + dd.getIDRef());
}
PDFGoTo gt = getPDFGoToForID(targetID, pv.getKey());
pdfDoc.getFactory().makeDestination(
dd.getIDRef(), gt.makeReference());
} else {
log.warn("DestinationData item with null or empty IDRef received.");
}

Loading…
Cancel
Save