You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2006/01/17 12:08:04 UTC
svn commit: r369753 [1/2] - in /xmlgraphics/fop/trunk: ./
examples/embedding/java/embedding/intermediate/
examples/mathml/src/org/apache/fop/mathml/
examples/plan/src/org/apache/fop/plan/ src/java/org/apache/fop/area/
src/java/org/apache/fop/area/inlin...
Author: jeremias
Date: Tue Jan 17 03:07:10 2006
New Revision: 369753
URL: http://svn.apache.org/viewcvs?rev=369753&view=rev
Log:
New feature: "Intermediate format" (IF). The IF is basically the XML dialect written by the area tree renderer (XMLRenderer). A new parser for this format allows reparsing a serialized and possibly modified area tree and rendering it to the final target format. More details on the Wiki at http://wiki.apache.org/xmlgraphics-fop/AreaTreeIntermediateXml. No advanced features have been implemented, yet, only the basic functionality. The whole change should be fully backwards-compatible WRT the outer FOP API except maybe for FOTreeBuilder.addElementMapping(), and the area tree XML which got small changes.
The area tree has been cleaned up. The serializability has been restored. The CachedRenderPagesModel works again and can, in certain situations, decrease the maximum amount of memory held at one point in time. Some adjustments were necessary in the area tree to help the work of the AreaTreeParser.
The AreaTreeParser is new and is responsible for parsing area tree XML files and adding pages to a RenderPagesModel instance. It is SAX-based and should be pretty efficient.
XMLUnit (http://xmlunit.sourceforge.net, BSD license) is a new dependency for the test code. It is used to verify the correctness of the intermediate format code. It doesn't have to be installed for the build to run through, though.
ElementMapping got a new method getDOMImplementation() which provides the DOMImplementation used to handle a subdocument of a particular namespace. For example, SVG uses Batik's SVG DOM. The AreaTreeParser needs that to properly recreate foreign objects because it can't use the mechanism of the FO tree. The default implementation returns null.
The ElementMapping instances are no longer maintained by the FOTreeBuilder, but by the newly created ElementMappingRegistry class. It is expected that the instance of this class is moved from the FOTreeBuilder and the AreaTreeParser's Handler class to the "environment class" once it is created to cut down on the startup time for each processed document.
The XMLRenderer has been slightly modified to improve the serialization/deserialization qualities of the area tree XML format.
The XMLRenderer can now mimic another renderer (see mimicRenderer(Renderer)) in order to use its font setup. That way it is made certain that the reparsed area tree will render to the final target format exactly as expected.
Fixed a bug in the XMLHandlerRegistry which did not always return the right XMLHandler for every situation.
Added a DefaultErrorListener to the util package. I've had problems with Xalan-J swallowing exceptions with its default ErrorListener, so I added a simple one for convenience and use in AreaTreeParser.
Example code for working with the AreaTreeParser can be found in examples/embedding. Documentation will follow.
Added:
xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/
xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/ExampleConcat.java (with props)
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java (with props)
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMappingRegistry.java (with props)
xmlgraphics/fop/trunk/src/java/org/apache/fop/util/DefaultErrorListener.java (with props)
xmlgraphics/fop/trunk/test/java/org/apache/fop/intermediate/
xmlgraphics/fop/trunk/test/java/org/apache/fop/intermediate/AreaTreeParserTestCase.java (with props)
xmlgraphics/fop/trunk/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java (with props)
xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/
xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/BorderPropsTestCase.java (with props)
xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/TraitColorTestCase.java (with props)
Modified:
xmlgraphics/fop/trunk/build.xml
xmlgraphics/fop/trunk/examples/mathml/src/org/apache/fop/mathml/MathMLElementMapping.java
xmlgraphics/fop/trunk/examples/plan/src/org/apache/fop/plan/PlanElementMapping.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BeforeFloat.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Footnote.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Page.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionReference.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/ForeignObject.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Leader.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Viewport.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMapping.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/svg/BatikExtensionElementMapping.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/svg/SVGElementMapping.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/XMLHandlerRegistry.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/BorderProps.java
xmlgraphics/fop/trunk/status.xml
xmlgraphics/fop/trunk/test/java/org/apache/fop/UtilityCodeTestSuite.java
xmlgraphics/fop/trunk/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_border_padding.xml
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_display-align.xml
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_svg.xml
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/instream-foreign-object_border_padding.xml
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/instream-foreign-object_display-align.xml
Modified: xmlgraphics/fop/trunk/build.xml
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/build.xml?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/build.xml (original)
+++ xmlgraphics/fop/trunk/build.xml Tue Jan 17 03:07:10 2006
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
- Copyright 1999-2005 The Apache Software Foundation
+ Copyright 1999-2006 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.
@@ -258,6 +258,22 @@
</not>
</condition>
<echo message="${junit.message}"/>
+
+ <condition property="xmlunit.present">
+ <and>
+ <available classname="org.custommonkey.xmlunit.XMLTestCase" classpathref="libs-build-classpath"/>
+ <isset property="junit.present"/>
+ </and>
+ </condition>
+ <condition property="xmlunit.message" value="XMLUnit Support PRESENT">
+ <equals arg1="${xmlunit.present}" arg2="true"/>
+ </condition>
+ <condition property="xmlunit.message" value="XMLUnit Support NOT Present - you can get it from http://xmlunit.sourceforge.net">
+ <not>
+ <equals arg1="${xmlunit.present}" arg2="true"/>
+ </not>
+ </condition>
+ <echo message="${xmlunit.message}"/>
</target>
@@ -628,13 +644,22 @@
<!-- =================================================================== -->
<!-- Testing -->
<!-- =================================================================== -->
- <target name="junit-compile" depends="package, transcoder-pkg" description="Runs FOP's JUnit tests" if="junit.present">
+ <target name="junit-with-xmlunit" depends="init-avail" if="xmlunit.present">
+ <patternset id="test-sources"/>
+ </target>
+ <target name="junit-without-xmlunit" depends="init-avail" unless="xmlunit.present">
+ <patternset id="test-sources">
+ <exclude name="**/intermediate/*"/>
+ </patternset>
+ </target>
+ <target name="junit-compile" depends="package, transcoder-pkg, junit-with-xmlunit, junit-without-xmlunit" description="Runs FOP's JUnit tests" if="junit.present">
<mkdir dir="${build.dir}/test-classes"/>
<javac destdir="${build.dir}/test-classes" fork="javac.fork"
debug="${javac.debug}" deprecation="${javac.deprecation}"
optimize="${javac.optimize}" source="${javac.source}"
target="${javac.target}">
<src path="${basedir}/test/java"/>
+ <patternset refid="test-sources"/>
<classpath>
<path refid="libs-build-classpath"/>
<fileset dir="${build.dir}">
@@ -802,7 +827,30 @@
</junit>
</target>
- <target name="junit" depends="junit-basic, junit-transcoder, junit-layout, junit-fotree" description="Runs all of FOP's JUnit tests" if="junit.present">
+ <target name="junit-intermediate-format" depends="junit-compile" description="Runs FOP's intermediate format JUnit tests" if="xmlunit.present">
+ <echo message="Running intermediate format tests"/>
+ <junit haltonerror="no" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure">
+ <sysproperty key="basedir" value="${basedir}"/>
+ <sysproperty key="jawa.awt.headless" value="true"/>
+ <sysproperty key="fop.layoutengine.disabled" value="${layoutengine.disabled}"/>
+ <sysproperty key="fop.layoutengine.testset" value="standard"/>
+ <formatter type="brief" usefile="false"/>
+ <classpath>
+ <pathelement location="${build.dir}/test-classes"/>
+ <path refid="libs-build-classpath"/>
+ <fileset dir="build">
+ <include name="fop.jar"/>
+ </fileset>
+ </classpath>
+ <batchtest todir="${build.dir}/test-reports/fop">
+ <fileset dir="${build.dir}/test-classes">
+ <include name="org/apache/fop/intermediate/IntermediateFormatTestSuite.class"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="junit" depends="junit-basic, junit-transcoder, junit-layout, junit-fotree, junit-intermediate-format" description="Runs all of FOP's JUnit tests" if="junit.present">
<fail>
<condition>
<or>
Added: xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/ExampleConcat.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/ExampleConcat.java?rev=369753&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/ExampleConcat.java (added)
+++ xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/ExampleConcat.java Tue Jan 17 03:07:10 2006
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2006 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: ExampleDOM2PDF.java 332791 2005-11-12 15:58:07Z jeremias $ */
+
+package embedding.intermediate;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.area.AreaTreeModel;
+import org.apache.fop.area.AreaTreeParser;
+import org.apache.fop.area.RenderPagesModel;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.render.xml.XMLRenderer;
+import org.xml.sax.SAXException;
+
+import embedding.ExampleObj2XML;
+import embedding.model.ProjectMember;
+import embedding.model.ProjectTeam;
+
+/**
+ * Example for the intermediate format that demonstrates the concatenation of two documents
+ * renderered to the intermediate format. A single PDF file is generated from the two intermediate
+ * files.
+ */
+public class ExampleConcat {
+
+ /**
+ * Creates a sample ProjectTeam instance for this demo.
+ * @return ProjectTeam the newly created ProjectTeam instance
+ */
+ public static ProjectTeam createAnotherProjectTeam() {
+ ProjectTeam team = new ProjectTeam();
+ team.setProjectName("The Dynamic Duo");
+ team.addMember(new ProjectMember(
+ "Batman", "lead", "batman@heroes.org"));
+ team.addMember(new ProjectMember(
+ "Robin", "aid", "robin@heroes.org"));
+ return team;
+ }
+
+ /**
+ * Converts an XSL-FO document to an intermediate file.
+ * @param src the source file
+ * @param xslt the stylesheet file
+ * @param intermediate the target intermediate file (area tree XML)
+ * @throws IOException In case of an I/O problem
+ * @throws FOPException In case of a FOP problem
+ * @throws TransformerException In case of a XSL transformation problem
+ */
+ public void convertToIntermediate(Source src, Source xslt, File intermediate)
+ throws IOException, FOPException, TransformerException {
+
+ //Create a user agent
+ FOUserAgent userAgent = new FOUserAgent();
+
+ //Create an instance of the target renderer so the XMLRenderer can use its font setup
+ Renderer targetRenderer = userAgent.getRendererFactory().createRenderer(
+ userAgent, MimeConstants.MIME_PDF);
+
+ //Create the XMLRenderer to create the intermediate format (area tree XML)
+ XMLRenderer xmlRenderer = new XMLRenderer();
+ xmlRenderer.setUserAgent(userAgent);
+
+ //Tell the XMLRenderer to mimic the target renderer
+ xmlRenderer.mimicRenderer(targetRenderer);
+
+ //Make sure the prepared XMLRenderer is used
+ userAgent.setRendererOverride(xmlRenderer);
+
+ // Construct fop (the MIME type here is unimportant due to the override on the user agent)
+ Fop fop = new Fop(MimeConstants.MIME_FOP_AREA_TREE, userAgent);
+
+ // Setup output
+ OutputStream out = new java.io.FileOutputStream(intermediate);
+ out = new java.io.BufferedOutputStream(out);
+ try {
+ fop.setOutputStream(out);
+
+ // Setup XSLT
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer;
+ if (xslt != null) {
+ transformer = factory.newTransformer(xslt);
+ } else {
+ transformer = factory.newTransformer();
+ }
+
+ // Resulting SAX events (the generated FO) must be piped through to FOP
+ Result res = new SAXResult(fop.getDefaultHandler());
+
+ // Start XSLT transformation and FOP processing
+ transformer.transform(src, res);
+ } finally {
+ out.close();
+ }
+ }
+
+ /**
+ * Concatenates an array of intermediate files to a single PDF file.
+ * @param files the array of intermediate files (area tree XML)
+ * @param pdffile the target PDF file
+ * @throws IOException In case of an I/O problem
+ * @throws TransformerException In case of a XSL transformation problem
+ * @throws SAXException In case of an XML-related problem
+ */
+ public void concatToPDF(File[] files, File pdffile)
+ throws IOException, TransformerException, SAXException {
+ // Setup output
+ OutputStream out = new java.io.FileOutputStream(pdffile);
+ out = new java.io.BufferedOutputStream(out);
+ try {
+ //Setup fonts and user agent
+ FontInfo fontInfo = new FontInfo();
+ FOUserAgent userAgent = new FOUserAgent();
+
+ //Construct the AreaTreeModel that will received the individual pages
+ AreaTreeModel treeModel = new RenderPagesModel(userAgent,
+ MimeConstants.MIME_PDF, fontInfo, out);
+
+ //Iterate over all intermediate files
+ AreaTreeParser parser = new AreaTreeParser();
+ for (int i = 0; i < files.length; i++) {
+ Source src = new StreamSource(files[i]);
+ parser.parse(src, treeModel, userAgent);
+ }
+
+ //Signal the end of the processing. The renderer can finalize the target document.
+ treeModel.endDocument();
+ } finally {
+ out.close();
+ }
+ }
+
+ /**
+ * Main method.
+ * @param args command-line arguments
+ */
+ public static void main(String[] args) {
+ try {
+ System.out.println("FOP ExampleConcat\n");
+
+ //Setup directories
+ File baseDir = new File(".");
+ File outDir = new File(baseDir, "out");
+ outDir.mkdirs();
+
+ //Setup output file
+ File xsltfile = new File(baseDir, "xml/xslt/projectteam2fo.xsl");
+ File[] files = new File[] {
+ new File(outDir, "team1.at.xml"),
+ new File(outDir, "team2.at.xml")};
+ File pdffile = new File(outDir, "ResultConcat.pdf");
+ for (int i = 0; i < files.length; i++) {
+ System.out.println("Intermediate file " + (i + 1) + ": "
+ + files[i].getCanonicalPath());
+ }
+ System.out.println("PDF Output File: " + pdffile.getCanonicalPath());
+ System.out.println();
+
+
+ ProjectTeam team1 = ExampleObj2XML.createSampleProjectTeam();
+ ProjectTeam team2 = createAnotherProjectTeam();
+
+ ExampleConcat app = new ExampleConcat();
+
+ //Create intermediate files
+ app.convertToIntermediate(
+ team1.getSourceForProjectTeam(),
+ new StreamSource(xsltfile), files[0]);
+ app.convertToIntermediate(
+ team2.getSourceForProjectTeam(),
+ new StreamSource(xsltfile), files[1]);
+
+ //Concatenate the individual intermediate files to one document
+ app.concatToPDF(files, pdffile);
+
+ System.out.println("Success!");
+
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ System.exit(-1);
+ }
+ }
+
+}
Propchange: xmlgraphics/fop/trunk/examples/embedding/java/embedding/intermediate/ExampleConcat.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: xmlgraphics/fop/trunk/examples/mathml/src/org/apache/fop/mathml/MathMLElementMapping.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/examples/mathml/src/org/apache/fop/mathml/MathMLElementMapping.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/examples/mathml/src/org/apache/fop/mathml/MathMLElementMapping.java (original)
+++ xmlgraphics/fop/trunk/examples/mathml/src/org/apache/fop/mathml/MathMLElementMapping.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 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.
@@ -22,6 +22,7 @@
import org.apache.fop.fo.ElementMapping;
import org.apache.fop.image.analyser.XMLReader;
import org.apache.fop.image.FopImage;
+import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import java.util.HashMap;
@@ -37,10 +38,17 @@
/** MathML Namespace */
public static final String NAMESPACE = "http://www.w3.org/1998/Math/MathML";
+ /** Main constructor. */
public MathMLElementMapping() {
this.namespaceURI = NAMESPACE;
}
+ /** @see org.apache.fop.fo.ElementMapping#getDOMImplementation() */
+ public DOMImplementation getDOMImplementation() {
+ return getDefaultDOMImplementation();
+ }
+
+ /** @see org.apache.fop.fo.ElementMapping#initialize() */
protected void initialize() {
if (foObjs == null) {
foObjs = new HashMap();
Modified: xmlgraphics/fop/trunk/examples/plan/src/org/apache/fop/plan/PlanElementMapping.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/examples/plan/src/org/apache/fop/plan/PlanElementMapping.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/examples/plan/src/org/apache/fop/plan/PlanElementMapping.java (original)
+++ xmlgraphics/fop/trunk/examples/plan/src/org/apache/fop/plan/PlanElementMapping.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 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.
@@ -22,10 +22,9 @@
import org.apache.fop.fo.ElementMapping;
import org.apache.fop.image.analyser.XMLReader;
import org.apache.fop.image.FopImage;
+import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
-import java.util.HashMap;
-
/**
* This class provides the element mapping for FOP.
*/
@@ -34,10 +33,17 @@
/** Plan Namespace */
public static final String NAMESPACE = "http://xmlgraphics.apache.org/fop/plan";
+ /** Main constructor. */
public PlanElementMapping() {
this.namespaceURI = NAMESPACE;
}
+ /** @see org.apache.fop.fo.ElementMapping#getDOMImplementation() */
+ public DOMImplementation getDOMImplementation() {
+ return getDefaultDOMImplementation();
+ }
+
+ /** @see org.apache.fop.fo.ElementMapping#initialize() */
protected void initialize() {
if (foObjs == null) {
foObjs = new java.util.HashMap();
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java?rev=369753&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java Tue Jan 17 03:07:10 2006
@@ -0,0 +1,676 @@
+/*
+ * Copyright 2006 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.area;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.area.Trait.Background;
+import org.apache.fop.area.Trait.Color;
+import org.apache.fop.area.inline.AbstractTextArea;
+import org.apache.fop.area.inline.Character;
+import org.apache.fop.area.inline.ForeignObject;
+import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.InlineBlockParent;
+import org.apache.fop.area.inline.InlineParent;
+import org.apache.fop.area.inline.Leader;
+import org.apache.fop.area.inline.Space;
+import org.apache.fop.area.inline.SpaceArea;
+import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.area.inline.WordArea;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.ElementMappingRegistry;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.util.DefaultErrorListener;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * This is a parser for the area tree XML (intermediate format) which is used to reread an area
+ * tree (or part of it) into memory again for rendering to the final output format.
+ */
+public class AreaTreeParser {
+
+ /** Logger instance */
+ protected static Log log = LogFactory.getLog(AreaTreeParser.class);
+
+ private static SAXTransformerFactory tFactory
+ = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+
+ /**
+ * Parses an intermediate file (area tree XML) into an AreaTreeModel instance by adding
+ * pages to it.
+ * @param src the Source instance pointing to the intermediate file
+ * @param treeModel the AreaTreeModel that the parsed pages are added to
+ * @param userAgent the user agent
+ * @throws TransformerException if an error occurs while parsing the area tree XML
+ */
+ public void parse(Source src, AreaTreeModel treeModel, FOUserAgent userAgent)
+ throws TransformerException {
+ Transformer transformer = tFactory.newTransformer();
+ transformer.setErrorListener(new DefaultErrorListener(log));
+
+ SAXResult res = new SAXResult(getContentHandler(treeModel, userAgent));
+
+ transformer.transform(src, res);
+ }
+
+ /**
+ * Creates a new ContentHandler instance that you can send the area tree XML to. The parsed
+ * pages are added to the AreaTreeModel instance you pass in as a parameter.
+ * @param treeModel the AreaTreeModel that the parsed pages are added to
+ * @param userAgent the user agent
+ * @return the ContentHandler instance to receive the SAX stream from the area tree XML
+ */
+ public ContentHandler getContentHandler(AreaTreeModel treeModel, FOUserAgent userAgent) {
+ //TODO Retrieve this instance from the environment class once it has been created.
+ ElementMappingRegistry elementMappingRegistry = new ElementMappingRegistry(userAgent);
+ return new Handler(treeModel, userAgent, elementMappingRegistry);
+ }
+
+ private static class Handler extends DefaultHandler {
+
+ private AreaTreeModel treeModel;
+ private FOUserAgent userAgent;
+ private ElementMappingRegistry elementMappingRegistry;
+
+ private Attributes lastAttributes;
+ private StringBuffer content = new StringBuffer();
+
+ private PageViewport currentPageViewport;
+ private Stack areaStack = new Stack();
+ private boolean firstFlow;
+
+ private Stack delegateStack = new Stack();
+ private ContentHandler delegate;
+ private DOMImplementation domImplementation;
+
+ public Handler(AreaTreeModel treeModel, FOUserAgent userAgent,
+ ElementMappingRegistry elementMappingRegistry) {
+ this.treeModel = treeModel;
+ this.userAgent = userAgent;
+ this.elementMappingRegistry = elementMappingRegistry;
+ }
+
+ private static Rectangle2D parseRect(String rect) {
+ StringTokenizer tokenizer = new StringTokenizer(rect, " ");
+ return new Rectangle2D.Double(
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()));
+ }
+
+ private Area findAreaType(Class clazz) {
+ if (areaStack.size() > 0) {
+ int pos = areaStack.size() - 1;
+ Object obj = null;
+ while (pos >= 0 && !(clazz.isInstance(obj = areaStack.get(pos)))) {
+ pos--;
+ }
+ if (pos >= 0) {
+ return (Area)obj;
+ }
+ }
+ return null;
+ }
+
+ private RegionViewport getCurrentRegionViewport() {
+ return (RegionViewport)findAreaType(RegionViewport.class);
+ }
+
+ private BodyRegion getCurrentBodyRegion() {
+ return (BodyRegion)findAreaType(BodyRegion.class);
+ }
+
+ private BlockParent getCurrentBlockParent() {
+ return (BlockParent)findAreaType(BlockParent.class);
+ }
+
+ private AbstractTextArea getCurrentText() {
+ return (AbstractTextArea)findAreaType(AbstractTextArea.class);
+ }
+
+ private Viewport getCurrentViewport() {
+ return (Viewport)findAreaType(Viewport.class);
+ }
+
+ /** @see org.xml.sax.helpers.DefaultHandler */
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException {
+ if (delegate != null) {
+ delegateStack.push(qName);
+ delegate.startElement(uri, localName, qName, attributes);
+ } else if (domImplementation != null) {
+ TransformerHandler handler;
+ try {
+ handler = tFactory.newTransformerHandler();
+ } catch (TransformerConfigurationException e) {
+ throw new SAXException("Error creating a new TransformerHandler", e);
+ }
+ Document doc = domImplementation.createDocument(uri, qName, null);
+ //It's easier to work with an empty document, so remove the root element
+ doc.removeChild(doc.getDocumentElement());
+ handler.setResult(new DOMResult(doc));
+ Area parent = (Area)areaStack.peek();
+ ((ForeignObject)parent).setDocument(doc);
+
+ //activate delegate for nested foreign document
+ this.delegate = handler;
+ delegateStack.push(qName);
+ delegate.startDocument();
+ delegate.startElement(uri, localName, qName, attributes);
+ } else {
+ lastAttributes = attributes;
+ boolean handled = true;
+ if ("".equals(uri)) {
+ if ("areaTree".equals(localName)) {
+ //nop
+ } else if ("pageSequence".equals(localName)) {
+ treeModel.startPageSequence(null);
+ } else if ("pageViewport".equals(localName)) {
+ if (currentPageViewport != null) {
+ throw new IllegalStateException("currentPageViewport must be null");
+ }
+ Rectangle2D viewArea = parseRect(attributes.getValue("bounds"));
+ currentPageViewport = new PageViewport(viewArea, attributes.getValue("nr"));
+ } else if ("page".equals(localName)) {
+ Page p = new Page();
+ currentPageViewport.setPage(p);
+ } else if ("regionViewport".equals(localName)) {
+ RegionViewport rv = getCurrentRegionViewport();
+ if (rv != null) {
+ throw new IllegalStateException("Current RegionViewport must be null");
+ }
+ Rectangle2D viewArea = parseRect(attributes.getValue("rect"));
+ rv = new RegionViewport(viewArea);
+ rv.setClip(getAttributeAsBoolean(attributes, "clipped", false));
+ setAreaAttributes(attributes, rv);
+ setTraits(attributes, rv);
+ areaStack.push(rv);
+ } else if ("regionBefore".equals(localName)) {
+ pushNewRegionReference(attributes, Constants.FO_REGION_BEFORE);
+ } else if ("regionAfter".equals(localName)) {
+ pushNewRegionReference(attributes, Constants.FO_REGION_AFTER);
+ } else if ("regionStart".equals(localName)) {
+ pushNewRegionReference(attributes, Constants.FO_REGION_START);
+ } else if ("regionEnd".equals(localName)) {
+ pushNewRegionReference(attributes, Constants.FO_REGION_END);
+ } else if ("regionBody".equals(localName)) {
+ BodyRegion body = getCurrentBodyRegion();
+ if (body != null) {
+ throw new IllegalStateException("Current BodyRegion must be null");
+ }
+ String regionName = attributes.getValue("name");
+ int columnCount = getAttributeAsInteger(attributes, "columnCount", 1);
+ int columnGap = getAttributeAsInteger(attributes, "columnGap", 0);
+ RegionViewport rv = getCurrentRegionViewport();
+ body = new BodyRegion(Constants.FO_REGION_BODY,
+ regionName, rv, columnCount, columnGap);
+ body.setCTM(getAttributeAsCTM(attributes, "ctm"));
+ setAreaAttributes(attributes, body);
+ rv.setRegionReference(body);
+ currentPageViewport.getPage().setRegionViewport(
+ Constants.FO_REGION_BODY, rv);
+ areaStack.push(body);
+ } else if ("mainReference".equals(localName)) {
+ //mainReference is created by the BodyRegion
+ setAreaAttributes(attributes, getCurrentBodyRegion().getMainReference());
+ } else if ("span".equals(localName)) {
+ int ipd = getAttributeAsInteger(attributes, "ipd", 0);
+ int columnCount = getAttributeAsInteger(attributes, "columnCount", 1);
+ BodyRegion body = getCurrentBodyRegion();
+ Span span = new Span(columnCount,
+ body.getColumnGap(), ipd);
+ setAreaAttributes(attributes, span);
+ body.getMainReference().getSpans().add(span);
+ firstFlow = true;
+ } else if ("flow".equals(localName)) {
+ BodyRegion body = getCurrentBodyRegion();
+ if (!firstFlow) {
+ body.getMainReference().getCurrentSpan().moveToNextFlow();
+ } else {
+ firstFlow = false;
+ }
+ NormalFlow flow = body.getMainReference().getCurrentSpan().getCurrentFlow();
+ setAreaAttributes(attributes, flow);
+ areaStack.push(flow);
+ } else if ("footnote".equals(localName)) {
+ areaStack.push(getCurrentBodyRegion().getFootnote());
+ } else if ("beforeFloat".equals(localName)) {
+ areaStack.push(getCurrentBodyRegion().getBeforeFloat());
+ } else if ("block".equals(localName)) {
+ boolean isViewport = getAttributeAsBoolean(attributes,
+ "is-viewport-area", false);
+ Block block;
+ if (isViewport) {
+ BlockViewport bv = new BlockViewport();
+ bv.setClip(getAttributeAsBoolean(attributes, "clipped", false));
+ bv.setCTM(getAttributeAsCTM(attributes, "ctm"));
+ if (bv.getPositioning() != BlockViewport.RELATIVE) {
+ bv.setXOffset(
+ getAttributeAsInteger(attributes, "left-position", 0));
+ bv.setYOffset(
+ getAttributeAsInteger(attributes, "top-position", 0));
+ }
+ block = bv;
+ } else {
+ block = new Block();
+ }
+ String positioning = attributes.getValue("positioning");
+ if ("absolute".equalsIgnoreCase(positioning)) {
+ block.setPositioning(Block.ABSOLUTE);
+ } else if ("fixed".equalsIgnoreCase(positioning)) {
+ block.setPositioning(Block.FIXED);
+ } else if ("relative".equalsIgnoreCase(positioning)) {
+ block.setPositioning(Block.RELATIVE);
+ } else {
+ block.setPositioning(Block.STACK);
+ }
+ if (attributes.getValue("left-offset") != null) {
+ block.setXOffset(getAttributeAsInteger(attributes, "left-offset", 0));
+ }
+ if (attributes.getValue("top-offset") != null) {
+ block.setYOffset(getAttributeAsInteger(attributes, "top-offset", 0));
+ }
+ setAreaAttributes(attributes, block);
+ setTraits(attributes, block);
+ Area parent = (Area)areaStack.peek();
+ //BlockParent parent = getCurrentBlockParent();
+ parent.addChildArea(block);
+ areaStack.push(block);
+ } else if ("lineArea".equals(localName)) {
+ LineArea line = new LineArea();
+ setAreaAttributes(attributes, line);
+ setTraits(attributes, line);
+ BlockParent parent = getCurrentBlockParent();
+ parent.addChildArea(line);
+ areaStack.push(line);
+ } else if ("inlineparent".equals(localName)) {
+ InlineParent ip = new InlineParent();
+ ip.setOffset(getAttributeAsInteger(attributes, "offset", 0));
+ setAreaAttributes(attributes, ip);
+ setTraits(attributes, ip);
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(ip);
+ areaStack.push(ip);
+ } else if ("inlineblockparent".equals(localName)) {
+ InlineBlockParent ibp = new InlineBlockParent();
+ ibp.setOffset(getAttributeAsInteger(attributes, "offset", 0));
+ setAreaAttributes(attributes, ibp);
+ setTraits(attributes, ibp);
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(ibp);
+ areaStack.push(ibp);
+ } else if ("text".equals(localName)) {
+ if (getCurrentText() != null) {
+ throw new IllegalStateException("Current Text must be null");
+ }
+ TextArea text = new TextArea();
+ setAreaAttributes(attributes, text);
+ setTraits(attributes, text);
+ text.setBaselineOffset(getAttributeAsInteger(attributes, "baseline", 0));
+ text.setTextLetterSpaceAdjust(getAttributeAsInteger(attributes,
+ "tlsadjust", 0));
+ text.setTextWordSpaceAdjust(getAttributeAsInteger(attributes,
+ "twsadjust", 0));
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(text);
+ areaStack.push(text);
+ } else if ("word".equals(localName)) {
+ //handled in endElement
+ } else if ("space".equals(localName)) {
+ //handled in endElement
+ } else if ("char".equals(localName)) {
+ //handled in endElement
+ } else if ("leader".equals(localName)) {
+ Leader leader = new Leader();
+ setAreaAttributes(attributes, leader);
+ setTraits(attributes, leader);
+ leader.setOffset(getAttributeAsInteger(attributes, "offset", 0));
+ String ruleStyle = attributes.getValue("ruleStyle");
+ if (ruleStyle != null) {
+ leader.setRuleStyle(ruleStyle);
+ }
+ leader.setRuleThickness(
+ getAttributeAsInteger(attributes, "ruleThickness", 0));
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(leader);
+ } else if ("viewport".equals(localName)) {
+ Viewport viewport = new Viewport(null);
+ setAreaAttributes(attributes, viewport);
+ setTraits(attributes, viewport);
+ viewport.setContentPosition(getAttributeAsRectangle2D(attributes, "pos"));
+ viewport.setClip(getAttributeAsBoolean(attributes, "clip", false));
+ viewport.setOffset(getAttributeAsInteger(attributes, "offset", 0));
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(viewport);
+ areaStack.push(viewport);
+ } else if ("image".equals(localName)) {
+ String url = attributes.getValue("url");
+ Image image = new Image(url);
+ setAreaAttributes(attributes, image);
+ setTraits(attributes, image);
+ getCurrentViewport().setContent(image);
+ } else if ("foreignObject".equals(localName)) {
+ String ns = attributes.getValue("ns");
+ this.domImplementation
+ = elementMappingRegistry.getDOMImplementationForNamespace(ns);
+ if (this.domImplementation == null) {
+ throw new SAXException("No DOMImplementation could be"
+ + " identified to handle namespace: " + ns);
+ }
+ ForeignObject foreign = new ForeignObject(ns);
+ setAreaAttributes(attributes, foreign);
+ setTraits(attributes, foreign);
+ getCurrentViewport().setContent(foreign);
+ areaStack.push(foreign);
+ } else {
+ handled = false;
+ }
+ } else {
+ handled = false;
+ }
+ if (!handled) {
+ throw new SAXException("Unhandled element " + localName
+ + " in namespace: " + uri);
+ }
+ }
+ }
+
+ private void pushNewRegionReference(Attributes attributes, int side) {
+ String regionName = attributes.getValue("name");
+ RegionViewport rv = getCurrentRegionViewport();
+ RegionReference reg = new RegionReference(side,
+ regionName, rv);
+ reg.setCTM(getAttributeAsCTM(attributes, "ctm"));
+ setAreaAttributes(attributes, reg);
+ rv.setRegionReference(reg);
+ currentPageViewport.getPage().setRegionViewport(
+ side, rv);
+ areaStack.push(reg);
+ }
+
+ private void assertObjectOfClass(Object obj, Class clazz) {
+ if (!clazz.isInstance(obj)) {
+ throw new IllegalStateException("Object is not an instance of "
+ + clazz.getName() + " but of " + obj.getClass().getName());
+ }
+ }
+
+ /** @see org.xml.sax.helpers.DefaultHandler */
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (delegate != null) {
+ delegate.endElement(uri, localName, qName);
+ delegateStack.pop();
+ if (delegateStack.size() == 0) {
+ delegate.endDocument();
+ delegate = null;
+ domImplementation = null;
+ }
+ } else {
+ if ("".equals(uri)) {
+ if ("pageSequence".equals(localName)) {
+ //end page-sequence
+ } else if ("page".equals(localName)) {
+ treeModel.addPage(currentPageViewport);
+ currentPageViewport = null;
+ } else if ("pageViewport".equals(localName)) {
+ //nop
+ } else if ("regionViewport".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), RegionViewport.class);
+ } else if ("regionBefore".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), RegionReference.class);
+ } else if ("regionAfter".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), RegionReference.class);
+ } else if ("regionStart".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), RegionReference.class);
+ } else if ("regionEnd".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), RegionReference.class);
+ } else if ("regionBody".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), BodyRegion.class);
+ } else if ("flow".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), NormalFlow.class);
+ } else if ("footnote".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), Footnote.class);
+ } else if ("beforeFloat".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), BeforeFloat.class);
+ } else if ("block".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), Block.class);
+ } else if ("lineArea".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), LineArea.class);
+ } else if ("inlineparent".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), InlineParent.class);
+ } else if ("inlineblockparent".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), InlineBlockParent.class);
+ } else if ("text".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), TextArea.class);
+ } else if ("word".equals(localName)) {
+ int offset = getAttributeAsInteger(lastAttributes, "offset", 0);
+ String txt = content.toString();
+ WordArea word = new WordArea(txt, offset);
+ AbstractTextArea text = getCurrentText();
+ word.setParentArea(text);
+ text.addChildArea(word);
+ } else if ("space".equals(localName)) {
+ int offset = getAttributeAsInteger(lastAttributes, "offset", 0);
+ String txt = content.toString();
+ //TODO the isAdjustable parameter is currently not used/implemented
+ if (txt.length() > 0) {
+ SpaceArea space = new SpaceArea(txt.charAt(0), offset, false);
+ AbstractTextArea text = getCurrentText();
+ space.setParentArea(text);
+ text.addChildArea(space);
+ } else {
+ Space space = new Space();
+ setAreaAttributes(lastAttributes, space);
+ setTraits(lastAttributes, space);
+ space.setOffset(getAttributeAsInteger(lastAttributes, "offset", 0));
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(space);
+ }
+ } else if ("char".equals(localName)) {
+ String txt = content.toString();
+ Character ch = new Character(txt.charAt(0));
+ setAreaAttributes(lastAttributes, ch);
+ setTraits(lastAttributes, ch);
+ ch.setOffset(getAttributeAsInteger(lastAttributes, "offset", 0));
+ ch.setBaselineOffset(getAttributeAsInteger(lastAttributes, "baseline", 0));
+ Area parent = (Area)areaStack.peek();
+ parent.addChildArea(ch);
+ } else if ("viewport".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), Viewport.class);
+ } else if ("foreignObject".equals(localName)) {
+ assertObjectOfClass(areaStack.pop(), ForeignObject.class);
+ }
+ } else {
+ //log.debug("Ignoring " + localName + " in namespace: " + uri);
+ }
+ content.setLength(0); //Reset text buffer (see characters())
+ }
+ }
+
+ private void setAreaAttributes(Attributes attributes, Area area) {
+ area.setIPD(Integer.parseInt(attributes.getValue("ipd")));
+ area.setBPD(Integer.parseInt(attributes.getValue("bpd")));
+ }
+
+ private void setTraits(Attributes attributes, Area area) {
+ for (int i = 0, c = Trait.TRAIT_LIST.length; i < c; i++) {
+ Object trait = Trait.TRAIT_LIST[i];
+ Class cl = Trait.getTraitClass(trait);
+ if (cl == Boolean.class) {
+ String value = attributes.getValue(Trait.getTraitName(trait));
+ if (value != null) {
+ area.addTrait(trait, Boolean.valueOf(value));
+ }
+ } else if (cl == Integer.class) {
+ String value = attributes.getValue(Trait.getTraitName(trait));
+ if (value != null) {
+ area.addTrait(trait, new Integer(value));
+ }
+ } else if (cl == String.class) {
+ String value = attributes.getValue(Trait.getTraitName(trait));
+ if (value != null) {
+ area.addTrait(trait, value);
+ }
+ } else if (cl == FontTriplet.class) {
+ String fontName = attributes.getValue("font-name");
+ if (fontName != null) {
+ String fontStyle = attributes.getValue("font-style");
+ int fontWeight = getAttributeAsInteger(
+ attributes, "font-weight", Font.NORMAL);
+ area.addTrait(trait,
+ new FontTriplet(fontName, fontStyle, fontWeight));
+ }
+ } else if (cl == Color.class) {
+ String value = attributes.getValue(Trait.getTraitName(trait));
+ if (value != null) {
+ area.addTrait(trait, Color.valueOf(value));
+ }
+ } else if (cl == Background.class) {
+ String value = attributes.getValue(Trait.getTraitName(trait));
+ if (value != null) {
+ Background bkg = new Background();
+ Color col = Color.valueOf(attributes.getValue("bkg-color"));
+ if (col != null) {
+ bkg.setColor(col);
+ }
+ String url = attributes.getValue("bkg-img");
+ if (url != null) {
+ bkg.setURL(url);
+
+ ImageFactory fact = ImageFactory.getInstance();
+ FopImage img = fact.getImage(url, userAgent);
+ if (img == null) {
+ log.error("Background image not available: " + url);
+ } else {
+ // load dimensions
+ if (!img.load(FopImage.DIMENSIONS)) {
+ log.error("Cannot read background image dimensions: "
+ + url);
+ }
+ }
+ bkg.setFopImage(img);
+
+ String repeat = attributes.getValue("bkg-repeat");
+ if (repeat != null) {
+ bkg.setRepeat(repeat);
+ }
+ bkg.setHoriz(getAttributeAsInteger(attributes,
+ "bkg-horz-offset", 0));
+ bkg.setVertical(getAttributeAsInteger(attributes,
+ "bkg-vert-offset", 0));
+ }
+ area.addTrait(trait, bkg);
+ }
+ } else if (cl == BorderProps.class) {
+ String value = attributes.getValue(Trait.getTraitName(trait));
+ if (value != null) {
+ area.addTrait(trait, BorderProps.valueOf(value));
+ }
+ }
+ }
+ }
+
+ private boolean getAttributeAsBoolean(Attributes attributes, String name,
+ boolean defaultValue) {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return defaultValue;
+ } else {
+ return Boolean.valueOf(s).booleanValue();
+ }
+ }
+
+ private int getAttributeAsInteger(Attributes attributes, String name,
+ int defaultValue) {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return defaultValue;
+ } else {
+ return Integer.parseInt(s);
+ }
+ }
+
+ private CTM getAttributeAsCTM(Attributes attributes, String name) {
+ String s = attributes.getValue(name).trim();
+ if (s.startsWith("[") && s.endsWith("]")) {
+ s = s.substring(1, s.length() - 1);
+ StringTokenizer tokenizer = new StringTokenizer(s, " ");
+ double[] values = new double[] {
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken())};
+ return new CTM(values[0], values[1], values[2], values[3], values[4], values[5]);
+ } else {
+ throw new IllegalArgumentException("CTM must be surrounded by square brackets");
+ }
+ }
+
+ private Rectangle2D getAttributeAsRectangle2D(Attributes attributes, String name) {
+ String s = attributes.getValue(name).trim();
+ StringTokenizer tokenizer = new StringTokenizer(s, " ");
+ double[] values = new double[] {
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken()),
+ Double.parseDouble(tokenizer.nextToken())};
+ return new Rectangle2D.Double(values[0], values[1], values[2], values[3]);
+ }
+
+ /** @see org.xml.sax.ContentHandler#characters(char[], int, int) */
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (delegate != null) {
+ delegate.characters(ch, start, length);
+ } else {
+ content.append(ch, start, length);
+ }
+ }
+
+ }
+
+}
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BeforeFloat.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BeforeFloat.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BeforeFloat.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BeforeFloat.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -61,6 +61,7 @@
return h;
}
+ /** @see org.apache.fop.area.BlockParent#isEmpty() */
public boolean isEmpty() {
return true; // before floats are not yet implemented
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -77,13 +77,10 @@
* @param autoHeight increase the height of the block.
*/
public void addBlock(Block block, boolean autoHeight) {
- if (children == null) {
- children = new ArrayList();
- }
if (autoHeight) {
bpd += block.getAllocBPD();
}
- children.add(block);
+ addChildArea(block);
}
/**
@@ -92,11 +89,8 @@
* @param line the line area to add
*/
public void addLineArea(LineArea line) {
- if (children == null) {
- children = new ArrayList();
- }
bpd += line.getAllocBPD();
- children.add(line);
+ addChildArea(line);
}
/**
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java Tue Jan 17 03:07:10 2006
@@ -52,16 +52,21 @@
// orientation if reference area
private int orientation = ORIENT_0;
+ /** @see org.apache.fop.area.Area#addChildArea(org.apache.fop.area.Area) */
+ public void addChildArea(Area childArea) {
+ if (children == null) {
+ children = new ArrayList();
+ }
+ children.add(childArea);
+ }
+
/**
* Add the block area to this block parent.
*
* @param block the child block area to add
*/
public void addBlock(Block block) {
- if (children == null) {
- children = new ArrayList();
- }
- children.add(block);
+ addChildArea(block);
}
/**
@@ -71,6 +76,15 @@
*/
public List getChildAreas() {
return children;
+ }
+
+ /**
+ * Check whether there are child areas.
+ *
+ * @return the result.
+ */
+ public boolean isEmpty() {
+ return children == null || children.size() == 0;
}
/**
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Footnote.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Footnote.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Footnote.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Footnote.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -18,9 +18,6 @@
package org.apache.fop.area;
-import java.util.ArrayList;
-import java.util.List;
-
// may combine with before float into a conditional area
/**
@@ -80,29 +77,9 @@
* @param child the block area.
*/
public void addBlock(Block child) {
- if (children == null) {
- children = new ArrayList();
- }
+ addChildArea(child);
this.setBPD(this.getBPD() + child.getBPD());
- children.add(child);
- }
-
- /**
- * Get all child areas.
- *
- * @return the list of child areas. Maybe null.
- */
- public List getChildAreas() {
- return children;
}
- /**
- * Check whether there are child areas.
- *
- * @return the result.
- */
- public boolean isEmpty() {
- return children == null || children.size() == 0;
- }
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -57,13 +57,13 @@
private LineAdjustingInfo adjustingInfo = null;
- private int stacking = LR;
+ //private int stacking = LR;
// contains inline areas
// has start indent and length, dominant baseline, height
private int startIndent;
// this is the offset for the dominant baseline
- private int baseLine;
+ //private int baseLine;
// this class can contain the dominant char styling info
// this means that many renderers can optimise a bit
@@ -82,6 +82,8 @@
* a new LineAdjustingInfo object is created
* @param alignment alignment of this line
* @param diff difference between content width and line width
+ * @param stretch the available stretch for any adjustments
+ * @param shrink the available shrink for any adjustments
*/
public LineArea(int alignment, int diff,
int stretch, int shrink) {
@@ -185,7 +187,8 @@
break;
case Constants.EN_JUSTIFY:
// compute variation factor
- adjustingInfo.variationFactor *= (float) (adjustingInfo.difference - ipdVariation) / adjustingInfo.difference;
+ adjustingInfo.variationFactor *= (float) (adjustingInfo.difference - ipdVariation)
+ / adjustingInfo.difference;
adjustingInfo.difference -= ipdVariation;
// if the LineArea has already been added to the area tree,
// call finalize(); otherwise, wait for the LineLM to call it
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Page.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Page.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Page.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Page.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -187,7 +187,7 @@
* @param areaclass the area class of the region to set
* @param port the region viewport to set
*/
- private void setRegionViewport(int areaclass, RegionViewport port) {
+ public void setRegionViewport(int areaclass, RegionViewport port) {
if (areaclass == Constants.FO_REGION_BEFORE) {
regionBefore = port;
} else if (areaclass == Constants.FO_REGION_START) {
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java Tue Jan 17 03:07:10 2006
@@ -108,6 +108,16 @@
}
/**
+ * Constructor used by the area tree parser.
+ * @param viewArea the view area
+ * @param pageStr String representation of the page number
+ */
+ public PageViewport(Rectangle2D viewArea, String pageStr) {
+ this.viewArea = viewArea;
+ this.pageNumberString = pageStr;
+ }
+
+ /**
* Get the view area rectangle of this viewport.
* @return the rectangle for this viewport
*/
@@ -121,6 +131,14 @@
*/
public Page getPage() {
return page;
+ }
+
+ /**
+ * Sets the page object for this PageViewport.
+ * @param page the page
+ */
+ public void setPage(Page page) {
+ this.page = page;
}
/**
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionReference.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionReference.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionReference.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionReference.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -67,6 +67,11 @@
regionViewport = parent;
}
+ /** @see org.apache.fop.area.Area#addChildArea(org.apache.fop.area.Area) */
+ public void addChildArea(Area child) {
+ blocks.add(child);
+ }
+
/**
* Set the Coordinate Transformation Matrix which transforms content
* coordinates in this region reference area which are specified in
@@ -125,7 +130,7 @@
* @param block the block area to add
*/
public void addBlock(Block block) {
- blocks.add(block);
+ addChildArea(block);
}
/**
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -113,8 +113,11 @@
try {
renderer.renderPage(page);
} catch (Exception e) {
- // use error handler to handle this FOP or IO Exception
- log.error(e);
+ //TODO use error handler to handle this FOP or IO Exception or propagate exception
+ String err = "Error while rendering page " + page.getPageNumberString();
+ log.error(err, e);
+ throw new IllegalStateException("Fatal error occurred. Cannot continue. "
+ + e.getClass().getName() + ": " + err);
}
page.clear();
} else {
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -202,6 +202,9 @@
public static final Integer LINETHROUGH_COLOR = new Integer(36);
private static final Map TRAIT_INFO = new HashMap();
+
+ /** The list of simple traits in order to avoid iterators */
+ public static final Object[] TRAIT_LIST;
private static class TraitInfo {
private String name;
@@ -232,19 +235,19 @@
new TraitInfo("font", FontTriplet.class));
TRAIT_INFO.put(FONT_SIZE,
new TraitInfo("font-size", Integer.class));
- TRAIT_INFO.put(COLOR, new TraitInfo("color", String.class));
+ TRAIT_INFO.put(COLOR, new TraitInfo("color", Color.class));
TRAIT_INFO.put(PROD_ID, new TraitInfo("prod-id", String.class));
TRAIT_INFO.put(BACKGROUND,
new TraitInfo("background", Background.class));
TRAIT_INFO.put(UNDERLINE,
new TraitInfo("underline-score", Boolean.class));
- TRAIT_INFO.put(UNDERLINE_COLOR, new TraitInfo("underline-score-color", String.class));
+ TRAIT_INFO.put(UNDERLINE_COLOR, new TraitInfo("underline-score-color", Color.class));
TRAIT_INFO.put(OVERLINE,
new TraitInfo("overline-score", Boolean.class));
- TRAIT_INFO.put(OVERLINE_COLOR, new TraitInfo("overline-score-color", String.class));
+ TRAIT_INFO.put(OVERLINE_COLOR, new TraitInfo("overline-score-color", Color.class));
TRAIT_INFO.put(LINETHROUGH,
new TraitInfo("through-score", Boolean.class));
- TRAIT_INFO.put(LINETHROUGH_COLOR, new TraitInfo("through-score-color", String.class));
+ TRAIT_INFO.put(LINETHROUGH_COLOR, new TraitInfo("through-score-color", Color.class));
TRAIT_INFO.put(BLINK,
new TraitInfo("blink", Boolean.class));
TRAIT_INFO.put(OFFSET, new TraitInfo("offset", Integer.class));
@@ -285,6 +288,8 @@
new TraitInfo("is-reference-area", Boolean.class));
TRAIT_INFO.put(IS_VIEWPORT_AREA,
new TraitInfo("is-viewport-area", Boolean.class));
+
+ TRAIT_LIST = TRAIT_INFO.keySet().toArray();
}
/**
@@ -326,7 +331,7 @@
* @param oTraitCode the trait code to lookup
* @return the class type for the trait
*/
- private static Class getTraitClass(Object oTraitCode) {
+ public static Class getTraitClass(Object oTraitCode) {
TraitInfo ti = (TraitInfo) TRAIT_INFO.get(oTraitCode);
return (ti != null ? ti.getClazz() : null);
}
@@ -496,6 +501,51 @@
}
}
+ /** @see java.lang.Object#hashCode() */
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /** @see java.lang.Object#equals(java.lang.Object) */
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ } else if (obj == this) {
+ return true;
+ } else {
+ if (obj instanceof ColorType) {
+ ColorType other = (ColorType)obj;
+ return getRed() == other.getRed()
+ && getGreen() == other.getGreen()
+ && getBlue() == other.getBlue()
+ && getAlpha() == other.getAlpha();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a Color represtation of a string of the format "#RRGGBB".
+ * @param s the string
+ * @return the Color value
+ */
+ public static Color valueOf(String s) {
+ if (s == null) {
+ return null;
+ }
+ if (!s.startsWith("#")) {
+ throw new IllegalArgumentException("Color must start with '#'");
+ }
+ int r = Integer.parseInt(s.substring(1, 3), 16);
+ int g = Integer.parseInt(s.substring(3, 5), 16);
+ int b = Integer.parseInt(s.substring(5, 7), 16);
+ int a = 255;
+ if (s.length() > 7) {
+ a = Integer.parseInt(s.substring(7, 9), 16);
+ }
+ return new Color(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
+ }
+
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sbuf = new StringBuffer(8);
@@ -515,6 +565,13 @@
sbuf.append('0');
}
sbuf.append(s);
+ if (alpha != 1) {
+ s = Integer.toHexString((int)(alpha * 255.0));
+ if (s.length() == 1) {
+ sbuf.append('0');
+ }
+ sbuf.append(s);
+ }
return sbuf.toString();
}
@@ -617,6 +674,14 @@
}
/**
+ * Sets the image repetition behaviour for images.
+ * @param repeat The image repetition behaviour to set
+ */
+ public void setRepeat(String repeat) {
+ setRepeat(getConstantForRepeat(repeat));
+ }
+
+ /**
* Sets the URL to the background image.
* @param url The URL to set
*/
@@ -640,7 +705,31 @@
this.vertical = vertical;
}
- /**
+ private String getRepeatString() {
+ switch (getRepeat()) {
+ case Constants.EN_REPEAT: return "repeat";
+ case Constants.EN_REPEATX: return "repeat-x";
+ case Constants.EN_REPEATY: return "repeat-y";
+ case Constants.EN_NOREPEAT: return "no-repeat";
+ default: throw new IllegalStateException("Illegal repeat style: " + getRepeat());
+ }
+ }
+
+ private static int getConstantForRepeat(String repeat) {
+ if ("repeat".equalsIgnoreCase(repeat)) {
+ return Constants.EN_REPEAT;
+ } else if ("repeat-x".equalsIgnoreCase(repeat)) {
+ return Constants.EN_REPEATX;
+ } else if ("repeat-y".equalsIgnoreCase(repeat)) {
+ return Constants.EN_REPEATY;
+ } else if ("no-repeat".equalsIgnoreCase(repeat)) {
+ return Constants.EN_NOREPEAT;
+ } else {
+ throw new IllegalStateException("Illegal repeat style: " + repeat);
+ }
+ }
+
+ /**
* Return the string for debugging.
* @see java.lang.Object#toString()
*/
@@ -649,23 +738,7 @@
sb.append("color=").append(color);
if (url != null) {
sb.append(",url=").append(url);
- sb.append(",repeat=");
- switch (repeat) {
- case Constants.EN_REPEAT:
- sb.append("repeat");
- break;
- case Constants.EN_REPEATX:
- sb.append("repeat-x");
- break;
- case Constants.EN_REPEATY:
- sb.append("repeat-y");
- break;
- case Constants.EN_NOREPEAT:
- sb.append("no-repeat");
- break;
- default:
- sb.append("ILLEGAL!");
- }
+ sb.append(",repeat=").append(getRepeatString());
sb.append(",horiz=").append(horiz);
sb.append(",vertical=").append(vertical);
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/ForeignObject.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/ForeignObject.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/ForeignObject.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/ForeignObject.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 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.
@@ -29,6 +29,7 @@
* This holds an xml document and the associated namespace.
*/
public class ForeignObject extends Area {
+
private Document doc;
private String namespace;
@@ -43,6 +44,23 @@
namespace = ns;
}
+ /**
+ * Create a new empty foreign object for which the DOM Document will be set later.
+ *
+ * @param ns the namespace of the document
+ */
+ public ForeignObject(String ns) {
+ namespace = ns;
+ }
+
+ /**
+ * Sets the DOM document for this foreign object.
+ * @param document the DOM document
+ */
+ public void setDocument(Document document) {
+ this.doc = document;
+ }
+
/**
* Get the document for this foreign object.
*
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
@@ -33,11 +33,9 @@
*/
protected List inlines = new ArrayList();
- /**
- * An inline parent is a reference area somay have clipping
- */
- protected boolean clip = false;
-
+ /** Controls whether the IPD is automatically adjusted based on the area's children. */
+ protected transient boolean autoSize;
+
/**
* Create a new inline parent to add areas to.
*/
@@ -50,9 +48,14 @@
* @param childArea the child area to add
*/
public void addChildArea(Area childArea) {
+ if (inlines.size() == 0) {
+ autoSize = (getIPD() == 0);
+ }
if (childArea instanceof InlineArea) {
inlines.add(childArea);
- increaseIPD(((InlineArea) childArea).getAllocIPD());
+ if (autoSize) {
+ increaseIPD(((InlineArea) childArea).getAllocIPD());
+ }
}
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Leader.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Leader.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Leader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Leader.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 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.
@@ -50,6 +50,28 @@
}
/**
+ * Set the rule style of this leader area.
+ * @param style the rule style for the leader area (XSL enum values)
+ */
+ public void setRuleStyle(String style) {
+ if ("dotted".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_DOTTED);
+ } else if ("dashed".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_DASHED);
+ } else if ("solid".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_SOLID);
+ } else if ("double".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_DOUBLE);
+ } else if ("groove".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_GROOVE);
+ } else if ("ridge".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_RIDGE);
+ } else if ("none".equalsIgnoreCase(style)) {
+ setRuleStyle(Constants.EN_NONE);
+ }
+ }
+
+ /**
* Set the rule thickness of the rule in miilipoints.
*
* @param rt the rule thickness in millipoints
@@ -67,6 +89,21 @@
return ruleStyle;
}
+ /** @return the rule style as string */
+ public String getRuleStyleAsString() {
+ switch (getRuleStyle()) {
+ case Constants.EN_DOTTED: return "dotted";
+ case Constants.EN_DASHED: return "dashed";
+ case Constants.EN_SOLID: return "solid";
+ case Constants.EN_DOUBLE: return "double";
+ case Constants.EN_GROOVE: return "groove";
+ case Constants.EN_RIDGE: return "ridge";
+ case Constants.EN_NONE: return "none";
+ default:
+ throw new IllegalStateException("Unsupported rule style: " + getRuleStyle());
+ }
+ }
+
/**
* Get the rule thickness of the rule in miilipoints.
*
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Viewport.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Viewport.java?rev=369753&r1=369752&r2=369753&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Viewport.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Viewport.java Tue Jan 17 03:07:10 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 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.
@@ -35,7 +35,7 @@
private Area content;
// clipping for the viewport
private boolean clip = false;
- // position of the cild area relative to this area
+ // position of the child area relative to this area
private Rectangle2D contentPosition;
/**
@@ -83,6 +83,14 @@
return contentPosition;
}
+ /**
+ * Sets the content area.
+ * @param content the content area
+ */
+ public void setContent(Area content) {
+ this.content = content;
+ }
+
/**
* Get the content area for this viewport.
*
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org