]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
1.) Moved the Renderer creation further down from AreaTree to RenderPagesModel (subcl...
authorGlen Mazza <gmazza@apache.org>
Wed, 7 Jul 2004 01:51:50 +0000 (01:51 +0000)
committerGlen Mazza <gmazza@apache.org>
Wed, 7 Jul 2004 01:51:50 +0000 (01:51 +0000)
2.) Removed encapsulation-breaking methods from AreaTree; dropped the AreaTreeBuilder class as it wasn't conformant with our API and required too many objects to expose internal functionality.

3.) Validity checking added for fo:title, however still won't work as #PCDATA needs <fo:blocks> around it within FOP, but the Recommendation bans those for fo:title.

4.) isInlineItem() added to FObj, as a quick check for the %inline; parameter entity as defined in spec.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197763 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/area/AreaTree.java
src/java/org/apache/fop/area/AreaTreeModel.java
src/java/org/apache/fop/area/CachedRenderPagesModel.java
src/java/org/apache/fop/area/RenderPagesModel.java
src/java/org/apache/fop/area/StorePagesModel.java
src/java/org/apache/fop/fo/FObj.java
src/java/org/apache/fop/fo/pagination/Title.java
src/java/org/apache/fop/tools/AreaTreeBuilder.java [deleted file]

index 3334cda39fd4a8d96efb3dafa79f4ba1306ae725..26593ceb940e36df91eff3b08962120d826ec0b6 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.fop.area;
 
 // Java
-import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -35,11 +34,9 @@ import org.xml.sax.SAXException;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.area.extensions.BookmarkData;
-import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.Outline;
 import org.apache.fop.fo.extensions.Bookmarks;
 import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.render.Renderer;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -52,12 +49,12 @@ import org.apache.commons.logging.LogFactory;
  * The area tree needs to be simple to render and follow the spec
  * closely.
  * This area tree has the concept of page sequences.
- * Where ever possible information is discarded or optimised to
- * keep memory use low. The data is also organised to make it
- * possible for renderers to minimise their output.
+ * Where ever possible information is discarded or optimized to
+ * keep memory use low. The data is also organized to make it
+ * possible for renderers to minimize their output.
  * A page can be saved if not fully resolved and once rendered
  * a page contains only size and id reference information.
