From 0dafe4daaa3857d147ab4bfa41f54bb817213356 Mon Sep 17 00:00:00 2001 From: Keiron Liddle Date: Sun, 3 Nov 2002 16:24:22 +0000 Subject: [PATCH] fixed link/resolving problem made sure area tree is serializable git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195405 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/area/AreaTree.java | 31 +++++++++---- .../fop/area/CachedRenderPagesModel.java | 46 ++++++++++--------- src/org/apache/fop/area/PageViewport.java | 11 +++++ src/org/apache/fop/area/Trait.java | 4 +- src/org/apache/fop/datatypes/ColorType.java | 3 +- src/org/apache/fop/fo/flow/BasicLink.java | 4 +- src/org/apache/fop/pdf/PDFDocument.java | 19 +++++--- src/org/apache/fop/pdf/PDFGoTo.java | 4 +- src/org/apache/fop/pdf/PDFPage.java | 1 - .../apache/fop/render/pdf/PDFRenderer.java | 32 +++++++++---- src/org/apache/fop/svg/PDFGraphics2D.java | 2 +- src/org/apache/fop/traits/BorderProps.java | 8 +++- 12 files changed, 109 insertions(+), 56 deletions(-) diff --git a/src/org/apache/fop/area/AreaTree.java b/src/org/apache/fop/area/AreaTree.java index b82368c0d..8d03f6a0f 100644 --- a/src/org/apache/fop/area/AreaTree.java +++ b/src/org/apache/fop/area/AreaTree.java @@ -397,23 +397,31 @@ public class AreaTree { public void addPage(PageViewport page) { super.addPage(page); - // check prepared pages - boolean cont = checkPreparedPages(); - - // if page finished - if (cont && page.isResolved()) { + // for links the renderer needs to prepare the page + // it is more appropriate to do this after queued pages but + // it will mean that the renderer has not prepared a page that + // could be referenced + boolean done = renderer.supportsOutOfOrder() && page.isResolved(); + if (done) { try { renderer.renderPage(page); } catch (Exception e) { // use error handler to handle this FOP or IO Exception + e.printStackTrace(); } page.clear(); } else { preparePage(page); } - renderExtensions(pendingExt); - pendingExt.clear(); + + // check prepared pages + boolean cont = checkPreparedPages(page); + + if (cont) { + renderExtensions(pendingExt); + pendingExt.clear(); + } } /** @@ -422,7 +430,7 @@ public class AreaTree { * false if the renderer doesn't support out of order * rendering and there are pending pages */ - protected boolean checkPreparedPages() { + protected boolean checkPreparedPages(PageViewport newpage) { for (Iterator iter = prepared.iterator(); iter.hasNext();) { PageViewport p = (PageViewport)iter.next(); if (p.isResolved()) { @@ -430,6 +438,7 @@ public class AreaTree { renderer.renderPage(p); } catch (Exception e) { // use error handler to handle this FOP or IO Exception + e.printStackTrace(); } p.clear(); iter.remove(); @@ -491,7 +500,11 @@ public class AreaTree { */ public void endDocument() { // render any pages that had unresolved ids - checkPreparedPages(); + checkPreparedPages(null); + + renderExtensions(pendingExt); + pendingExt.clear(); + renderExtensions(endDocExt); } } diff --git a/src/org/apache/fop/area/CachedRenderPagesModel.java b/src/org/apache/fop/area/CachedRenderPagesModel.java index f706a8de4..43c35f91b 100644 --- a/src/org/apache/fop/area/CachedRenderPagesModel.java +++ b/src/org/apache/fop/area/CachedRenderPagesModel.java @@ -45,30 +45,33 @@ public class CachedRenderPagesModel extends AreaTree.RenderPagesModel { * false if the renderer doesn't support out of order * rendering and there are pending pages */ - protected boolean checkPreparedPages() { + protected boolean checkPreparedPages(PageViewport newpage) { for (Iterator iter = prepared.iterator(); iter.hasNext();) { PageViewport p = (PageViewport)iter.next(); if (p.isResolved()) { - try { - // load page from cache - String name = (String)pageMap.get(p); - File temp = new File(name); - System.out.println("page serialized to: " + temp.length()); - ObjectInputStream in = new ObjectInputStream( - new BufferedInputStream( - new FileInputStream(temp))); - p.loadPage(in); - in.close(); - temp.delete(); - pageMap.remove(p); - } catch (Exception e) { - e.printStackTrace(); + if(p != newpage) { + try { + // load page from cache + String name = (String)pageMap.get(p); + File temp = new File(name); + System.out.println("page serialized to: " + temp.length()); + ObjectInputStream in = new ObjectInputStream( + new BufferedInputStream( + new FileInputStream(temp))); + p.loadPage(in); + in.close(); + temp.delete(); + pageMap.remove(p); + } catch (Exception e) { + e.printStackTrace(); + } } try { renderer.renderPage(p); } catch (Exception e) { // use error handler to handle this FOP or IO Exception + e.printStackTrace(); } p.clear(); iter.remove(); @@ -78,18 +81,19 @@ public class CachedRenderPagesModel extends AreaTree.RenderPagesModel { } } } + if(newpage != null && newpage.getPage() != null) { + savePage(newpage); + } return renderer.supportsOutOfOrder() || prepared.isEmpty(); } /** - * Prepare a page. - * This uses the parent to prepare the page. - * It then saves the contents of the page to a file. + * Save a page. + * It saves the contents of the page to a file. + * * @param page the page to prepare */ - protected void preparePage(PageViewport page) { - super.preparePage(page); - + protected void savePage(PageViewport page) { try { // save page to cache ObjectOutputStream tempstream; diff --git a/src/org/apache/fop/area/PageViewport.java b/src/org/apache/fop/area/PageViewport.java index e1e15dba0..aaf495d14 100644 --- a/src/org/apache/fop/area/PageViewport.java +++ b/src/org/apache/fop/area/PageViewport.java @@ -89,6 +89,17 @@ public class PageViewport implements Resolveable, Cloneable { return pageNumber; } + /** + * 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. + * + * @return a unique page viewport key for this area tree + */ + public String getKey() { + return toString(); + } + /** * Add an unresolved id to this page. * All unresolved ids for the contents of this page are diff --git a/src/org/apache/fop/area/Trait.java b/src/org/apache/fop/area/Trait.java index b9ebd8f76..a8943e577 100644 --- a/src/org/apache/fop/area/Trait.java +++ b/src/org/apache/fop/area/Trait.java @@ -117,7 +117,7 @@ public class Trait implements Serializable { shmTraitInfo = new HashMap(); shmTraitInfo.put(ID_LINK, new TraitInfo("id-link", String.class)); shmTraitInfo.put(INTERNAL_LINK, - new TraitInfo("internal-link", PageViewport.class)); + new TraitInfo("internal-link", String.class)); shmTraitInfo.put(EXTERNAL_LINK, new TraitInfo("external-link", String.class)); shmTraitInfo.put(FONT_NAME, @@ -229,7 +229,7 @@ public class Trait implements Serializable { return null; } - public static class Background { + public static class Background implements Serializable { public ColorType color = null; public String url = null; public int repeat; diff --git a/src/org/apache/fop/datatypes/ColorType.java b/src/org/apache/fop/datatypes/ColorType.java index cab72e557..eae150ce5 100644 --- a/src/org/apache/fop/datatypes/ColorType.java +++ b/src/org/apache/fop/datatypes/ColorType.java @@ -8,11 +8,12 @@ package org.apache.fop.datatypes; import java.util.*; +import java.io.Serializable; /** * a colour quantity in XSL */ -public class ColorType { +public class ColorType implements Serializable { /** * the red component diff --git a/src/org/apache/fop/fo/flow/BasicLink.java b/src/org/apache/fop/fo/flow/BasicLink.java index c692629ad..bd1b72088 100644 --- a/src/org/apache/fop/fo/flow/BasicLink.java +++ b/src/org/apache/fop/fo/flow/BasicLink.java @@ -63,7 +63,7 @@ public class BasicLink extends Inline { } else { PageViewport page = parentLM.resolveRefID(link); if (page != null) { - area.addTrait(Trait.INTERNAL_LINK, page); + area.addTrait(Trait.INTERNAL_LINK, page.getKey()); } else { LinkResolver res = new LinkResolver(link, area); parentLM.addUnresolvedArea(link, res); @@ -148,7 +148,7 @@ public class BasicLink extends Inline { resolved = true; if (idRef.equals(id) && pages != null) { PageViewport page = (PageViewport)pages.get(0); - area.addTrait(Trait.INTERNAL_LINK, page); + area.addTrait(Trait.INTERNAL_LINK, page.getKey()); } } } diff --git a/src/org/apache/fop/pdf/PDFDocument.java b/src/org/apache/fop/pdf/PDFDocument.java index aa672b79b..dc1636381 100644 --- a/src/org/apache/fop/pdf/PDFDocument.java +++ b/src/org/apache/fop/pdf/PDFDocument.java @@ -1229,7 +1229,7 @@ public class PDFDocument { * @return the PDFLink object created */ public PDFLink makeLink(Rectangle2D rect, String destination, - int linkType) { + int linkType, float yoffset) { PDFLink linkObject; PDFAction action; @@ -1240,7 +1240,10 @@ public class PDFDocument { if (linkType == PDFLink.EXTERNAL) { // check destination - if (destination.endsWith(".pdf")) { // FileSpec + if (destination.startsWith("http://")) { + PDFUri uri = new PDFUri(destination); + link.setAction(uri); + } else if (destination.endsWith(".pdf")) { // FileSpec PDFFileSpec fileSpec = new PDFFileSpec(++this.objectcount, destination); this.objects.add(fileSpec); @@ -1267,17 +1270,19 @@ public class PDFDocument { PDFUri uri = new PDFUri(destination); link.setAction(uri); } - } else { // linkType is internal - String goToReference = getGoToReference(destination); + } else { + // linkType is internal + String goToReference = getGoToReference(destination, yoffset); PDFInternalLink internalLink = new PDFInternalLink(goToReference); link.setAction(internalLink); } return link; } - private String getGoToReference(String destination) { + private String getGoToReference(String destination, float yoffset) { String goToReference = null; PDFGoTo gt = new PDFGoTo(++this.objectcount, destination); + gt.setYPosition(yoffset); goToReference = gt.referencePDF(); addTrailerObject(gt); return goToReference; @@ -1383,8 +1388,8 @@ public class PDFDocument { * @return the new PDF outline object */ public PDFOutline makeOutline(PDFOutline parent, String label, - String destination) { - String goToRef = getGoToReference(destination); + String destination, float yoffset) { + String goToRef = getGoToReference(destination, yoffset); PDFOutline obj = new PDFOutline(++this.objectcount, label, goToRef); diff --git a/src/org/apache/fop/pdf/PDFGoTo.java b/src/org/apache/fop/pdf/PDFGoTo.java index f8dd65a8e..0a9042b91 100644 --- a/src/org/apache/fop/pdf/PDFGoTo.java +++ b/src/org/apache/fop/pdf/PDFGoTo.java @@ -52,8 +52,8 @@ public class PDFGoTo extends PDFAction { * * @param yPosition y position */ - public void setYPosition(int yPosition) { - this.yPosition = (yPosition / 1000f); + public void setYPosition(float yPosition) { + this.yPosition = yPosition; } public void setDestination(String dest) { diff --git a/src/org/apache/fop/pdf/PDFPage.java b/src/org/apache/fop/pdf/PDFPage.java index 807dbc1d8..8cef07787 100644 --- a/src/org/apache/fop/pdf/PDFPage.java +++ b/src/org/apache/fop/pdf/PDFPage.java @@ -121,7 +121,6 @@ public class PDFPage extends PDFResourceContext { } sb = sb.append(">>\nendobj\n"); - return sb.toString().getBytes(); } diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index 4e4b253cc..9f6d9ea3a 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -109,6 +109,7 @@ public class PDFRenderer extends PrintRenderer { * for pdf this means we need the pdf page reference */ protected HashMap pageReferences = new HashMap(); + protected HashMap pvReferences = new HashMap(); private String producer; @@ -273,14 +274,18 @@ public class PDFRenderer extends PrintRenderer { private void renderOutline(BookmarkData outline, PDFOutline parentOutline) { PDFOutline outlineRoot = pdfDoc.getOutlineRoot(); PDFOutline pdfOutline = null; - String intDest = (String)pageReferences.get(outline.getPage()); + PageViewport pv = outline.getPage(); + Rectangle2D bounds = pv.getViewArea(); + double h = bounds.getHeight(); + float yoffset = (float)h / 1000f; + String intDest = (String)pageReferences.get(pv.getKey()); if (parentOutline == null) { pdfOutline = pdfDoc.makeOutline(outlineRoot, - outline.getLabel(), intDest); + outline.getLabel(), intDest, yoffset); } else { PDFOutline pdfParentOutline = parentOutline; pdfOutline = pdfDoc.makeOutline(pdfParentOutline, - outline.getLabel(), intDest); + outline.getLabel(), intDest, yoffset); } for (int i = 0; i < outline.getCount(); i++) { @@ -315,7 +320,8 @@ public class PDFRenderer extends PrintRenderer { pages = new HashMap(); } pages.put(page, currentPage); - pageReferences.put(page, currentPage.referencePDF()); + pageReferences.put(page.getKey(), currentPage.referencePDF()); + pvReferences.put(page.getKey(), page); } /** @@ -339,7 +345,8 @@ public class PDFRenderer extends PrintRenderer { pageHeight = (int) h; currentPage = this.pdfDoc.makePage(this.pdfResources, (int) Math.round(w / 1000), (int) Math.round(h / 1000)); - pageReferences.put(page, currentPage.referencePDF()); + pageReferences.put(page.getKey(), currentPage.referencePDF()); + pvReferences.put(page.getKey(), page); } currentStream = this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER, false); @@ -678,12 +685,19 @@ public class PDFRenderer extends PrintRenderer { Object tr = ip.getTrait(Trait.INTERNAL_LINK); boolean internal = false; String dest = null; + float yoffset = 0; if (tr == null) { dest = (String)ip.getTrait(Trait.EXTERNAL_LINK); } else { - PageViewport pv = (PageViewport)tr; - dest = (String)pageReferences.get(pv); - internal = true; + String pvKey = (String)tr; + dest = (String)pageReferences.get(pvKey); + if(dest != null) { + PageViewport pv = (PageViewport)pvReferences.get(pvKey); + Rectangle2D bounds = pv.getViewArea(); + double h = bounds.getHeight(); + yoffset = (float)h / 1000f; + internal = true; + } } if (dest != null) { // add link to pdf document @@ -693,7 +707,7 @@ public class PDFRenderer extends PrintRenderer { rect = transform.createTransformedShape(rect).getBounds(); int type = internal ? PDFLink.INTERNAL : PDFLink.EXTERNAL; - PDFLink pdflink = pdfDoc.makeLink(rect, dest, type); + PDFLink pdflink = pdfDoc.makeLink(rect, dest, type, yoffset); currentPage.addAnnotation(pdflink); } } diff --git a/src/org/apache/fop/svg/PDFGraphics2D.java b/src/org/apache/fop/svg/PDFGraphics2D.java index b6d28779f..194868f5a 100644 --- a/src/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/org/apache/fop/svg/PDFGraphics2D.java @@ -277,7 +277,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { resourceContext.addAnnotation(pdfDoc.makeLink(rect, pageRef, pdfdest)); } else { resourceContext.addAnnotation(pdfDoc.makeLink(rect, - dest, linkType)); + dest, linkType, 0)); } } diff --git a/src/org/apache/fop/traits/BorderProps.java b/src/org/apache/fop/traits/BorderProps.java index e7753f4c3..3929255a7 100644 --- a/src/org/apache/fop/traits/BorderProps.java +++ b/src/org/apache/fop/traits/BorderProps.java @@ -9,7 +9,13 @@ package org.apache.fop.traits; import org.apache.fop.datatypes.ColorType; -public class BorderProps { +import java.io.Serializable; + +/** + * Border properties. + * Class to store border trait propties for the area tree. + */ +public class BorderProps implements Serializable { public int style; // Enum for border style public ColorType color; // Border color public int width; // Border width -- 2.39.5