made sure area tree is serializable git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195405 13f79535-47bb-0310-9956-ffa450edef68pull/30/head
@@ -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); | |||
} | |||
} |
@@ -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; |
@@ -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 |
@@ -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; |
@@ -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 |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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); | |||
@@ -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) { |
@@ -121,7 +121,6 @@ public class PDFPage extends PDFResourceContext { | |||
} | |||
sb = sb.append(">>\nendobj\n"); | |||
return sb.toString().getBytes(); | |||
} | |||
@@ -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); | |||
} | |||
} |
@@ -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)); | |||
} | |||
} | |||
@@ -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 |