- * The area tree pages are organised in a model that depends on the
+ * The area tree pages are organized in a model that depends on the
  * type of renderer.
  */
 public class AreaTree {
@@ -67,106 +64,33 @@ public class AreaTree {
 
     // hashmap of arraylists containing pages with id area
     private Map idLocations = new HashMap();
+
     // list of id's yet to be resolved and arraylists of pages
     private Map resolve = new HashMap();
+
     private List treeExtensions = new ArrayList();
 
     private static Log log = LogFactory.getLog(AreaTree.class);
 
     private FOUserAgent foUserAgent;
 
-    /**
-     * the renderer to use to output the area tree
-     */
-    private Renderer renderer;
-
     /**
      * Constructor.
+     * @param userAgent FOUserAgent object for process
+     * @param renderType Desired fo.Constants output type (RENDER_PDF, 
+     *   RENDER_PS, etc.)
+     * @param fontInfo FontInfo object
+     * @param stream OutputStream
      */
     public AreaTree (FOUserAgent userAgent, int renderType, 
         FontInfo fontInfo, OutputStream stream) throws FOPException {
 
         foUserAgent = userAgent;
-
-        if (foUserAgent.getRendererOverride() != null) {
-            renderer = foUserAgent.getRendererOverride();
-        } else {
-            renderer = createRenderer(renderType);
-            renderer.setUserAgent(foUserAgent);
-        }
-
-        try {
-            renderer.setupFontInfo(fontInfo);
-            // check that the "any,normal,400" font exists
-            if (!fontInfo.isSetupValid()) {
-                throw new FOPException(
-                    "No default font defined by OutputConverter");
-            }
-            renderer.startRenderer(stream);
-        } catch (IOException e) {
-            throw new FOPException(e);
-        }
-
-        // this.atModel = new CachedRenderPagesModel(renderer);
-        setTreeModel(new RenderPagesModel(renderer));
-    }
-
-
-    /**
-     * Creates a Renderer object based on render-type desired
-     * @param renderType the type of renderer to use
-     * @return Renderer the new Renderer instance
-     * @throws IllegalArgumentException if an unsupported renderer type was requested
-     */
-    private Renderer createRenderer(int renderType) throws IllegalArgumentException {
-
-        switch (renderType) {
-        case Constants.RENDER_PDF:
-            return new org.apache.fop.render.pdf.PDFRenderer();
-        case Constants.RENDER_AWT:
-            return new org.apache.fop.render.awt.AWTRenderer();
-        case Constants.RENDER_PRINT:
-            return new org.apache.fop.render.awt.AWTPrintRenderer();
-        case Constants.RENDER_PCL:
-            return new org.apache.fop.render.pcl.PCLRenderer();
-        case Constants.RENDER_PS:
-            return new org.apache.fop.render.ps.PSRenderer();
-        case Constants.RENDER_TXT:
-            return new org.apache.fop.render.txt.TXTRenderer();
-        case Constants.RENDER_XML:
-            return new org.apache.fop.render.xml.XMLRenderer();
-        case Constants.RENDER_SVG:
-            return new org.apache.fop.render.svg.SVGRenderer();
-        default:
-            throw new IllegalArgumentException("Invalid renderer type " 
-                + renderType);
-        }
-    }
-
-    /**
-     * Temporary accessor for renderer for tools.AreaTreeBuilder
-     * @return renderer The renderer being used by this area tree
-     */
-    public Renderer getRenderer() {
-        return renderer;
-    }
-
-    /**
-     * Create a new store pages model.
-     * @return StorePagesModel the new model
-     */
-    public static StorePagesModel createStorePagesModel() {
-        return new StorePagesModel();
-    }
-
-    /**
-     * Set the tree model to use for this area tree.
-     * The different models can have different behaviour
-     * when pages area added and other changes.
-     * @param m the area tree model
-     */
-    public void setTreeModel(AreaTreeModel m) {
-        model = m;
+        
+        // model = new CachedRenderPagesModel(userAgent, renderType,
+        //  fontInfo, stream);
+        model = new RenderPagesModel(userAgent, renderType, fontInfo,
+            stream);
     }
 
     /**
@@ -297,11 +221,6 @@ public class AreaTree {
             }
         }
         model.endDocument();
-        try {
-            renderer.stopRenderer();
-        } catch (IOException ex) {
-            throw new SAXException(ex);
-        }        
     }
 
     /**
index a0ba93f500ae2877a66190248f62f233ca53d1ab..d57d10d195cb5f61fc75b87b71210fe50d2cf29f 100644 (file)
  
 package org.apache.fop.area;
 
+// XML
+import org.xml.sax.SAXException;
+
 /**
  * This is the model for the area tree object.
  * The model implementation can handle the page sequence,
  * page and extensions.
- * The mathods to acces the page viewports can only
+ * The methods to access the page viewports can only
  * assume the PageViewport is valid as it remains for
  * the life of the area tree model.
  */
@@ -49,7 +52,7 @@ public abstract class AreaTreeModel {
     /**
      * Signal the end of the document for any processing.
      */
-    public abstract void endDocument();
+    public abstract void endDocument() throws SAXException;
 
     /**
      * Get the page sequence count.
index ef7c314bf855242d516bee22ea23b9980fdf8a1c..5446f9952dd73beb8cf63ac30f71bd231c5eda7b 100644 (file)
@@ -18,6 +18,9 @@
  
 package org.apache.fop.area;
 
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.render.Renderer;
 
 import java.util.Map;
@@ -29,6 +32,7 @@ import java.io.FileOutputStream;
 import java.io.FileInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectInputStream;
+import java.io.OutputStream;
 import java.io.BufferedOutputStream;
 import java.io.BufferedInputStream;
 
@@ -42,11 +46,12 @@ public class CachedRenderPagesModel extends RenderPagesModel {
     private Map pageMap = new HashMap();
 
     /**
-     * Create a new render pages model with the given renderer.
-     * @param rend the renderer to render pages to
+     * Constructor
+     * @see org.apache.fop.area.RenderPagesModel(FOUserAgent, int, FontInfo, OutputStream)
      */
-    public CachedRenderPagesModel(Renderer rend) {
-        super(rend);
+    public CachedRenderPagesModel (FOUserAgent userAgent, int renderType, 
+        FontInfo fontInfo, OutputStream stream) throws FOPException {
+        super(userAgent, renderType, fontInfo, stream);
     }
 
     /**
index 3ad65a8f6f993a2cdc5adb58cfd7192bc254dafb..96fcb8a7e4d2f2d3f602d4e62bea589672daa63f 100644 (file)
  
 package org.apache.fop.area;
 
-// FOP
-import org.apache.fop.render.Renderer;
-
 // Java
+import java.io.IOException;
+import java.io.OutputStream;
 import java.util.List;
 import java.util.Iterator;
 
+// XML
+import org.xml.sax.SAXException;
+
+// FOP
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.Renderer;
+
 /**
  * This uses the store pages model to store the pages
  * each page is either rendered if ready or prepared
@@ -38,6 +47,7 @@ public class RenderPagesModel extends StorePagesModel {
      * The renderer that will render the pages.
      */
     protected Renderer renderer;
+    
     /**
      * Pages that have been prepared but not rendered yet.
      */
@@ -47,10 +57,64 @@ public class RenderPagesModel extends StorePagesModel {
 
     /**
      * Create a new render pages model with the given renderer.
-     * @param rend the renderer to render pages to
+     * @param userAgent FOUserAgent object for process
+     * @param renderType Desired fo.Constants output type (RENDER_PDF, 
+     *   RENDER_PS, etc.)
+     * @param fontInfo FontInfo object
+     * @param stream OutputStream
      */
-    public RenderPagesModel(Renderer rend) {
-        renderer = rend;
+    public RenderPagesModel (FOUserAgent userAgent, int renderType, 
+        FontInfo fontInfo, OutputStream stream) throws FOPException {
+
+        if (userAgent.getRendererOverride() != null) {
+            renderer = userAgent.getRendererOverride();
+        } else {
+            renderer = createRenderer(renderType);
+            renderer.setUserAgent(userAgent);
+        }
+
+        try {
+            renderer.setupFontInfo(fontInfo);
+            // check that the "any,normal,400" font exists
+            if (!fontInfo.isSetupValid()) {
+                throw new FOPException(
+                    "No default font defined by OutputConverter");
+            }
+            renderer.startRenderer(stream);
+        } catch (IOException e) {
+            throw new FOPException(e);
+        }
+    }
+
+    /**
+     * Creates a Renderer object based on render-type desired
+     * @param renderType the type of renderer to use
+     * @return Renderer the new Renderer instance
+     * @throws IllegalArgumentException if an unsupported renderer type was requested
+     */
+    private Renderer createRenderer(int renderType) throws IllegalArgumentException {
+
+        switch (renderType) {
+        case Constants.RENDER_PDF:
+            return new org.apache.fop.render.pdf.PDFRenderer();
+        case Constants.RENDER_AWT:
+            return new org.apache.fop.render.awt.AWTRenderer();
+        case Constants.RENDER_PRINT:
+            return new org.apache.fop.render.awt.AWTPrintRenderer();
+        case Constants.RENDER_PCL:
+            return new org.apache.fop.render.pcl.PCLRenderer();
+        case Constants.RENDER_PS:
+            return new org.apache.fop.render.ps.PSRenderer();
+        case Constants.RENDER_TXT:
+            return new org.apache.fop.render.txt.TXTRenderer();
+        case Constants.RENDER_XML:
+            return new org.apache.fop.render.xml.XMLRenderer();
+        case Constants.RENDER_SVG:
+            return new org.apache.fop.render.svg.SVGRenderer();
+        default:
+            throw new IllegalArgumentException("Invalid renderer type " 
+                + renderType);
+        }
     }
 
     /**
@@ -178,7 +242,7 @@ public class RenderPagesModel extends StorePagesModel {
     /**
      * End the document. Render any end document extensions.
      */
-    public void endDocument() {
+    public void endDocument() throws SAXException {
         // render any pages that had unresolved ids
         checkPreparedPages(null);
 
@@ -186,6 +250,12 @@ public class RenderPagesModel extends StorePagesModel {
         pendingExt.clear();
 
         renderExtensions(endDocExt);
+        
+        try {
+            renderer.stopRenderer();
+        } catch (IOException ex) {
+            throw new SAXException(ex);
+        }        
     }
 }
 
index d901bbc913872b4a9efec32ba8a9b592b50b1555..23903ff5e27c806280155310ae15757b1fd8cda0 100644 (file)
@@ -21,6 +21,10 @@ package org.apache.fop.area;
 // Java
 import java.util.List;
 
+// XML
+import org.xml.sax.SAXException;
+
+
 /**
  * This class stores all the pages in the document
  * for interactive agents.
@@ -142,6 +146,6 @@ public class StorePagesModel extends AreaTreeModel {
     /**
      * End document, do nothing.
      */
-    public void endDocument() {
+    public void endDocument() throws SAXException {
     }
 }
index 64a6813269cf6dcd8d84992605566eee97b9a2ba..06dd20a5b0721fcb937cb3a21958bd6effe3c9b6 100644 (file)
@@ -445,7 +445,7 @@ public class FObj extends FONode implements Constants {
      * Convenience method for validity checking.  Checks if the
      * incoming node is a member of the "%block;" parameter entity
      * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
-     * @param nsURI namespace URI of incoming invalid node
+     * @param nsURI namespace URI of incoming node
      * @param lName local name (i.e., no prefix) of incoming node 
      * @return true if a member, false if not
      */
@@ -456,15 +456,40 @@ public class FObj extends FONode implements Constants {
             || lName.equals("table-and-caption") 
             || lName.equals("block-container")
             || lName.equals("list-block") 
-            || lName.equals("float")))
-            || isNeutralItem(nsURI, lName);
+            || lName.equals("float")
+            || isNeutralItem(nsURI, lName)));
+    }
+
+    /**
+     * Convenience method for validity checking.  Checks if the
+     * incoming node is a member of the "%inline;" parameter entity
+     * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
+     * @param nsURI namespace URI of incoming node
+     * @param lName local name (i.e., no prefix) of incoming node 
+     * @return true if a member, false if not
+     */
+    protected static boolean isInlineItem(String nsURI, String lName) {
+        return (nsURI == FOElementMapping.URI && 
+            (lName.equals("bidi-override") 
+            || lName.equals("character") 
+            || lName.equals("external-graphic") 
+            || lName.equals("instream-foreign-object")
+            || lName.equals("inline") 
+            || lName.equals("inline-container")
+            || lName.equals("leader") 
+            || lName.equals("page-number") 
+            || lName.equals("page-number-citation")
+            || lName.equals("basic-link")
+            || lName.equals("multi-toggle")
+            || lName.equals("footnote") // temp only -- not always correct (see spec)
+            || isNeutralItem(nsURI, lName)));
     }
 
     /**
      * Convenience method for validity checking.  Checks if the
      * incoming node is a member of the neutral item list
      * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
-     * @param nsURI namespace URI of incoming invalid node
+     * @param nsURI namespace URI of incoming node
      * @param lName local name (i.e., no prefix) of incoming node 
      * @return true if a member, false if not
      */
@@ -473,6 +498,7 @@ public class FObj extends FONode implements Constants {
             (lName.equals("multi-switch") 
             || lName.equals("multi-properties")
             || lName.equals("wrapper") 
+            || lName.equals("float") // temp only -- not always correct (see spec)
             || lName.equals("retrieve-marker")));
     }
 }
index 70a24b9ccdcb897da093735232b48d6719963377..5ebc2b1441616f641edf9f0460284d4b78c13a28 100644 (file)
 
 package org.apache.fop.fo.pagination;
 
+// XML
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
 // FOP
 import org.apache.fop.datatypes.ColorType;
 import org.apache.fop.datatypes.Length;
@@ -46,6 +50,16 @@ public class Title extends FObjMixed {
         super(parent);
     }
 
+    /**
+     * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+        XSL/FOP: (#PCDATA|%inline;)*
+     */
+    protected void validateChildNode(Locator loc, String nsURI, String localName) {
+        if (!isInlineItem(nsURI, localName)) {
+            invalidChildError(loc, nsURI, localName);
+        }
+    }
+
     private void setup() {
 
         // Common Accessibility Properties
diff --git a/src/java/org/apache/fop/tools/AreaTreeBuilder.java b/src/java/org/apache/fop/tools/AreaTreeBuilder.java
deleted file mode 100644 (file)
index c844a0d..0000000
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * Copyright 1999-2004 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.
- * 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.tools;
-
-// Java
-import java.awt.geom.Rectangle2D;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.StringTokenizer;
-
-// JAXP
-import javax.xml.parsers.DocumentBuilderFactory;
-
-// DOM
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Element;
-import org.w3c.dom.Document;
-
-// Batik
-import org.apache.batik.dom.svg.SVGDOMImplementation;
-
-// FOP
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.area.Area;
-import org.apache.fop.area.AreaTree;
-import org.apache.fop.area.AreaTreeModel;
-import org.apache.fop.area.BeforeFloat;
-import org.apache.fop.area.Block;
-import org.apache.fop.area.BodyRegion;
-import org.apache.fop.area.CTM;
-import org.apache.fop.area.Flow;
-import org.apache.fop.area.Footnote;
-import org.apache.fop.area.LineArea;
-import org.apache.fop.area.MainReference;
-import org.apache.fop.area.Page;
-import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.RegionReference;
-import org.apache.fop.area.RegionViewport;
-import org.apache.fop.area.Span;
-import org.apache.fop.area.StorePagesModel;
-import org.apache.fop.area.Title;
-import org.apache.fop.area.Trait;
-import org.apache.fop.area.inline.Character;
-import org.apache.fop.area.inline.Container;
-import org.apache.fop.area.inline.ForeignObject;
-import org.apache.fop.area.inline.Image;
-import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.area.inline.Leader;
-import org.apache.fop.area.inline.Space;
-import org.apache.fop.area.inline.Viewport;
-import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.render.Renderer;
-import org.apache.fop.render.pdf.PDFRenderer;
-import org.apache.fop.render.svg.SVGRenderer;
-import org.apache.fop.render.xml.XMLRenderer;
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.pagination.Region;
-import org.apache.fop.fonts.FontMetrics;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.impl.SimpleLog;
-
-
-/**
- * Area tree tester.
- * The purpose of this class is to create and render an area tree
- * for the purpose of testing the area tree and rendering.
- * This covers the set of possible properties that can be set
- * on the area tree for rendering.
- * As this is not for general purpose there is no attempt to handle
- * invalid area tree xml.
- *
- * Tests: different renderers, saving and loading pages with serialization
- * out of order rendering
- */
-public class AreaTreeBuilder {
-
-    /**
-     * logging instance
-     */
-    protected Log logger = null;
-
-    /**
-     * Sets the Commons-Logging instance for this class
-     * @param logger The Commons-Logging instance
-     */
-    public void setLogger(Log logger) {
-        this.logger = logger;
-    }
-
-    /**
-     * Returns the Commons-Logging instance for this class
-     * @return  The Commons-Logging instance
-     */
-    protected Log getLogger() {
-        return logger;
-    }
-
-    /**
-     * Main method
-     * @param args command line arguments
-     */
-    public static void main(String[] args) {
-        AreaTreeBuilder atb = new AreaTreeBuilder();
-        SimpleLog logger = new SimpleLog("FOP");
-        logger.setLevel(SimpleLog.LOG_LEVEL_DEBUG);
-        atb.setLogger(logger);
-
-        atb.runTests(args[0], args[1], args[2]);
-        System.exit(0);
-    }
-
-    /**
-     * Run the tests.
-     * @param in input filename
-     * @param type output format
-     * @param out output filename
-     */
-    protected void runTests(String in, String type, String out) {
-        logger.debug("Starting tests");
-        runTest(in, type, out);
-        logger.debug("Finished");
-    }
-
-    /**
-     * Run a test.
-     * @param in input filename
-     * @param type output format
-     * @param out output filename
-     */
-    protected void runTest(String in, String type, String out) {
-        int renderType = Constants.NOT_SET;
-        if ("xml".equals(type)) {
-            renderType = Constants.RENDER_XML;
-        } else if ("pdf".equals(type)) {
-            renderType = Constants.RENDER_PDF;
-        } else if ("svg".equals(type)) {
-            renderType = Constants.RENDER_SVG;
-        }
-
-        FontInfo fontInfo = new FontInfo();
-        FOUserAgent ua = new FOUserAgent();
-
-        try {
-            OutputStream os =
-              new java.io.BufferedOutputStream(new java.io.FileOutputStream(out));
-    
-            StorePagesModel sm = AreaTree.createStorePagesModel();
-            TreeLoader tl = new TreeLoader(ua, renderType, fontInfo, os);
-            tl.setLogger(logger);
-            tl.setTreeModel(sm);
-            InputStream is =
-              new java.io.BufferedInputStream(new java.io.FileInputStream(in));
-            tl.buildAreaTree(is);
-            renderAreaTree(sm, tl.getAreaTree().getRenderer());
-            os.close();
-        } catch (Exception e) {
-            logger.error("Error processing file: " + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Renders an area tree to a target format using a renderer.
-     * @param sm area tree pages
-     * @param rend renderer to use for output
-     */
-    protected void renderAreaTree(StorePagesModel sm,
-                                  Renderer rend) {
-        try {
-            int count = 0;
-            int seqc = sm.getPageSequenceCount();
-            while (count < seqc) {
-                Title title = sm.getTitle(count);
-                rend.startPageSequence(title);
-                int pagec = sm.getPageCount(count);
-                int c = 0;
-                while (c < pagec) {
-                    PageViewport page = sm.getPage(count, c);
-                    c++;
-                    // save the page to a stream for testing
-                    /*ObjectOutputStream tempstream = new ObjectOutputStream(
-                                                      new BufferedOutputStream(
-                                                        new FileOutputStream("temp.ser")));
-                    page.savePage(tempstream);
-                    tempstream.close();
-                    File temp = new File("temp.ser");
-                    getLogger().debug("page serialized to: " + temp.length());
-                    temp = null;
-                    ObjectInputStream in = new ObjectInputStream(
-                                             new BufferedInputStream(
-                                               new FileInputStream("temp.ser")));
-                    page.loadPage(in);
-                    in.close();*/
-
-                    rend.renderPage(page);
-                }
-                count++;
-            }
-
-            rend.stopRenderer();
-        } catch (Exception e) {
-            logger.error("error rendering output", e);
-        }
-    }
-
-
-}
-
-// this loads an area tree from an xml file
-// the xml format is the same as the xml renderer output
-class TreeLoader {
-    private AreaTree areaTree;
-    private AreaTreeModel model;
-    private Renderer renderer;
-    private FontInfo fontInfo;
-    private Font currentFontState;
-    private Log logger = null;
-    private FOUserAgent foUserAgent = null;
-    private int renderType = Constants.NOT_SET;
-    private OutputStream outputStream;
-    
-    TreeLoader(FOUserAgent userAgent, int rendType, FontInfo fontInfo, OutputStream os) {
-        this.foUserAgent = userAgent;
-        this.renderType = rendType;
-        this.fontInfo = fontInfo;
-        this.outputStream = os;
-    }
-
-    /**
-     * Sets the Commons-Logging instance for this class
-     * @param logger The Commons-Logging instance
-     */
-    public void setLogger(Log logger) {
-        this.logger = logger;
-    }
-
-    public AreaTree getAreaTree() {
-        return areaTree;
-    }
-
-    public void setTreeModel(AreaTreeModel mo) {
-        model = mo;
-    }
-
-    public void buildAreaTree(InputStream is) throws FOPException {
-        Document doc = null;
-        try {
-            DocumentBuilderFactory fact =
-              DocumentBuilderFactory.newInstance();
-            fact.setNamespaceAware(true);
-            doc = fact.newDocumentBuilder().parse(is);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        Element root = null;
-        root = doc.getDocumentElement();
-
-        areaTree = new AreaTree(foUserAgent, renderType, fontInfo, outputStream);
-        areaTree.setTreeModel(model);
-
-        readAreaTree(root);
-    }
-
-    public void readAreaTree(Element root) {
-
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("pageSequence")) {
-                readPageSequence((Element) obj);
-            }
-        }
-    }
-
-    public void readPageSequence(Element root) {
-        Title title = null;
-        boolean started = false;
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("title")) {
-                if (started) {
-                    // problem
-                } else {
-                    title = readTitle((Element) obj);
-                    model.startPageSequence(title);
-                    started = true;
-                }
-            } else if (obj.getNodeName().equals("pageViewport")) {
-                if (!started) {
-                    model.startPageSequence(null);
-                    started = true;
-                }
-                PageViewport viewport = readPageViewport((Element) obj);
-                areaTree.addPage(viewport);
-            }
-        }
-    }
-
-    public Title readTitle(Element root) {
-        Title title = new Title();
-        List childs = getInlineAreas(root);
-        for (int i = 0; i < childs.size(); i++) {
-            InlineArea obj = (InlineArea) childs.get(i);
-            title.addInlineArea(obj);
-        }
-        return title;
-    }
-
-    public PageViewport readPageViewport(Element root) {
-        Rectangle2D bounds = getRectangle(root, "bounds");
-        PageViewport viewport = null;
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("page")) {
-                Page page = readPage((Element) obj);
-                viewport = new PageViewport(page, bounds);
-            }
-        }
-        return viewport;
-    }
-
-    public Page readPage(Element root) {
-        //String bounds = root.getAttribute("bounds");
-        Page page = new Page();
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("regionViewport")) {
-                readRegionViewport(page, (Element) obj);
-            }
-        }
-        return page;
-    }
-
-    Rectangle2D getRectangle(Element root, String attr) {
-        String rect = root.getAttribute(attr);
-        StringTokenizer st = new StringTokenizer(rect, " ");
-        int x = 0, y = 0, w = 0, h = 0;
-        if (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            x = Integer.parseInt(tok);
-        }
-        if (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            y = Integer.parseInt(tok);
-        }
-        if (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            w = Integer.parseInt(tok);
-        }
-        if (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            h = Integer.parseInt(tok);
-        }
-        Rectangle2D r2d = new Rectangle2D.Float(x, y, w, h);
-        return r2d;
-    }
-
-    public RegionViewport readRegionViewport(Page page, Element root) {
-        RegionViewport reg = new RegionViewport(getRectangle(root, "rect"));
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("regionBefore")) {
-                reg.setRegion(readRegion((Element) obj, Region.BEFORE_CODE));
-                page.setRegionViewport(Region.BEFORE_CODE, reg);
-            } else if (obj.getNodeName().equals("regionStart")) {
-                reg.setRegion(readRegion((Element) obj, Region.START_CODE));
-                page.setRegionViewport(Region.START_CODE, reg);
-            } else if (obj.getNodeName().equals("regionBody")) {
-                reg.setRegion(readRegion((Element) obj, Region.BODY_CODE));
-                page.setRegionViewport(Region.BODY_CODE, reg);
-            } else if (obj.getNodeName().equals("regionEnd")) {
-                reg.setRegion(readRegion((Element) obj, Region.END_CODE));
-                page.setRegionViewport(Region.END_CODE, reg);
-            } else if (obj.getNodeName().equals("regionAfter")) {
-                reg.setRegion(readRegion((Element) obj, Region.AFTER_CODE));
-                page.setRegionViewport(Region.AFTER_CODE, reg);
-            }
-        }
-
-        return reg;
-    }
-
-    public RegionReference readRegion(Element root, int type) {
-        RegionReference reg;
-        if (type == Region.BODY_CODE) {
-            BodyRegion br = new BodyRegion();
-            NodeList childs = root.getChildNodes();
-            for (int i = 0; i < childs.getLength(); i++) {
-                Node obj = childs.item(i);
-                if (obj.getNodeName().equals("beforeFloat")) {
-                    BeforeFloat bf = readBeforeFloat((Element) obj);
-                    br.setBeforeFloat(bf);
-                } else if (obj.getNodeName().equals("mainReference")) {
-                    MainReference mr = readMainReference((Element) obj);
-                    br.setMainReference(mr);
-                } else if (obj.getNodeName().equals("footnote")) {
-                    Footnote foot = readFootnote((Element) obj);
-                    br.setFootnote(foot);
-                }
-            }
-            reg = br;
-        } else {
-            reg = new RegionReference(type);
-            List blocks = getBlocks(root);
-            for (int i = 0; i < blocks.size(); i++) {
-                Block obj = (Block) blocks.get(i);
-                reg.addBlock(obj);
-            }
-        }
-        reg.setCTM(new CTM());
-        return reg;
-    }
-
-    public BeforeFloat readBeforeFloat(Element root) {
-        BeforeFloat bf = new BeforeFloat();
-        List blocks = getBlocks(root);
-        for (int i = 0; i < blocks.size(); i++) {
-            Block obj = (Block) blocks.get(i);
-            bf.addBlock(obj);
-        }
-        return bf;
-    }
-
-    public MainReference readMainReference(Element root) {
-        MainReference mr = new MainReference();
-        List spans = getSpans(root);
-        for (int i = 0; i < spans.size(); i++) {
-            Span obj = (Span) spans.get(i);
-            mr.addSpan(obj);
-        }
-        return mr;
-    }
-
-    List getSpans(Element root) {
-        List list = new java.util.ArrayList();
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("span")) {
-                List flows = getFlows((Element) obj);
-                Span span = new Span(flows.size());
-                for (int j = 0; j < flows.size(); j++) {
-                    Flow flow = (Flow) flows.get(j);
-                    span.addFlow(flow);
-                }
-                list.add(span);
-            }
-        }
-        return list;
-    }
-
-    List getFlows(Element root) {
-        List list = new java.util.ArrayList();
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("flow")) {
-                Flow flow = new Flow();
-                List blocks = getBlocks((Element) obj);
-                for (int j = 0; j < blocks.size(); j++) {
-                    Block block = (Block) blocks.get(j);
-                    flow.addBlock(block);
-                }
-                list.add(flow);
-            }
-        }
-        return list;
-    }
-
-    public Footnote readFootnote(Element root) {
-        Footnote foot = new Footnote();
-        List blocks = getBlocks(root);
-        for (int i = 0; i < blocks.size(); i++) {
-            Block obj = (Block) blocks.get(i);
-            foot.addBlock(obj);
-        }
-        return foot;
-    }
-
-
-    List getBlocks(Element root) {
-        List list = new java.util.ArrayList();
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("block")) {
-                Block block = new Block();
-        addTraits((Element)obj, block);
-                addBlockChildren(block, (Element) obj);
-                list.add(block);
-            }
-        }
-        return list;
-    }
-
-    protected void addBlockChildren(Block block, Element root) {
-        NodeList childs = root.getChildNodes();
-        int type = -1;
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("block")) {
-                if (type == 2) {
-                    // error
-                }
-                Block b = new Block();
-                addBlockChildren(b, (Element) obj);
-                block.addBlock(b);
-                type = 1;
-            } else if (obj.getNodeName().equals("lineArea")) {
-                if (type == 1) {
-                    // error
-                }
-                LineArea line = new LineArea();
-                addTraits((Element) obj, line);
-                String height = ((Element) obj).getAttribute("height");
-                int h = Integer.parseInt(height);
-                line.setHeight(h);
-
-                List inlines = getInlineAreas((Element) obj);
-                for (int j = 0; j < inlines.size(); j++) {
-                    InlineArea inline = (InlineArea) inlines.get(j);
-                    line.addInlineArea(inline);
-                }
-
-                block.addLineArea(line);
-                type = 2;
-            }
-        }
-    }
-
-    // children of element are inline areas
-    List getInlineAreas(Element root) {
-        List list = new java.util.ArrayList();
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("char")) {
-                Character ch =
-                  new Character(getString((Element) obj).charAt(0));
-                addTraits((Element) obj, ch);
-                String fname = fontInfo.fontLookup("sans-serif", "normal", Font.NORMAL);
-                FontMetrics metrics = fontInfo.getMetricsFor(fname);
-                currentFontState =
-                    new Font(fname, metrics, 12000);
-
-                ch.setWidth(currentFontState.getWidth(ch.getChar()));
-                ch.setOffset(currentFontState.getCapHeight());
-                list.add(ch);
-            } else if (obj.getNodeName().equals("space")) {
-                Space space = new Space();
-                String width = ((Element) obj).getAttribute("width");
-                int w = Integer.parseInt(width);
-                space.setWidth(w);
-                list.add(space);
-            } else if (obj.getNodeName().equals("viewport")) {
-                Viewport viewport = getViewport((Element) obj);
-                if (viewport != null) {
-                    list.add(viewport);
-                }
-            } else if (obj.getNodeName().equals("leader")) {
-                Leader leader = getLeader((Element) obj);
-                if (leader != null) {
-                    list.add(leader);
-                }
-            } else if (obj.getNodeName().equals("word")) {
-                String fname = fontInfo.fontLookup("sans-serif", "normal", Font.NORMAL);
-                FontMetrics metrics = fontInfo.getMetricsFor(fname);
-                currentFontState =
-                    new Font(fname, metrics, 12000);
-                TextArea text = getText((Element) obj);
-
-                text.addTrait(Trait.FONT_NAME, fname);
-                text.addTrait(Trait.FONT_SIZE, new Integer(12000));
-
-                if (text != null) {
-                    list.add(text);
-                }
-            } else {
-            }
-        }
-        return list;
-    }
-
-    Viewport getViewport(Element root) {
-        Area child = null;
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj.getNodeName().equals("container")) {
-                child = getContainer((Element) obj);
-            } else if (obj.getNodeName().equals("foreignObject")) {
-                child = getForeignObject((Element) obj);
-            } else if (obj.getNodeName().equals("image")) {
-                child = getImage((Element) obj);
-            }
-        }
-        if (child == null) {
-            return null;
-        }
-        Viewport viewport = new Viewport(child);
-        String str = root.getAttribute("width");
-        if (str != null && !"".equals(str)) {
-            int width = Integer.parseInt(str);
-            viewport.setWidth(width);
-        }
-        return viewport;
-    }
-
-    Container getContainer(Element root) {
-        Container cont = new Container();
-        List blocks = getBlocks(root);
-        for (int i = 0; i < blocks.size(); i++) {
-            Block obj = (Block) blocks.get(i);
-            cont.addBlock(obj);
-        }
-        return cont;
-    }
-
-    ForeignObject getForeignObject(Element root) {
-        Document doc;
-        String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
-
-        NodeList childs = root.getChildNodes();
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            if (obj instanceof Element) {
-                //getLogger().debug(obj.getNodeName());
-                Element rootEle = (Element) obj;
-                String space = rootEle.getAttribute("xmlns");
-                if (svgNS.equals(space)) {
-                    try {
-                        DocumentBuilderFactory fact =
-                          DocumentBuilderFactory.newInstance();
-                        fact.setNamespaceAware(true);
-
-                        doc = fact.newDocumentBuilder().newDocument();
-                        Node node = doc.importNode(obj, true);
-                        doc.appendChild(node);
-                        //DOMImplementation impl =
-                        //  SVGDOMImplementation.getDOMImplementation();
-                        // due to namespace problem attributes are not cloned
-                        // serializing causes an npe
-                        //doc = DOMUtilities.deepCloneDocument(doc, impl);
-
-                        ForeignObject fo = new ForeignObject(doc, svgNS);
-                        return fo;
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                } else {
-                    try {
-                        DocumentBuilderFactory fact =
-                          DocumentBuilderFactory.newInstance();
-                        fact.setNamespaceAware(true);
-                        doc = fact.newDocumentBuilder().newDocument();
-                        Node node = doc.importNode(obj, true);
-                        doc.appendChild(node);
-                        ForeignObject fo = new ForeignObject(doc, space);
-                        return fo;
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    Image getImage(Element root) {
-        String url = root.getAttribute("url");
-        Image image = new Image(url);
-        return image;
-    }
-
-    Leader getLeader(Element root) {
-        Leader leader = new Leader();
-        String rs = root.getAttribute("ruleStyle");
-        if ("solid".equals(rs)) {
-            leader.setRuleStyle(Constants.RuleStyle.SOLID);
-        } else if ("dotted".equals(rs)) {
-            leader.setRuleStyle(Constants.RuleStyle.DOTTED);
-        } else if ("dashed".equals(rs)) {
-            leader.setRuleStyle(Constants.RuleStyle.DASHED);
-        } else if ("double".equals(rs)) {
-            leader.setRuleStyle(Constants.RuleStyle.DOUBLE);
-        } else if ("groove".equals(rs)) {
-            leader.setRuleStyle(Constants.RuleStyle.GROOVE);
-        } else if ("ridge".equals(rs)) {
-            leader.setRuleStyle(Constants.RuleStyle.RIDGE);
-        }
-        String rt = root.getAttribute("ruleThickness");
-        int thick = Integer.parseInt(rt);
-        leader.setRuleThickness(thick);
-        rt = root.getAttribute("width");
-        if (rt != null && !"".equals(rt)) {
-            thick = Integer.parseInt(rt);
-            leader.setWidth(thick);
-        }
-        leader.setOffset(currentFontState.getCapHeight());
-        addTraits(root, leader);
-        return leader;
-    }
-
-    TextArea getText(Element root) {
-        String str = getString(root);
-        TextArea text = new TextArea();
-        text.setTextArea(str);
-        addTraits(root, text);
-        int width = 0;
-        for (int count = 0; count < str.length(); count++) {
-            width += currentFontState.getWidth(str.charAt(count));
-        }
-        text.setWidth(width);
-        text.setOffset(currentFontState.getCapHeight());
-
-        return text;
-    }
-
-
-    public void addTraits(Element ele, Area area) {
-        String str = ele.getAttribute("props");
-        StringTokenizer st = new StringTokenizer(str, ";");
-        while (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            int index = tok.indexOf(":");
-            String id = tok.substring(0, index);
-            Object traitCode = Trait.getTraitCode(id);
-            if (traitCode != null) {
-                area.addTrait(traitCode,
-                      Trait.makeTraitValue(traitCode,
-                               tok.substring(index + 1)));
-            } else {
-                logger.error("Unknown trait: " + id);
-            }
-        }
-    }
-
-    public List getRanges(Element ele) {
-        List list = new java.util.ArrayList();
-        String str = ele.getAttribute("ranges");
-        StringTokenizer st = new StringTokenizer(str, ";");
-        while (st.hasMoreTokens()) {
-            /*String tok =*/ st.nextToken();
-        }
-        return list;
-    }
-
-    public String getString(Element ele) {
-        String str = "";
-        NodeList childs = ele.getChildNodes();
-        if (childs.getLength() == 0) {
-            return null;
-        }
-        for (int i = 0; i < childs.getLength(); i++) {
-            Node obj = childs.item(i);
-            str = str + obj.getNodeValue();
-        }
-        return str;
-    }
-
-}
-