aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/area
diff options
context:
space:
mode:
authorKeiron Liddle <keiron@apache.org>2002-09-09 05:58:15 +0000
committerKeiron Liddle <keiron@apache.org>2002-09-09 05:58:15 +0000
commit08b77b1cd5556d549c0778401508ef09f88013e6 (patch)
treea8b38bdf8c26d911aaf1c4b04ba08f26fec892a0 /src/org/apache/fop/area
parentcf02e02cc3e1d392b9abfd2eabba9054bb5f5ddc (diff)
downloadxmlgraphics-fop-08b77b1cd5556d549c0778401508ef09f88013e6.tar.gz
xmlgraphics-fop-08b77b1cd5556d549c0778401508ef09f88013e6.zip
implemented render pages model with a simple cached impl
depending on the renderer it can prepare pages for later rendering or queue pages until resolved pages are properly serialized so that resolvers also serialize git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195156 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache/fop/area')
-rw-r--r--src/org/apache/fop/area/AreaTree.java72
-rw-r--r--src/org/apache/fop/area/CachedRenderPagesModel.java107
-rw-r--r--src/org/apache/fop/area/Page.java22
-rw-r--r--src/org/apache/fop/area/PageViewport.java155
-rw-r--r--src/org/apache/fop/area/Resolveable.java3
5 files changed, 334 insertions, 25 deletions
diff --git a/src/org/apache/fop/area/AreaTree.java b/src/org/apache/fop/area/AreaTree.java
index 5958b6390..4046c6afd 100644
--- a/src/org/apache/fop/area/AreaTree.java
+++ b/src/org/apache/fop/area/AreaTree.java
@@ -47,7 +47,7 @@ public class AreaTree {
* @param rend the renderer that will be used
* @return RenderPagesModel the new area tree model
*/
- public RenderPagesModel createRenderPagesModel(Renderer rend) {
+ public static RenderPagesModel createRenderPagesModel(Renderer rend) {
return new RenderPagesModel(rend);
}
@@ -354,8 +354,14 @@ public class AreaTree {
* contents but the PageViewport is retained.
*/
public static class RenderPagesModel extends StorePagesModel {
- private Renderer renderer;
- private ArrayList prepared = new ArrayList();
+ /**
+ * The renderer that will render the pages.
+ */
+ protected Renderer renderer;
+ /**
+ * Pages that have been prepared but not rendered yet.
+ */
+ protected ArrayList prepared = new ArrayList();
private ArrayList pendingExt = new ArrayList();
private ArrayList endDocExt = new ArrayList();
@@ -388,19 +394,63 @@ public class AreaTree {
*/
public void addPage(PageViewport page) {
super.addPage(page);
+
+ // check prepared pages
+ boolean cont = checkPreparedPages();
+
// if page finished
- try {
- renderer.renderPage(page);
- } catch (Exception e) {
- // use error handler to handle this FOP or IO Exception
+ if (cont && page.isResolved()) {
+ try {
+ renderer.renderPage(page);
+ } catch (Exception e) {
+ // use error handler to handle this FOP or IO Exception
+ }
+ page.clear();
+ } else {
+ preparePage(page);
}
- page.clear();
renderExtensions(pendingExt);
pendingExt.clear();
+ }
+
+ /**
+ * Check prepared pages
+ * @return true if the current page should be rendered
+ * false if the renderer doesn't support out of order
+ * rendering and there are pending pages
+ */
+ protected boolean checkPreparedPages() {
+ for (Iterator iter = prepared.iterator(); iter.hasNext();) {
+ PageViewport p = (PageViewport)iter.next();
+ if (p.isResolved()) {
+ try {
+ renderer.renderPage(p);
+ } catch (Exception e) {
+ // use error handler to handle this FOP or IO Exception
+ }
+ p.clear();
+ iter.remove();
+ } else {
+ // if keeping order then stop at first page not resolved
+ if (!renderer.supportsOutOfOrder()) {
+ break;
+ }
+ }
+ }
+ return renderer.supportsOutOfOrder() || prepared.isEmpty();
+ }
- // else prepare
- //renderer.preparePage(page);
+ /**
+ * Prepare a page.
+ * An unresolved page can be prepared if the renderer supports
+ * it and the page will be rendered later.
+ * @param page the page to prepare
+ */
+ protected void preparePage(PageViewport page) {
+ if (renderer.supportsOutOfOrder()) {
+ renderer.preparePage(page);
+ }
prepared.add(page);
}
@@ -438,6 +488,8 @@ public class AreaTree {
* End the document. Render any end document extensions.
*/
public void endDocument() {
+ // render any pages that had unresolved ids
+ checkPreparedPages();
renderExtensions(endDocExt);
}
}
diff --git a/src/org/apache/fop/area/CachedRenderPagesModel.java b/src/org/apache/fop/area/CachedRenderPagesModel.java
new file mode 100644
index 000000000..f706a8de4
--- /dev/null
+++ b/src/org/apache/fop/area/CachedRenderPagesModel.java
@@ -0,0 +1,107 @@
+/*
+ * $Id$
+ * Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.area;
+
+import org.apache.fop.render.Renderer;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedInputStream;
+
+/**
+ * A simple cached render pages model.
+ * If the page is prepared for later rendering then this saves
+ * the page contents to a file and once the page is resolved
+ * the contents a reloaded.
+ */
+public class CachedRenderPagesModel extends AreaTree.RenderPagesModel {
+ private HashMap pageMap = new HashMap();
+
+ /**
+ * Create a new render pages model with the given renderer.
+ * @param rend the renderer to render pages to
+ */
+ public CachedRenderPagesModel(Renderer rend) {
+ super(rend);
+ }
+
+ /**
+ * Check prepared pages
+ * If a page is resolved it loads the page contents from
+ * the file.
+ * @return true if the current page should be rendered
+ * false if the renderer doesn't support out of order
+ * rendering and there are pending pages
+ */
+ protected boolean checkPreparedPages() {
+ 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();
+ }
+
+ try {
+ renderer.renderPage(p);
+ } catch (Exception e) {
+ // use error handler to handle this FOP or IO Exception
+ }
+ p.clear();
+ iter.remove();
+ } else {
+ if (!renderer.supportsOutOfOrder()) {
+ break;
+ }
+ }
+ }
+ 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.
+ * @param page the page to prepare
+ */
+ protected void preparePage(PageViewport page) {
+ super.preparePage(page);
+
+ try {
+ // save page to cache
+ ObjectOutputStream tempstream;
+ String fname = "page" + page.toString() + ".ser";
+ tempstream = new ObjectOutputStream(new BufferedOutputStream(
+ new FileOutputStream(fname)));
+ page.savePage(tempstream);
+ tempstream.close();
+ pageMap.put(page, fname);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
diff --git a/src/org/apache/fop/area/Page.java b/src/org/apache/fop/area/Page.java
index 3289fdaf3..41b72f8c2 100644
--- a/src/org/apache/fop/area/Page.java
+++ b/src/org/apache/fop/area/Page.java
@@ -10,6 +10,17 @@ package org.apache.fop.area;
import java.io.Serializable;
import java.util.HashMap;
+/**
+ * The page.
+ * This holds the contents of the page. Each region is added.
+ * The unresolved references area added so that if the page is
+ * serialized then it will handle the resolving properly after
+ * being reloaded.
+ * This is serializable so it can be saved to cache to save
+ * memory if there are forward references.
+ * The page is cloneable so the page master can make copies of
+ * the top level page and regions.
+ */
public class Page implements Serializable, Cloneable {
// contains before, start, body, end and after regions
RegionViewport regionBefore = null;
@@ -23,6 +34,8 @@ public class Page implements Serializable, Cloneable {
HashMap markerStart = null;
HashMap markerEnd = null;
+ private HashMap unresolved = null;
+
public void setRegion(int areaclass, RegionViewport port) {
if (areaclass == RegionReference.BEFORE) {
regionBefore = port;
@@ -67,4 +80,13 @@ public class Page implements Serializable, Cloneable {
return p;
}
+
+ public void setUnresolvedReferences(HashMap unres) {
+ unresolved = unres;
+ }
+
+ public HashMap getUnresolvedReferences() {
+ return unresolved;
+ }
}
+
diff --git a/src/org/apache/fop/area/PageViewport.java b/src/org/apache/fop/area/PageViewport.java
index b09048808..e5422658b 100644
--- a/src/org/apache/fop/area/PageViewport.java
+++ b/src/org/apache/fop/area/PageViewport.java
@@ -1,6 +1,6 @@
/*
* $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
@@ -11,59 +11,188 @@ import java.awt.geom.Rectangle2D;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.Iterator;
-// this is the level that creates the page
-// the page (reference area) is then rendered inside the page object
-public class PageViewport implements Cloneable {
- Page page;
- Rectangle2D viewArea;
- boolean clip = false;
- String pageNumber = null;
+/**
+ * Page viewport that specifies the viewport area and holds the page contents.
+ * This is the top level object for a page and remains valid for the life
+ * of the document and the area tree.
+ * This object may be used as a key to reference a page.
+ * This is the level that creates the page
+ * The page (reference area) is then rendered inside the page object
+ */
+public class PageViewport implements Resolveable, Cloneable {
+ private Page page;
+ private Rectangle2D viewArea;
+ private boolean clip = false;
+ private String pageNumber = null;
- // this list is only used when the page is discarded
- // the information is kept for future reference
- ArrayList idReferences = null;
+ // list of id references and the rectangle on the page
+ private HashMap idReferences = null;
// this keeps a list of currently unresolved areas or extensions
// once the thing is resolved it is removed
// when this is empty the page can be rendered
- ArrayList unresolved = null;
+ private HashMap unresolved = null;
+
+ private HashMap pendingResolved = null;
+ /**
+ * Create a page viewport.
+ * @param p the page reference area that holds the contents
+ * @param bounds the bounds of this viewport
+ */
public PageViewport(Page p, Rectangle2D bounds) {
page = p;
viewArea = bounds;
}
+ /**
+ * Set if this viewport should clip.
+ * @param c true if this viewport should clip
+ */
public void setClip(boolean c) {
clip = c;
}
+ /**
+ * Get the view area rectangle of this viewport.
+ * @return the rectangle for this viewport
+ */
public Rectangle2D getViewArea() {
return viewArea;
}
- // a viewport area for page and reference areas
+ /**
+ * Get the page reference area with the contents.
+ * @return the page reference area
+ */
public Page getPage() {
return page;
}
+ /**
+ * Set the page number for this page.
+ * @param num the string representing the page number
+ */
public void setPageNumber(String num) {
pageNumber = num;
}
+ /**
+ * Get the page number of this page.
+ * @return the string that represents this page
+ */
public String getPageNumber() {
return pageNumber;
}
+ /**
+ * Add an unresolved id to this page.
+ * All unresolved ids for the contents of this page are
+ * added to this page. This is so that the resolvers can be
+ * serialized with the page to preserve the proper function.
+ * @param id the id of the reference
+ * @param res the resolver of the reference
+ */
+ public void addUnresolvedID(String id, Resolveable res) {
+ if (unresolved == null) {
+ unresolved = new HashMap();
+ }
+ List list = (List)unresolved.get(id);
+ if (list == null) {
+ list = new ArrayList();
+ unresolved.put(id, list);
+ }
+ list.add(res);
+ }
+
+ /**
+ * Check if this page has been fully resolved.
+ * @return true if the page is resolved and can be rendered
+ */
+ public boolean isResolved() {
+ return unresolved == null;
+ }
+
+ /**
+ * Get the id references for this page.
+ * @return always null
+ */
+ public String[] getIDs() {
+ return null;
+ }
+
+ /**
+ * This resolves reference with a list of pages.
+ * The pages (PageViewport) contain the rectangle of the area.
+ * @param id the id to resolve
+ * @param pages the list of pages with the id area
+ * may be null if not found
+ */
+ public void resolve(String id, List pages) {
+ if (page == null) {
+ if (pendingResolved == null) {
+ pendingResolved = new HashMap();
+ }
+ pendingResolved.put(id, pages);
+ } else {
+ List todo = (List)unresolved.get(id);
+ if (todo != null) {
+ for (int count = 0; count < todo.size(); count++) {
+ Resolveable res = (Resolveable)todo.get(count);
+ res.resolve(id, pages);
+ }
+ }
+ }
+ unresolved.remove(id);
+ if (unresolved.isEmpty()) {
+ unresolved = null;
+ }
+ }
+
+ /**
+ * Save the page contents to an object stream.
+ * The map of unresolved references are set on the page so that
+ * the resolvers can be properly serialized and reloaded.
+ * @param out the object output stream to write the contents
+ * @throws Exception if there is a problem saving the page
+ */
public void savePage(ObjectOutputStream out) throws Exception {
+ // set the unresolved references so they are serialized
+ page.setUnresolvedReferences(unresolved);
out.writeObject(page);
page = null;
}
+ /**
+ * Load the page contents from an object stream.
+ * This loads the page contents from the stream and
+ * if there are any unresolved references that were resolved
+ * while saved they will be resolved on the page contents.
+ * @param in the object input stream to read the page from
+ * @throws Exception if there is an error loading the page
+ */
public void loadPage(ObjectInputStream in) throws Exception {
page = (Page) in.readObject();
+ unresolved = page.getUnresolvedReferences();
+ if (unresolved != null && pendingResolved != null) {
+ for (Iterator iter = pendingResolved.keySet().iterator();
+ iter.hasNext();) {
+ String id = (String) iter.next();
+ resolve(id, (List)pendingResolved.get(id));
+ }
+ pendingResolved = null;
+ }
}
+ /**
+ * Clone this page.
+ * Used by the page master to create a copy of an original page.
+ * @return a copy of this page and associated viewports
+ */
public Object clone() {
Page p = (Page)page.clone();
PageViewport ret = new PageViewport(p, (Rectangle2D)viewArea.clone());
diff --git a/src/org/apache/fop/area/Resolveable.java b/src/org/apache/fop/area/Resolveable.java
index c40fc5329..edfcce6b8 100644
--- a/src/org/apache/fop/area/Resolveable.java
+++ b/src/org/apache/fop/area/Resolveable.java
@@ -8,14 +8,13 @@
package org.apache.fop.area;
import java.util.List;
-import java.io.Serializable;
/**
* Resolveable Interface.
* Classes that implement this can be resolved when
* an id is added to the area tree.
*/
-public interface Resolveable extends Serializable {
+public interface Resolveable {
public boolean isResolved();