aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-10-18 16:06:31 +0000
committerJeremias Maerki <jeremias@apache.org>2005-10-18 16:06:31 +0000
commit20be3fe07bda82ab51d180744cba05ed707d8276 (patch)
treee7b9a68ba93e08aa7b77fd8b38a8cafbf7a69fda /src/java
parent4273340fedb25e6f3ea47f5750d3c5592fd4630f (diff)
downloadxmlgraphics-fop-20be3fe07bda82ab51d180744cba05ed707d8276.tar.gz
xmlgraphics-fop-20be3fe07bda82ab51d180744cba05ed707d8276.zip
Fix for internal forward references in PDF output (basic-link with internal-destination):
Implemented by making out-of-order processing possible. The problem will still surface if supportsOutOfOrder() returns false. PDF library now supports the addition of pages in non-consecutive order. This is a backwards-compatible change. The old behaviour and the old method signatures are still in place. PageViewport now carries a page index which doesn't represent the page number but the overall index of the page within the current rendering run. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@326133 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/fop/area/AreaTreeModel.java10
-rw-r--r--src/java/org/apache/fop/area/PageViewport.java17
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java27
-rw-r--r--src/java/org/apache/fop/pdf/PDFPage.java44
-rw-r--r--src/java/org/apache/fop/pdf/PDFPages.java22
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java39
6 files changed, 112 insertions, 47 deletions
diff --git a/src/java/org/apache/fop/area/AreaTreeModel.java b/src/java/org/apache/fop/area/AreaTreeModel.java
index 34a4d39fa..75783def8 100644
--- a/src/java/org/apache/fop/area/AreaTreeModel.java
+++ b/src/java/org/apache/fop/area/AreaTreeModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import org.apache.commons.logging.LogFactory;
*/
public class AreaTreeModel {
private List pageSequenceList = null;
+ private int currentPageSequenceIndex = -1;
private List currentPageSequencePageList;
private List offDocumentItems = new java.util.ArrayList();
@@ -57,6 +58,7 @@ public class AreaTreeModel {
public void startPageSequence(LineArea title) {
currentPageSequencePageList = new java.util.ArrayList();
pageSequenceList.add(currentPageSequencePageList);
+ currentPageSequenceIndex = pageSequenceList.size() - 1;
}
/**
@@ -65,6 +67,12 @@ public class AreaTreeModel {
*/
public void addPage(PageViewport page) {
currentPageSequencePageList.add(page);
+ int pageIndex = 0;
+ for (int i = 0; i < currentPageSequenceIndex; i++) {
+ pageIndex += ((List)pageSequenceList.get(i)).size();
+ }
+ pageIndex += currentPageSequencePageList.size() - 1;
+ page.setPageIndex(pageIndex);
}
/**
diff --git a/src/java/org/apache/fop/area/PageViewport.java b/src/java/org/apache/fop/area/PageViewport.java
index 046bd4698..2cced4a5f 100644
--- a/src/java/org/apache/fop/area/PageViewport.java
+++ b/src/java/org/apache/fop/area/PageViewport.java
@@ -48,6 +48,7 @@ public class PageViewport implements Resolvable, Cloneable {
private Rectangle2D viewArea;
private boolean clip = false;
private String pageNumberString = null;
+ private int pageIndex = -1; //-1 = undetermined
private SimplePageMaster spm = null;
private boolean blank;
@@ -138,6 +139,22 @@ public class PageViewport implements Resolvable, Cloneable {
}
/**
+ * Sets the page index of the page in this rendering run.
+ * @param index the page index (zero-based), -1 if it is undetermined
+ */
+ public void setPageIndex(int index) {
+ this.pageIndex = index;
+ }
+
+ /**
+ * @return the overall page index of the page in this rendering run (zero-based,
+ * -1 if it is undetermined).
+ */
+ public int getPageIndex() {
+ return this.pageIndex;
+ }
+
+ /**
* Get the key for this page viewport.
* This is used so that a serializable key can be used to
* lookup the page or some other reference.
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index 28a14e8ef..bacb3251c 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -133,26 +133,43 @@ public class PDFFactory {
* PDFDocument later using addObject().
*
* @param resources resources object to use
- * @param pagewidth width of the page in points
- * @param pageheight height of the page in points
+ * @param pageWidth width of the page in points
+ * @param pageHeight height of the page in points
+ * @param pageIndex index of the page (zero-based)
*
* @return the created /Page object
*/
public PDFPage makePage(PDFResources resources,
- int pagewidth, int pageheight) {
+ int pageWidth, int pageHeight, int pageIndex) {
/*
* create a PDFPage with the next object number, the given
* resources, contents and dimensions
*/
PDFPage page = new PDFPage(resources,
- pagewidth, pageheight);
+ pageWidth, pageHeight, pageIndex);
getDocument().assignObjectNumber(page);
getDocument().getPages().addPage(page);
return page;
}
+ /**
+ * Make a /Page object. The page is assigned an object number immediately
+ * so references can already be made. The page must be added to the
+ * PDFDocument later using addObject().
+ *
+ * @param resources resources object to use
+ * @param pageWidth width of the page in points
+ * @param pageHeight height of the page in points
+ *
+ * @return the created /Page object
+ */
+ public PDFPage makePage(PDFResources resources,
+ int pageWidth, int pageHeight) {
+ return makePage(resources, pageWidth, pageHeight, -1);
+ }
+
/* ========================= functions ================================= */
/**
diff --git a/src/java/org/apache/fop/pdf/PDFPage.java b/src/java/org/apache/fop/pdf/PDFPage.java
index 74932403f..bd00cbd2d 100644
--- a/src/java/org/apache/fop/pdf/PDFPage.java
+++ b/src/java/org/apache/fop/pdf/PDFPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,6 +48,9 @@ public class PDFPage extends PDFResourceContext {
*/
protected int pageheight;
+ /** the page index (zero-based) */
+ protected int pageIndex;
+
/**
* Duration to display page
*/
@@ -59,41 +62,38 @@ public class PDFPage extends PDFResourceContext {
protected TransitionDictionary trDictionary = null;
/**
- * create a /Page object
+ * Create a /Page object
*
* @param resources the /Resources object
* @param contents the content stream
- * @param pagewidth the page's width in points
- * @param pageheight the page's height in points
+ * @param pageWidth the page's width in points
+ * @param pageHeight the page's height in points
+ * @param pageIndex the page's zero-based index (or -1 if the page number is auto-determined)
*/
public PDFPage(PDFResources resources, PDFStream contents,
- int pagewidth, int pageheight) {
+ int pageWidth, int pageHeight, int pageIndex) {
/* generic creation of object */
super(resources);
/* set fields using parameters */
this.contents = contents;
- this.pagewidth = pagewidth;
- this.pageheight = pageheight;
+ this.pagewidth = pageWidth;
+ this.pageheight = pageHeight;
+ this.pageIndex = pageIndex;
}
/**
- * create a /Page object
+ * Create a /Page object
*
* @param resources the /Resources object
- * @param pagewidth the page's width in points
- * @param pageheight the page's height in points
+ * @param pageWidth the page's width in points
+ * @param pageHeight the page's height in points
+ * @param pageIndex the page's zero-based index (or -1 if the page number is auto-determined)
*/
public PDFPage(PDFResources resources,
- int pagewidth, int pageheight) {
-
- /* generic creation of object */
- super(resources);
-
- /* set fields using parameters */
- this.pagewidth = pagewidth;
- this.pageheight = pageheight;
+ int pageWidth, int pageHeight, int pageIndex) {
+ this(resources, null, pageWidth, pageHeight, pageIndex);
}
/**
@@ -144,6 +144,14 @@ public class PDFPage extends PDFResourceContext {
}
/**
+ * @return the page Index of this page (zero-based), -1 if it the page index should
+ * automatically be determined.
+ */
+ public int getPageIndex() {
+ return this.pageIndex;
+ }
+
+ /**
* @see org.apache.fop.pdf.PDFObject#toPDFString()
*/
public String toPDFString() {
diff --git a/src/java/org/apache/fop/pdf/PDFPages.java b/src/java/org/apache/fop/pdf/PDFPages.java
index aae5c6c90..6ce4830e1 100644
--- a/src/java/org/apache/fop/pdf/PDFPages.java
+++ b/src/java/org/apache/fop/pdf/PDFPages.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,7 +72,19 @@ public class PDFPages extends PDFObject {
* @param page the child page
*/
public void notifyKidRegistered(PDFPage page) {
- this.kids.add(page.referencePDF());
+ int idx = page.getPageIndex();
+ if (idx >= 0) {
+ while (idx > this.kids.size() - 1) {
+ this.kids.add(null);
+ }
+ if (this.kids.get(idx) != null) {
+ throw new IllegalStateException("A page already exists at index "
+ + idx + " (zero-based).");
+ }
+ this.kids.set(idx, page.referencePDF());
+ } else {
+ this.kids.add(page.referencePDF());
+ }
}
/**
@@ -102,7 +114,11 @@ public class PDFPages extends PDFObject {
append(this.getCount()).
append("\n/Kids [");
for (int i = 0; i < kids.size(); i++) {
- sb.append(kids.get(i)).append(" ");
+ Object kid = kids.get(i);
+ if (kid == null) {
+ throw new IllegalStateException("Gap in the kids list!");
+ }
+ sb.append(kid).append(" ");
}
sb.append("] >>\nendobj\n");
return sb.toString();
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index ba8b6796e..70beb20fb 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -283,7 +283,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
* @see org.apache.fop.render.Renderer#supportsOutOfOrder()
*/
public boolean supportsOutOfOrder() {
- return false;
+ //return false;
+ return true;
}
/**
@@ -402,6 +403,14 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
* @param page the page to prepare
*/
public void preparePage(PageViewport page) {
+ setupPage(page);
+ if (pages == null) {
+ pages = new java.util.HashMap();
+ }
+ pages.put(page, currentPage);
+ }
+
+ private void setupPage(PageViewport page) {
this.pdfResources = this.pdfDoc.getResources();
Rectangle2D bounds = page.getViewArea();
@@ -409,15 +418,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
double h = bounds.getHeight();
currentPage = this.pdfDoc.getFactory().makePage(
this.pdfResources,
- (int) Math.round(w / 1000), (int) Math.round(h / 1000));
- if (pages == null) {
- pages = new java.util.HashMap();
- }
- pages.put(page, currentPage);
+ (int) Math.round(w / 1000), (int) Math.round(h / 1000),
+ page.getPageIndex());
pageReferences.put(page.getKey(), currentPage.referencePDF());
pvReferences.put(page.getKey(), page);
}
-
+
/**
* This method creates a pdf stream for the current page
* uses it as the contents of a new page. The page is written
@@ -428,22 +434,15 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
throws IOException, FOPException {
if (pages != null
&& (currentPage = (PDFPage) pages.get(page)) != null) {
+ //Retrieve previously prepared page (out-of-line rendering)
pages.remove(page);
- Rectangle2D bounds = page.getViewArea();
- double h = bounds.getHeight();
- pageHeight = (int) h;
} else {
- this.pdfResources = this.pdfDoc.getResources();
- Rectangle2D bounds = page.getViewArea();
- double w = bounds.getWidth();
- double h = bounds.getHeight();
- pageHeight = (int) h;
- currentPage = this.pdfDoc.getFactory().makePage(
- this.pdfResources,
- (int) Math.round(w / 1000), (int) Math.round(h / 1000));
- pageReferences.put(page.getKey(), currentPage.referencePDF());
- pvReferences.put(page.getKey(), page);
+ setupPage(page);
}
+ Rectangle2D bounds = page.getViewArea();
+ double h = bounds.getHeight();
+ pageHeight = (int) h;
+
currentStream = this.pdfDoc.getFactory()
.makeStream(PDFFilterList.CONTENT_FILTER, false);