From 18a28ab107b07c5ba0fee9a57ede8fb00b2fbaa3 Mon Sep 17 00:00:00 2001 From: Glen Mazza Date: Wed, 7 Jul 2004 01:51:50 +0000 Subject: [PATCH] 1.) Moved the Renderer creation further down from AreaTree to RenderPagesModel (subclass of AreaTreeModel). Still have the issue of the four-param constructor a bit messy, also some of the exceptions I have to declare to be thrown may not be necessary. 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 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 | 113 +-- .../org/apache/fop/area/AreaTreeModel.java | 7 +- .../fop/area/CachedRenderPagesModel.java | 13 +- .../org/apache/fop/area/RenderPagesModel.java | 84 +- .../org/apache/fop/area/StorePagesModel.java | 6 +- src/java/org/apache/fop/fo/FObj.java | 34 +- .../org/apache/fop/fo/pagination/Title.java | 14 + .../org/apache/fop/tools/AreaTreeBuilder.java | 789 ------------------ 8 files changed, 156 insertions(+), 904 deletions(-) delete mode 100644 src/java/org/apache/fop/tools/AreaTreeBuilder.java diff --git a/src/java/org/apache/fop/area/AreaTree.java b/src/java/org/apache/fop/area/AreaTree.java index 3334cda39..26593ceb9 100644 --- a/src/java/org/apache/fop/area/AreaTree.java +++ b/src/java/org/apache/fop/area/AreaTree.java @@ -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); - } } /** diff --git a/src/java/org/apache/fop/area/AreaTreeModel.java b/src/java/org/apache/fop/area/AreaTreeModel.java index a0ba93f50..d57d10d19 100644 --- a/src/java/org/apache/fop/area/AreaTreeModel.java +++ b/src/java/org/apache/fop/area/AreaTreeModel.java @@ -18,11 +18,14 @@ 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. diff --git a/src/java/org/apache/fop/area/CachedRenderPagesModel.java b/src/java/org/apache/fop/area/CachedRenderPagesModel.java index ef7c314bf..5446f9952 100644 --- a/src/java/org/apache/fop/area/CachedRenderPagesModel.java +++ b/src/java/org/apache/fop/area/CachedRenderPagesModel.java @@ -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); } /** diff --git a/src/java/org/apache/fop/area/RenderPagesModel.java b/src/java/org/apache/fop/area/RenderPagesModel.java index 3ad65a8f6..96fcb8a7e 100644 --- a/src/java/org/apache/fop/area/RenderPagesModel.java +++ b/src/java/org/apache/fop/area/RenderPagesModel.java @@ -18,13 +18,22 @@ 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); + } } } diff --git a/src/java/org/apache/fop/area/StorePagesModel.java b/src/java/org/apache/fop/area/StorePagesModel.java index d901bbc91..23903ff5e 100644 --- a/src/java/org/apache/fop/area/StorePagesModel.java +++ b/src/java/org/apache/fop/area/StorePagesModel.java @@ -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 { } } diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java index 64a681326..06dd20a5b 100644 --- a/src/java/org/apache/fop/fo/FObj.java +++ b/src/java/org/apache/fop/fo/FObj.java @@ -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"))); } } diff --git a/src/java/org/apache/fop/fo/pagination/Title.java b/src/java/org/apache/fop/fo/pagination/Title.java index 70a24b9cc..5ebc2b144 100644 --- a/src/java/org/apache/fop/fo/pagination/Title.java +++ b/src/java/org/apache/fop/fo/pagination/Title.java @@ -18,6 +18,10 @@ 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 index c844a0d8a..000000000 --- a/src/java/org/apache/fop/tools/AreaTreeBuilder.java +++ /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; - } - -} - -- 2.39.5