aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Pepping <spepping@apache.org>2004-08-01 19:48:51 +0000
committerSimon Pepping <spepping@apache.org>2004-08-01 19:48:51 +0000
commitdec1e96ca07e2a9ae6ef626eed7d89d3a0ebed9b (patch)
treea76bbf27c4ffb041ab1cca25109da3564411d4f3 /src
parent7e4a5bba40e1ffb155d6192ec3e5edbd966716e6 (diff)
downloadxmlgraphics-fop-dec1e96ca07e2a9ae6ef626eed7d89d3a0ebed9b.tar.gz
xmlgraphics-fop-dec1e96ca07e2a9ae6ef626eed7d89d3a0ebed9b.zip
First committed version
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197850 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/DnI/BookMaker.java334
-rw-r--r--src/documentation/content/xdocs/DnI/Makefile126
-rw-r--r--src/documentation/content/xdocs/DnI/README77
-rw-r--r--src/documentation/content/xdocs/DnI/addareas.xml971
-rw-r--r--src/documentation/content/xdocs/DnI/areatree.xml420
-rw-r--r--src/documentation/content/xdocs/DnI/book.xml122
-rw-r--r--src/documentation/content/xdocs/DnI/configuration.xml109
-rw-r--r--src/documentation/content/xdocs/DnI/cust-fo-docbook.xsl534
-rw-r--r--src/documentation/content/xdocs/DnI/cust-html-docbook.xsl37
-rw-r--r--src/documentation/content/xdocs/DnI/cust-xhtml-docbook.xsl40
-rw-r--r--src/documentation/content/xdocs/DnI/fonts.xml297
-rw-r--r--src/documentation/content/xdocs/DnI/foptrees.xml1065
-rw-r--r--src/documentation/content/xdocs/DnI/fotree.xml196
-rw-r--r--src/documentation/content/xdocs/DnI/getnextbreakposs.xml1227
-rw-r--r--src/documentation/content/xdocs/DnI/overview.xml152
-rw-r--r--src/documentation/content/xdocs/DnI/preparation.xml470
-rw-r--r--src/documentation/content/xdocs/DnI/properties.xml2455
-rw-r--r--src/documentation/content/xdocs/DnI/rendering.xml90
18 files changed, 8722 insertions, 0 deletions
diff --git a/src/documentation/content/xdocs/DnI/BookMaker.java b/src/documentation/content/xdocs/DnI/BookMaker.java
new file mode 100644
index 000000000..91f730711
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/BookMaker.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 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$ */
+
+// Derived from examples/embedding/java/embedding/ExampleXML2PDF.java
+// in FOP-0.20.5
+
+//Java
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import java.util.Vector;
+
+//JAXP
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.Source;
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXResult;
+
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.ParserConfigurationException;
+
+// SAX
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ErrorHandler;
+
+// XML Commons
+import org.apache.xml.resolver.tools.CatalogResolver;
+
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Parser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.ParseException;
+
+//Avalon
+import org.apache.avalon.framework.ExceptionUtil;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+
+//FOP
+import org.apache.fop.apps.Driver;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.messaging.MessageHandler;
+
+/**
+ * This class converts an XML file to PDF using
+ * JAXP (XSLT) and FOP (XSL:FO).
+ */
+public class BookMaker implements ErrorHandler {
+
+ private Logger logger;
+
+ private File xmlFile, xsltFile, outFile, pdfFile;
+ private boolean useCatalog;
+ private Vector xsltParams = null;
+
+ public BookMaker() {
+ //Setup logger
+ logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
+ }
+
+ /**
+ * org.xml.sax.ErrorHandler#warning
+ **/
+ public void warning(SAXParseException e) {
+ logger.warn(e.toString());
+ }
+
+ /**
+ * org.xml.sax.ErrorHandler#error
+ **/
+ public void error(SAXParseException e) {
+ logger.error(e.toString());
+ }
+
+ /**
+ * org.xml.sax.ErrorHandler#fatalError
+ **/
+ public void fatalError(SAXParseException e) throws SAXException {
+ logger.error(e.toString());
+ throw e;
+ }
+
+ public void makeBook()
+ throws IOException, FOPException, TransformerException,
+ FactoryConfigurationError,
+ ParserConfigurationException, SAXException {
+
+ OutputStream out = null;
+
+ try {
+
+ Source xmlSource, xsltSource;
+ Result result;
+ CatalogResolver resolver = null;
+
+ // Setup entity and URI resolver
+ if (useCatalog) {
+ resolver = new CatalogResolver();
+ logger.info("Using " + resolver.getClass().getName()
+ + " as entity/URI resolver");
+ }
+
+ //Setup XSLT transformer
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ if (useCatalog) {
+ tFactory.setURIResolver(resolver);
+ }
+
+ //Setup input and xslt sources
+ if (useCatalog) {
+
+ SAXParser parser;
+ XMLReader xmlReader;
+ FileInputStream fis;
+ InputSource is;
+
+ // throws FactoryConfigurationError
+ SAXParserFactory sFactory = SAXParserFactory.newInstance();
+ sFactory.setNamespaceAware(true);
+
+ // Setup input source
+ // throws ParserConfigurationException
+ parser = sFactory.newSAXParser();
+ // throws SAXException
+ xmlReader = parser.getXMLReader();
+ logger.info("Using " + xmlReader.getClass().getName()
+ + " as SAX parser");
+ xmlReader.setErrorHandler(this);
+ xmlReader.setEntityResolver(resolver);
+
+ // Setup SAX source
+ fis = new FileInputStream(xmlFile);
+ is = new InputSource(fis);
+ xmlSource = new SAXSource(xmlReader, is);
+
+ // Setup xslt source
+ // throws ParserConfigurationException
+ parser = sFactory.newSAXParser();
+ // throws SAXException
+ xmlReader = parser.getXMLReader();
+ logger.info("Using " + xmlReader.getClass().getName()
+ + " as SAX parser");
+ xmlReader.setErrorHandler(this);
+ xmlReader.setEntityResolver(resolver);
+
+ // Setup SAX source
+ fis = new FileInputStream(xsltFile);
+ is = new InputSource(fis);
+ xsltSource = new SAXSource(xmlReader, is);
+
+ } else {
+ xmlSource = new StreamSource(xmlFile);
+ xsltSource = new StreamSource(xsltFile);
+ }
+
+ // Setup output result
+ if (pdfFile != null) {
+ //Setup FOP
+ MessageHandler.setScreenLogger(logger);
+ Driver driver = new Driver();
+ driver.setLogger(logger);
+ driver.setRenderer(Driver.RENDER_PDF);
+ out = new FileOutputStream(pdfFile);
+ driver.setOutputStream(out);
+ //Resulting SAX events (the generated FO)
+ // must be piped through to FOP
+ result = new SAXResult(driver.getContentHandler());
+ } else {
+ out = new FileOutputStream(outFile);
+ result = new StreamResult(out);
+ }
+
+ // Setup the transformer
+ Transformer transformer
+ = tFactory.newTransformer(xsltSource);
+ logger.info("Using " + transformer.getClass().getName()
+ + " as TrAX transformer");
+
+ // Set the value of parameters, if any, defined for stylesheet
+ if (xsltParams != null) {
+ for (int i = 0; i < xsltParams.size(); i += 2) {
+ transformer.setParameter
+ ((String) xsltParams.elementAt(i),
+ (String) xsltParams.elementAt(i + 1));
+ }
+ }
+
+ //Start XSLT transformation and FOP processing
+ transformer.transform(xmlSource, result);
+
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ private static Options createOptions() {
+
+ Options options = new Options();
+ OptionGroup og;
+ Option o;
+
+ o = new Option("h", "help", false, "Print help");
+ options.addOption(o);
+
+ o = new Option("c", "useCatalog", false, "Use catalog");
+ options.addOption(o);
+
+ o = new Option("xml", "xmlFile", true, "XML input file");
+ o.setArgName("file");
+ options.addOption(o);
+
+ o = new Option("xsl", "xslFile", true, "XSLT stylesheet");
+ o.setArgName("file");
+ options.addOption(o);
+
+ // mutually exclusive output options
+ og = new OptionGroup();
+ o = new Option("out", "outFile", true, "(X)HTML/FO output file");
+ o.setArgName("file");
+ og.addOption(o);
+
+ o = new Option("pdf", "pdfFile", true, "PDF output file");
+ o.setArgName("file");
+ og.addOption(o);
+
+ options.addOptionGroup(og);
+
+ o = new Option("p", "parameter", true,
+ "Parameter for the XSLT transformation");
+ o.setArgs(2);
+ o.setArgName("name value");
+ options.addOption(o);
+
+ return options;
+ }
+
+ public static void main(String[] args) {
+
+ BookMaker app = new BookMaker();
+
+ try {
+
+ // Setup options
+ Options options = createOptions();
+
+ // Parse command line
+ // GNU parser allow multi-letter short options
+ Parser parser = new GnuParser();
+ CommandLine cl = null;
+ cl = parser.parse(options, args);
+ if (cl.hasOption("h")) {
+ // automatically generate the help statement
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("BookMaker", options);
+ System.exit(0);
+ }
+
+ //Setup input and output files and parameters
+ if (cl.hasOption("c")) {
+ app.useCatalog = true;
+ }
+ if (cl.hasOption("xml")) {
+ app.xmlFile = new File(cl.getOptionValue("xml"));
+ }
+ if (cl.hasOption("xsl")) {
+ app.xsltFile = new File(cl.getOptionValue("xsl"));
+ }
+ if (cl.hasOption("out")) {
+ app.outFile = new File(cl.getOptionValue("out"));
+ }
+ if (cl.hasOption("pdf")) {
+ app.pdfFile = new File(cl.getOptionValue("pdf"));
+ }
+ if (cl.hasOption("p")) {
+ String[] params = cl.getOptionValues("p");
+ app.xsltParams = new Vector();
+ for (int i = 0; i < params.length; ++i) {
+ app.xsltParams.addElement(params[i]);
+ }
+ }
+
+ app.logger.info("Input: XML (" + app.xmlFile + ")");
+ app.logger.info("Stylesheet: " + app.xsltFile);
+ if (app.pdfFile != null) {
+ app.logger.info("Output: PDF (" + app.pdfFile + ")");
+ } else {
+ app.logger.info("Output: (X)HTML/FO (" + app.outFile + ")");
+ }
+ app.logger.info("");
+ app.logger.info("Transforming...");
+
+ app.makeBook();
+
+ app.logger.info("Transforming done");
+ } catch (Exception e) {
+ app.logger.error(ExceptionUtil.printStackTrace(e));
+ System.exit(1);
+ }
+ }
+}
diff --git a/src/documentation/content/xdocs/DnI/Makefile b/src/documentation/content/xdocs/DnI/Makefile
new file mode 100644
index 000000000..98014017f
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/Makefile
@@ -0,0 +1,126 @@
+# Copyright 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$
+
+BOOK=book.xml
+CHAPTERS=addareas.xml areatree.xml configuration.xml fonts.xml \
+ foptrees.xml fotree.xml getnextbreakposs.xml overview.xml \
+ preparation.xml properties.xml rendering.xml
+CUSTOM_DOCBOOK_XHTML_STYLESHEET=cust-xhtml-docbook.xsl
+CUSTOM_DOCBOOK_HTML_STYLESHEET=cust-html-docbook.xsl
+CUSTOM_DOCBOOK_FO_STYLESHEET=cust-fo-docbook.xsl
+STYLESHEETS=$(CUSTOM_DOCBOOK_XHTML_STYLESHEET) \
+ $(CUSTOM_DOCBOOK_HTML_STYLESHEET) \
+ $(CUSTOM_DOCBOOK_FO_STYLESHEET)
+BOOKMAKER=BookMaker.java
+
+# destinations
+BUILD_DIR=../../../../../build/
+BOOKMAKERCLASSPATH=$(BUILD_DIR)/classes
+BOOKMAKER_CLASS=$(BOOKMAKERCLASSPATH)/BookMaker.class
+DNI_BUILD_DIR=$(BUILD_DIR)/site/DnI
+XHTML_DIR=$(DNI_BUILD_DIR)/xhtml
+HTML_DIR=$(DNI_BUILD_DIR)/html
+PDF_DIR=$(DNI_BUILD_DIR)
+
+JAVACLASSES=/usr/local/javaclasses
+FOPCLASSPATH=$(JAVACLASSES)/fop-0.20.5.jar
+AVALONCLASSPATH=$(JAVACLASSES)/avalon-framework-cvs-20020806.jar
+SAXONCLASSPATH=$(JAVACLASSES)/saxon.jar
+RESOLVERCLASSPATH=$(JAVACLASSES)/endorsed/resolver-xml-commons.jar
+XERCESCLASSPATH=$(JAVACLASSES)/endorsed/xml-apis.jar:$(JAVACLASSES)/endorsed/xercesImpl.jar
+CLICLASSPATH=$(JAVACLASSES)/commons-cli-1.0.jar
+
+all: xhtml html pdf
+
+xhtml: $(XHTML_DIR)/book-xhtml.xml
+html: $(HTML_DIR)/book.html
+fo: $(PDF_DIR)/book.fo
+pdf: $(PDF_DIR)/book.pdf
+
+$(XHTML_DIR)/book-xhtml.xml: $(BOOK) $(CHAPTERS) $(CUSTOM_DOCBOOK_XHTML_STYLESHEET) $(BOOKMAKER_CLASS)
+ [ -d $(XHTML_DIR) ] || mkdir -p $(XHTML_DIR)
+ java $(JAVAFLAGS) \
+ -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) \
+ BookMaker $(PROGOPTS) --parameter base.dir $(XHTML_DIR)/ -xml $< -xsl $(CUSTOM_DOCBOOK_XHTML_STYLESHEET) -out $@
+
+$(HTML_DIR)/book.html: $(BOOK) $(CHAPTERS) $(CUSTOM_DOCBOOK_HTML_STYLESHEET) $(BOOKMAKER_CLASS)
+ [ -d $(HTML_DIR) ] || mkdir -p $(HTML_DIR)
+ java $(JAVAFLAGS) \
+ -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) \
+ BookMaker $(PROGOPTS) --parameter base.dir $(HTML_DIR)/ -xml $< -xsl $(CUSTOM_DOCBOOK_HTML_STYLESHEET) -out $@
+
+$(PDF_DIR)/book.fo: $(BOOK) $(CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ [ -d $(PDF_DIR) ] || mkdir -p $(PDF_DIR)
+ java $(JAVAFLAGS) \
+ -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) \
+ BookMaker $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -out $@
+
+$(PDF_DIR)/book.pdf: $(BOOK) $(CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ [ -d $(PDF_DIR) ] || mkdir -p $(PDF_DIR)
+ java $(JAVAFLAGS) \
+ -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) \
+ BookMaker $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -pdf $@
+
+$(BOOKMAKERCLASSPATH)/%.class: %.java
+ [ -d $(BOOKMAKERCLASSPATH) ] || mkdir -p $(BOOKMAKERCLASSPATH)
+ javac -classpath $(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(CLASSPATH) \
+ -d $(BOOKMAKERCLASSPATH) $<
+
+############################ distribution file #########################
+
+CURRENT_DIR=documentation
+
+zip: documentation.zip
+
+documentation.zip: $(BOOK) $(CHAPTERS) $(STYLESHEETS) $(BOOKMAKER) Makefile README
+ -rm -f $@
+ cd .. && zip $(CURRENT_DIR)/$@ ${^:%=$(CURRENT_DIR)/%}
+
+############################ test section ###############################
+
+TEST=test.xml
+TEST_CHAPTERS=getnextbreakposs.xml overview.xml
+
+test-saxon.html: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_HTML_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) --parameter base.dir $(HTML_DIR)/ -xml $< -xsl $(CUSTOM_DOCBOOK_HTML_STYLESHEET) -out $@
+
+test-saxon.xhtml: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_XHTML_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) --parameter base.dir $(XHTML_DIR)/ -xml $< -xsl $(CUSTOM_DOCBOOK_XHTML_STYLESHEET) -out $@
+
+test-saxon.fo: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -out $@
+
+test-saxon.pdf: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -pdf $@
+
+test-saxon-stf.pdf: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(XERCESCLASSPATH):$(SAXONCLASSPATH):$(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) XML2PDF_STF $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -pdf $@
+
+test-xalan.html: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_HTML_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) --parameter base.dir $(HTML_DIR)/ -xml $< -xsl $(CUSTOM_DOCBOOK_HTML_STYLESHEET) -out $@
+
+test-xalan.xhtml: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_XHTML_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) --parameter base.dir $(XHTML_DIR)/ -xml $< -xsl $(CUSTOM_DOCBOOK_XHTML_STYLESHEET) -out $@
+
+test-xalan.fo: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -out $@
+
+test-xalan.pdf: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) BookMaker $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -pdf $@
+
+test-xalan-stf.pdf: $(TEST) $(TEST_CHAPTERS) $(CUSTOM_DOCBOOK_FO_STYLESHEET) $(BOOKMAKER_CLASS)
+ java $(JAVAFLAGS) -classpath $(FOPCLASSPATH):$(AVALONCLASSPATH):$(RESOLVERCLASSPATH):$(CLICLASSPATH):$(BOOKMAKERCLASSPATH):$(CLASSPATH) XML2PDF_STF $(PROGOPTS) -xml $< -xsl $(CUSTOM_DOCBOOK_FO_STYLESHEET) -pdf $@
+
diff --git a/src/documentation/content/xdocs/DnI/README b/src/documentation/content/xdocs/DnI/README
new file mode 100644
index 000000000..9138da809
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/README
@@ -0,0 +1,77 @@
+Readme for `FOP's design and implementation'
+
+This directory contains the documentation entitled `FOP's design and
+implementation'.
+
+The book is structured according to the Docbook XML DTD version 4.2,
+top-level element book.
+
+The top level file is book.xml. It calls in the various chapter files.
+
+The book can be converted to XHTML, HTML and FO using the Docbook XSL
+stylesheets. For each of these formats there are customization XSL
+stylesheets, which should be called as the main stylesheet of the
+conversion. The customization stylesheets were written against version
+1.64.1. The customization for FO is rather heavy, and may prove
+incompatible with later versions of the docbook stylesheets. Of
+course, you can always convert without the customization or with your
+own customization. The changes will only affect the layout, not the
+content of the book.
+
+The customization stylesheets for XHTML and HTML use the ability of
+the docbook stylesheets to write the resulting files in chunks. It
+makes sense to send the conversion result into a separate
+directory. If you make both conversions, you must send them to
+different directories, as they produce files of the same name. You can
+produce the result in a single file by making a small change at the
+top of the customization stylesheets: import the stylesheet
+docbook.xsl instead of chunk.xsl.
+
+For the XHTML and HTML conversions I have obtained the best conversion
+results using Saxon. I have used FOP-0.20.5 for FO Processor.
+
+The top-level file assumes that the docbook DTD files are located in
+`http://www.oasis-open.org/docbook/xml/4.2/'. The customization
+stylesheets assume that the docbook stylesheets are located in
+`http://cvs.sourceforge.net/viewcvs.py/*checkout*/docbook/xsl/'. I am
+not quite sure if the latter URL is correct. If you want to use local
+files from your XML installation, you must change these paths at the
+top of the top-level XML file and of each customization stylesheet.
+Alternatively, you can use catalog entries to map the Public ID for
+the Docbook DTD and the system id of the docbook XSL stylesheets to
+your local paths.
+
+You can use the included java class BookMaker to generate the various
+forms of the documentation. Note that it requires the Jakarta Commons
+CLI package. Call BookMaker with the option '--help' to get a short
+overview of its usage. Use the included Makefile, or learn from it how
+the BookMaker class can be called. If you use the Makefile, you must
+edit the class paths to reflect your java setup. Set the environment
+variable PROGOPTS=--useCatalog if you want to use a catalog. I have
+better results with Xerces and the catalog resolver; therefore Xerces
+is placed before Saxon in the class paths.
+
+If you do not use a catalog, you can also use Saxon and FOP from the
+command line. The following are typical invocations. Here the
+classpaths have obvious meanings. JAVAFLAGS are any other options for
+java, possibly none.
+
+java $JAVAFLAGS -cp "$SAXONCLASSPATH:$CLASSPATH" \
+ com.icl.saxon.StyleSheet \
+ -o ../documentation-xhtml/book-xhtml.xml \
+ book.xml cust-xhtml-docbook.xsl
+
+java $JAVAFLAGS -cp "$SAXONCLASSPATH:$CLASSPATH" \
+ com.icl.saxon.StyleSheet \
+ -o ../documentation-html/book.html \
+ book.xml cust-html-docbook.xsl
+
+java $JAVAFLAGS \
+ -cp $SAXONCLASSPATH:$FOPCLASSPATH:$AVALONCLASSPATH:$CLASSPATH \
+ org.apache.fop.apps.Fop \
+ -xml book.xml -xsl cust-html-docbook.xsl -pdf book.pdf
+
+I will try to construct an ant build file and an XML catalog which
+make conversion with your own XML and Java system easier.
+
+$Id$
diff --git a/src/documentation/content/xdocs/DnI/addareas.xml b/src/documentation/content/xdocs/DnI/addareas.xml
new file mode 100644
index 000000000..9ceb4ff49
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/addareas.xml
@@ -0,0 +1,971 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>Phase 2b: The <literal>addAreas</literal> call tree</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>This section presents a verbose overview of the
+<literal>addAreas</literal> call tree. The following section presents
+the Layout Managers in more detail.</para>
+
+ <itemizedlist>
+
+ <listitem>
+ <simpara>FlowLM receives from its parent LM an iterator with a
+single pagebreak. The first belongs to BlockLM1, the second belongs to
+BlockLM2. FlowLM itself holds 2 child BPs. The flow consists of two
+blocks. FlowLM sets up an iterator with its 2 BPs.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>BlockLM1 receives from its parent LM the iterator
+with those 2 BPs, of which only the first one belongs to it. Its leaf
+position is 13. BlockLM itself holds 14 child BPs, which all belong to
+a single LineLM. The block consists of 14 lines. BlockLM sets up an
+iterator corresponding to the first BP, containing the child BPs
+0–13.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>LineLM receives from its parent LM an iterator with
+those 14 BPs. The leaf positions are 3, 6, 11, 12, 13, 16, 19, 21, 23,
+24, 25, 26, 27, 28. LineLM itself holds 29 child BPs, which all belong
+to a single TextLM. LineLM maintains the position of the next BP in
+<literal>vecInlineBreaks</literal>, <literal>iStartPos</literal>.
+Initially it is set to 0. For each of its 14 BPs in the iterator,
+LineLM sets up an iterator with the child BPs in
+<literal>vecInlineBreaks</literal> from <literal>iStartPos</literal>
+up to an including the index <literal>iLeafPos</literal> to which the
+iterator BP points. Then it <literal>updates</literal> iStartPos to
+point to the next child BP. The iterators contain the child BP ranges:
+0–3, 4–6, 7–11, 12, 13, 14–16, 17–19, 20–21, 22–23, 24, 25, 26, 27,
+28.</simpara>
+
+ <screen>while (parentIter.hasNext()) {
+ LineBreakPosition lbp = (LineBreakPosition) parentIter.next();
+ ...
+ PositionIterator inlinePosIter =
+ new BreakPossPosIter(vecInlineBreaks, iStartPos,
+ lbp.getLeafPos() + 1);
+ iStartPos = lbp.getLeafPos() + 1;
+ ...
+ while ((childLM = inlinePosIter.getNextChildLM()) != null) {
+ childLM.addAreas(inlinePosIter, lc);
+ ...
+ }
+ ...
+}
+</screen>
+ </listitem>
+
+ <listitem>
+<simpara>TextLM receives from its parent LM an iterator with the BPs
+0–3. The leaf positions are 0, 1, 2, 3. It has itself 47 items in
+<literal>vecAreaInfo</literal>. It iterates over the 4 corresponding
+AIs, records the start of the first one, counts the word spaces, and
+records the end of the last one. This line contains the characters
+from 0 up to 13 and has no word spaces.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>TextLM receives from its parent LM an iterator with
+the BPs 4–6. The leaf positions are 5, 7, 8. It iterates over the
+three corresponding AIs. This line contains the characters from 13 up
+to 26 and has one word space. Note that the AIs 4 and 6 remain unused
+because they do not have a corresponding BP. These AIs represent areas
+that were too long, and over which the LM backed up.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>TextLM receives from its parent LM an iterator with
+the BPs 7–11. The leaf positions are 11, 12, 13, 14, 15. It iterates
+over the five corresponding AIs. This line contains the characters
+from 26 up to 40 and has no word spaces. Note that the AIs 9 and 10
+remain unused because they do not have a corresponding BP.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>TextLM receives from its parent LM an iterator with
+the single BP 12. The leaf position is 16. This line contains the
+characters from 40 up to 42 and has no word spaces.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>TextLM receives from its parent LM an iterator with
+the single BP 13. The leaf position is 18. This line contains the
+characters from 43 up to 60 and has no word spaces. Note that the AI
+17 remains unused because it does not have a corresponding BP. Note
+also that character 42 has been dropped, because it would be a leading
+space.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>etc. until all 14 line areas are done. LineLM
+returns.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>The second BP in the iterator from FlowLM belongs to
+BlockLM2. The loop <literal>while (parentIter.hasNext())</literal>
+ends because the LM of the next object is different from the current
+LM (<literal>BreakPossPosIter.checkNext()</literal>), and BlockLM1
+returns. FlowLM's loop <literal>while ((childLM =
+breakPosIter.getNextChildLM()) != null)</literal> then passes the
+iterator to BlockLM2.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>BlockLM2 receives from its parent LM the iterator with those 2
+BPs. The cursor is at one, because BlockLM1 has used the first object.
+Only the second BP belongs to BlockLM2. Its leaf position is
+0. BlockLM itself holds 1 child BP, belonging to a LineLM. The block
+consists of a single line. BlockLM sets up an iterator corresponding
+to the second BP, containing a single child BP.</simpara>
+ </listitem>
+
+ <listitem>
+<simpara>LineLM receives from its parent LM an iterator with that BP.
+The leaf position is 1. LineLM itself holds 2 child BPs, one belonging
+to a TextLM, the other to <literal>AddLMVisitor$2</literal>. LineLM
+sets up an iterator corresponding to the BP, containing its two child
+BPs.</simpara>
+ </listitem>
+
+ <listitem>
+<simpara>TextLM receives from its parent LM an iterator with the BPs 0
+and 1, of which only the first belongs to it. Its leaf position is 0.
+It iterates over the corresponding AI. This text area contains the
+characters from 0 up to 1, i.e. <literal>" "</literal>, and has one
+word space. This converted to a space area.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara><literal>AddLMVisitor$2</literal> receives from its
+parent LM an iterator with the BPs 0 and 1. The cursor is at one,
+because TextLM has used the first object. Only the second BP belongs
+to <literal>AddLMVisitor$2</literal>. Its leaf position is
+0.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>This completes the line. LineLM returns.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>BlockLM2 returns.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>FlowLM returns.</simpara>
+ </listitem>
+ </itemizedlist>
+
+ </section>
+
+ <section>
+ <title>Detailed overviews</title>
+
+ <section>
+ <title>PageLM</title>
+
+<screen>
+ bbp = {
+ breakps: instance of org.apache.fop.layoutmgr.BreakPoss(id=1167)
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.FlowLayoutManager(id=1169)
+}
+
+ bbp.breakps.position = {
+ iLeafPos: 1
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.FlowLayoutManager(id=1169)
+}
+
+ list = "[org.apache.fop.layoutmgr.BreakPoss@1aa2c23]"
+
+ list.get(0).position = {
+ iLeafPos: 1
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.FlowLayoutManager(id=1169)
+}
+
+ list.get(0).position.layoutManager = "org.apache.fop.layoutmgr.FlowLayoutManager@6963d0"
+</screen>
+ </section>
+
+ <section>
+ <title>FlowLM</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.FlowLayoutManager@6963d0"
+
+ lfp = {
+ iLeafPos: 1
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.FlowLayoutManager(id=1169)
+}
+
+ iStartPos = 0
+
+ blockBreaks = "[org.apache.fop.layoutmgr.BreakPoss@111bfbc, org.apache.fop.layoutmgr.BreakPoss@4310d0]"
+
+ blockBreaks.get(iStartPos).position = {
+ iLeafPos: 13
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.BlockLayoutManager(id=1183)
+}
+
+ blockBreaks.get(iStartPos).position.layoutManager = "org.apache.fop.layoutmgr.BlockLayoutManager@19e09a4"
+
+ blockBreaks.get(iStartPos+1).position = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.BlockLayoutManager(id=1186)
+}
+
+ blockBreaks.get(iStartPos+1).position.layoutManager = "org.apache.fop.layoutmgr.BlockLayoutManager@144b18f"
+</screen>
+ </section>
+
+ <section>
+ <title>BlockLM1</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.BlockLayoutManager@19e09a4"
+
+ lfp = {
+ iLeafPos: 13
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.BlockLayoutManager(id=1183)
+}
+
+ iStartPos = 0
+
+ childBreaks = "[
+org.apache.fop.layoutmgr.BreakPoss@2b249,
+org.apache.fop.layoutmgr.BreakPoss@106daba,
+org.apache.fop.layoutmgr.BreakPoss@1021f34,
+org.apache.fop.layoutmgr.BreakPoss@4eb043,
+org.apache.fop.layoutmgr.BreakPoss@163956,
+org.apache.fop.layoutmgr.BreakPoss@10e434d,
+org.apache.fop.layoutmgr.BreakPoss@16477d9,
+org.apache.fop.layoutmgr.BreakPoss@f864fe,
+org.apache.fop.layoutmgr.BreakPoss@1ae9aaa,
+org.apache.fop.layoutmgr.BreakPoss@2c17f7,
+org.apache.fop.layoutmgr.BreakPoss@d9896e,
+org.apache.fop.layoutmgr.BreakPoss@1cda59b,
+org.apache.fop.layoutmgr.BreakPoss@33788d,
+org.apache.fop.layoutmgr.BreakPoss@12fb0af
+]"
+
+ childBreaks.get(0).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 3
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(0).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(1).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 6
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(1).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(2).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 11
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(2).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(3).position = {
+ dAdjust: 7.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 12
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(3).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(4).position = {
+ dAdjust: 0.0
+ ipdAdjust: -1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 13
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(4).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(5).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 16
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(5).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(6).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 19
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(6).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(7).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 21
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(7).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(8).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 23
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(8).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(9).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 24
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(9).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(10).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 25
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(10).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(11).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 26
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(11).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(12).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 27
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(12).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ childBreaks.get(13).position = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 28
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ childBreaks.get(13).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+</screen>
+ </section>
+
+ <section>
+ <title>LineLM</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.LineLayoutManager@c06258"
+
+ lbp = {
+ dAdjust: 0.0
+ ipdAdjust: 1.0
+ startIndent: 0
+ lineHeight: 19200
+ baseline: 17000
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 3
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1199)
+}
+
+ iStartPos = 0
+
+ vecInlineBreaks = "[
+org.apache.fop.layoutmgr.BreakPoss@17e4dee,
+org.apache.fop.layoutmgr.BreakPoss@12e7c6a,
+org.apache.fop.layoutmgr.BreakPoss@ea5461,
+org.apache.fop.layoutmgr.BreakPoss@49cf9f,
+org.apache.fop.layoutmgr.BreakPoss@1de0b5e,
+org.apache.fop.layoutmgr.BreakPoss@bc5596,
+org.apache.fop.layoutmgr.BreakPoss@970c0e,
+org.apache.fop.layoutmgr.BreakPoss@987197,
+org.apache.fop.layoutmgr.BreakPoss@497904,
+org.apache.fop.layoutmgr.BreakPoss@1a7f9dc,
+org.apache.fop.layoutmgr.BreakPoss@104e28b,
+org.apache.fop.layoutmgr.BreakPoss@1b54362,
+org.apache.fop.layoutmgr.BreakPoss@15b0e2c,
+org.apache.fop.layoutmgr.BreakPoss@ff9053,
+org.apache.fop.layoutmgr.BreakPoss@5c7734,
+org.apache.fop.layoutmgr.BreakPoss@96212a,
+org.apache.fop.layoutmgr.BreakPoss@5b675e,
+org.apache.fop.layoutmgr.BreakPoss@df83e5,
+org.apache.fop.layoutmgr.BreakPoss@4c6320,
+org.apache.fop.layoutmgr.BreakPoss@ffd135,
+org.apache.fop.layoutmgr.BreakPoss@1000bcf,
+org.apache.fop.layoutmgr.BreakPoss@754fc,
+org.apache.fop.layoutmgr.BreakPoss@15c998a,
+org.apache.fop.layoutmgr.BreakPoss@6458a6,
+org.apache.fop.layoutmgr.BreakPoss@1f82ab4,
+org.apache.fop.layoutmgr.BreakPoss@1bb9696,
+org.apache.fop.layoutmgr.BreakPoss@9b6220,
+org.apache.fop.layoutmgr.BreakPoss@1474e45,
+org.apache.fop.layoutmgr.BreakPoss@63a721
+]"
+
+ vecInlineBreaks.get(0).position = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(0).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(1).position = {
+ iLeafPos: 1
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(1).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(2).position = {
+ iLeafPos: 2
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(2).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(3).position = {
+ iLeafPos: 3
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(3).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(4).position = {
+ iLeafPos: 5
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(4).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(5).position = {
+ iLeafPos: 7
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(5).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(6).position = {
+ iLeafPos: 8
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(6).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(7).position = {
+ iLeafPos: 11
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(7).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(8).position = {
+ iLeafPos: 12
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(8).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(9).position = {
+ iLeafPos: 13
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(9).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(10).position = {
+ iLeafPos: 14
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(10).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(11).position = {
+ iLeafPos: 15
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(11).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(12).position = {
+ iLeafPos: 16
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(12).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(13).position = {
+ iLeafPos: 18
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(13).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(14).position = {
+ iLeafPos: 20
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(14).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(15).position = {
+ iLeafPos: 21
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(15).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(16).position = {
+ iLeafPos: 22
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(16).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(17).position = {
+ iLeafPos: 23
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(17).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ vecInlineBreaks.get(18).position = {
+ iLeafPos: 25
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecInlineBreaks.get(18).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+</screen>
+ </section>
+
+ <section>
+ <title>TextLM</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.TextLayoutManager@57ea52"
+
+ this.chars = {
+w, a, t, e, r, s, t, a, a, t, s, i, n, g, e, n, i, e, u, r,
+ , m, i, n, i, s, t, e, r, s, p, o, r, t, e, f, e, u, i, l, l, e,
+ , a, a, n, d, a, c, h, t, s, t, r, e, k, k, e, r, .,
+ , V, e, r, n, e, d, e, r, l, a, n, d, s, t, e,
+ , v, a, k, l, i, t, e, r, a, t, u, u, r,
+ , v, e, r, s, c, h, i, l, l, e, n, d,
+ , v, e, r, h, o, l, l, a, n, d, s, t, e,
+ , v, a, k, l, i, t, e, r, a, t, u, u, r, .,
+ , b, e, s, t, u, u, r, s, t, a, k, e, n,
+ , l, a, n, d, s, t, a, a, l,
+ , b, e, l, a, n, g, r, i, j, k, .
+}
+
+ tbpNext = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo = "[
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@107bd0d,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@12922f6,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1b66b06,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@12c9557,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@9f0d,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@ca3783,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@2a6ff,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@21d23b,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@7124af,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1f7708,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1bfbfb8,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1c3e9ba,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@125d61e,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@10c6cfc,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@c72243,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@19a8416,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@155d3a3,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1b994de,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@dc9766,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@57e787,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1217e67,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1f1bd98,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1d686c1,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@128edf2,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1dddba,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@c7e8a7,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@7b4703,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1732ed2,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1071521,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1fc3c84,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@e93999,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1c486f2,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1779885,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@be76c7,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@682406,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@115126e,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@6d2380,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@135b1f3,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@35e6e3,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@c9630a,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@185572a,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@11daa0e,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@879860,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@24de7d,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@8b058b,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@1192059,
+org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@9ac0f5
+]"
+
+ vecAreaInfo.get(0) = {
+ iStartIndex: 0
+ iBreakIndex: 2
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1304)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(1) = {
+ iStartIndex: 2
+ iBreakIndex: 5
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1308)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(2) = {
+ iStartIndex: 5
+ iBreakIndex: 11
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1310)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(3) = {
+ iStartIndex: 11
+ iBreakIndex: 13
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1312)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(4) = {
+ iStartIndex: 13
+ iBreakIndex: 15
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1314)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(5) = {
+ iStartIndex: 13
+ iBreakIndex: 20
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1316)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(6) = {
+ iStartIndex: 20
+ iBreakIndex: 42
+ iWScount: 1
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1318)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(7) = {
+ iStartIndex: 20
+ iBreakIndex: 23
+ iWScount: 1
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1320)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(8) = {
+ iStartIndex: 23
+ iBreakIndex: 26
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1322)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(9) = {
+ iStartIndex: 26
+ iBreakIndex: 30
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1324)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(10) = {
+ iStartIndex: 26
+ iBreakIndex: 42
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1326)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(11) = {
+ iStartIndex: 26
+ iBreakIndex: 29
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1328)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(12) = {
+ iStartIndex: 29
+ iBreakIndex: 30
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1330)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(13) = {
+ iStartIndex: 30
+ iBreakIndex: 33
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1332)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(14) = {
+ iStartIndex: 33
+ iBreakIndex: 35
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1334)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(15) = {
+ iStartIndex: 35
+ iBreakIndex: 40
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1336)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(16) = {
+ iStartIndex: 40
+ iBreakIndex: 42
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1338)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(17) = {
+ iStartIndex: 42
+ iBreakIndex: 60
+ iWScount: 1
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1340)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+
+ vecAreaInfo.get(18) = {
+ iStartIndex: 43
+ iBreakIndex: 60
+ iWScount: 0
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1342)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1246)
+}
+</screen>
+ </section>
+
+ <section>
+ <title>BlockLM2</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.BlockLayoutManager@144b18f"
+
+ lfp = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.BlockLayoutManager(id=1186)
+}
+
+ iStartPos = 0
+
+ childBreaks = "[org.apache.fop.layoutmgr.BreakPoss@145f939]"
+
+ childBreaks.get(0).position = {
+ dAdjust: 0.0
+ ipdAdjust: -1.0
+ startIndent: 0
+ lineHeight: 14400
+ baseline: 12750
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 1
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1377)
+}
+
+ childBreaks.get(0).position.layoutManager = "org.apache.fop.layoutmgr.LineLayoutManager@df2d38"
+</screen>
+ </section>
+
+ <section>
+ <title>LineLM</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.LineLayoutManager@df2d38"
+
+ lbp = {
+ dAdjust: 0.0
+ ipdAdjust: -1.0
+ startIndent: 0
+ lineHeight: 14400
+ baseline: 12750
+ org.apache.fop.layoutmgr.LeafPosition.iLeafPos: 1
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1377)
+}
+
+ iStartPos = 0
+
+ vecInlineBreaks = "[
+org.apache.fop.layoutmgr.BreakPoss@eb67e8,
+org.apache.fop.layoutmgr.BreakPoss@f2ea42
+]"
+
+ vecInlineBreaks.get(0).position = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1385)
+}
+
+ vecInlineBreaks.get(0).position.layoutManager = "org.apache.fop.layoutmgr.TextLayoutManager@e265d0"
+
+ vecInlineBreaks.get(1).position = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.AddLMVisitor$2(id=1389)
+}
+
+ vecInlineBreaks.get(1).position.layoutManager = "org.apache.fop.layoutmgr.AddLMVisitor$2@2f356f"
+</screen>
+ </section>
+
+ <section>
+ <title>TextLM</title>
+
+<screen>
+ this = "org.apache.fop.layoutmgr.TextLayoutManager@e265d0"
+
+ this.chars = {
+
+}
+
+ tbpNext = {
+ iLeafPos: 0
+ org.apache.fop.layoutmgr.Position.layoutManager: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1385)
+}
+
+ vecAreaInfo = "[org.apache.fop.layoutmgr.TextLayoutManager$AreaInfo@996cca]"
+
+ vecAreaInfo.get(0) = {
+ iStartIndex: 0
+ iBreakIndex: 1
+ iWScount: 1
+ ipdArea: instance of org.apache.fop.traits.MinOptMax(id=1396)
+ this$0: instance of org.apache.fop.layoutmgr.TextLayoutManager(id=1385)
+}
+</screen>
+ </section>
+
+ <section>
+ <title><literal>AddLMVisitor$2</literal></title>
+ <simpara>No data</simpara>
+ </section>
+
+ </section>
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/areatree.xml b/src/documentation/content/xdocs/DnI/areatree.xml
new file mode 100644
index 000000000..5d361e3ca
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/areatree.xml
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>Phase 2: Building the Area tree</title>
+
+ <section>
+ <title>Initiating the layout process</title>
+
+<para>In the <literal>PageSequence.end()</literal> method the
+<literal>FOTreeHandler</literal> object
+<literal>foInputHandler</literal> notifies the
+<literal>FOTreeListeners</literal> of the PageSequence-end
+event. There is only one listener, the
+<literal>FOTreeControl</literal> object
+<literal>foTreeControl</literal>. This listener asks its
+<literal>LayoutManagerLS</literal> object to format the FO subtree of
+the <literal>PageSequence</literal> FO node. This object constructs a
+<literal>PageLayoutManager</literal> for the
+<literal>PageSequence</literal> FO node, which does the work.</para>
+
+<screen>
+org.apache.fop.fo.pagination.PageSequence.end():
+this.getFOTreeControl().getFOInputHandler().endPageSequence(this):
+-> foTreeControl.getFOInputHandler().endPageSequence(this)
+-> foInputHandler.endPageSequence(this) (type FOTreeHandler):
+</screen>
+
+<para>This method only calls
+<literal>FOTreeHandler.notifyPageSequenceComplete(pageSequence)</literal>,
+which notifies the <literal>FOTreeListeners</literal> of the
+PageSequence-end event. The <literal>PageSequence</literal> object
+attaches itself to the event, from which the listeners can retrieve it
+again.</para>
+
+<para>There is only one listener. It is an
+<literal>org.apache.fop.apps.Document</literal> object. It is the same
+object as <literal>pageSequence.root.foTreeControl</literal>. Its
+method <literal>foPageSequenceComplete(event)</literal> is called,
+which is a method of the <literal>FOTreeListener</literal>
+interface. It handles an <literal>FOTreeEvent</literal> that is fired
+when a <literal>PageSequence</literal> object has been
+completed.</para>
+
+<para>The listener formats the FO subtree of the
+<literal>PageSequence</literal> FO node. It calls its layout
+strategy's method <literal>LayoutManagerLS.format(pageSeq,
+areaTree)</literal>.</para>
+
+<para>This method creates a new <literal>PageLayoutManager</literal>
+for the <literal>PageSequence</literal> FO node and calls its
+<literal>run</literal> method (could start another thread). The pages
+in this page sequence are completely layed out by the
+<literal>PageLayoutManager</literal>, in its
+<literal>doLayout</literal> method. The first step in the layout
+process is getting the page setup from the page masters. Then the FO
+tree is processed.</para>
+
+<screen>
+ [1] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:220)
+ [2] org.apache.fop.layoutmgr.PageLayoutManager.run (PageLayoutManager.java:208)
+ [3] org.apache.fop.layoutmgr.LayoutManagerLS.format (LayoutManagerLS.java:83)
+ [4] org.apache.fop.apps.Document.foPageSequenceComplete (Document.java:348)
+ [5] org.apache.fop.fo.FOTreeHandler.notifyPageSequenceComplete (FOTreeHandler.java:497)
+ [6] org.apache.fop.fo.FOTreeHandler.endPageSequence (FOTreeHandler.java:215)
+ [7] org.apache.fop.fo.pagination.PageSequence.end (PageSequence.java:350)
+ [8] org.apache.fop.fo.FOTreeBuilder.endElement (FOTreeBuilder.java:223)
+ ... parser stuff
+ [16] org.apache.xerces.parsers.AbstractSAXParser.parse (null)
+ [17] org.apache.fop.apps.Driver.render (Driver.java:622)
+ [18] org.apache.fop.apps.Driver.render (Driver.java:558)
+ [19] org.apache.fop.apps.Fop.main (Fop.java:102)
+</screen>
+
+<screen>
+main[1] dump pageLM
+ pageLM = {
+ pageNumberGenerator: instance of org.apache.fop.fo.pagination.PageNumberGenerator(id=1005)
+ pageCount: 1
+ pageNumberString: "1"
+ isFirstPage: true
+ bFirstPage: false
+ curPage: null
+ curBody: null
+ curSpan: null
+ curSpanColumns: 0
+ curFlow: null
+ flowBPD: 0
+ flowIPD: 0
+ areaTree: instance of org.apache.fop.area.AreaTree(id=1025)
+ pageSequence: instance of org.apache.fop.fo.pagination.PageSequence(id=997)
+ currentSimplePageMaster: null
+ staticContentLMs: instance of java.util.HashMap(id=1033)
+ lmls: instance of org.apache.fop.layoutmgr.LayoutManagerLS(id=1034)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.userAgent: instance of org.apache.fop.apps.FOUserAgent(id=1035)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.parentLM: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.fobj: instance of org.apache.fop.fo.pagination.PageSequence(id=997)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.foID: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.markers: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.bFinished: false
+ org.apache.fop.layoutmgr.AbstractLayoutManager.curChildLM: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.childLMiter: instance of org.apache.fop.layoutmgr.LMiter(id=1036)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.bInited: false
+}
+</screen>
+
+ <para>The above calling sequence contains two configuration
+points. FOP's area tree building process can be modified by
+registering other listeners with the FO tree handler. It can also be
+configured by giving the Document object a different layout strategy
+object. See also the <literal>AddLMVisitor</literal> class which
+controls the creation of Layout Managers.
+<warning>
+ <simpara>TO BE EXPANDED</simpara>
+ </warning></para>
+
+ </section>
+
+ <section>
+ <title>Creating the page and body areas</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>Create the layout (<literal>doLayout</literal>) <itemizedlist spacing="compact">
+ <listitem>
+ <para>First create a new Page Viewport
+(<literal>makeNewPage</literal>). <itemizedlist spacing="compact">
+ <listitem>
+ <para>First finish the current page
+(<literal>finishPage</literal>).</para>
+ </listitem>
+ <listitem>
+ <para>Then create the new page viewport
+(<literal>createPage</literal>). <itemizedlist spacing="compact">
+ <listitem>
+ <para>First get the page master
+(<literal>getSimplePageMasterToUse</literal>,
+<literal>pageSequence.getPageSequenceMaster</literal> or
+<literal>pageSequence.getSimplePageMaster</literal>).</para>
+ </listitem>
+ <listitem>
+ <para>Then get the body
+(<literal>currentSimplePageMaster.getRegion</literal>, from
+<literal>currentSimplePageMaster</literal>'s
+<literal>regions</literal> map).</para>
+ </listitem>
+ <listitem>
+ <para>Then create the page viewport
+(<literal>createPageAreas(currentSimplePageMaster)</literal>).
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>From the properties of the page
+master create the page reference rectangle, a new page, a new
+FODimension object, and a CTM object.</para>
+ </listitem>
+ <listitem>
+ <para>For each region in the page master
+(in our example we only have a body): <itemizedlist spacing="compact">
+ <listitem>
+ <para>make a region viewport
+(<literal>makeRegionViewport</literal>), which involves calculating
+the position of the region on the page, using the FODimension and CTM
+objects.
+</para>
+ </listitem>
+ <listitem>
+ <para>make the reference area
+(<literal>makeRegionBodyReferenceArea</literal>,
+<literal>makeRegionReferenceArea</literal>).</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>At this point the page viewport and its region viewports
+have been laid out.</para>
+
+ <para> <itemizedlist spacing="compact">
+ <listitem>
+ <simpara>Then create the body's main reference area
+(<literal>createBodyMainReferenceArea</literal>).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Then create a Span
+(<literal>createSpan</literal>).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>And get the flowIPD
+(curFlow.<literal>getIPD</literal>()).</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>At this point the body has a single span area with a
+single flow area without children.
+</para>
+
+ </section>
+
+ <section>
+ <title>Detailed view</title>
+
+ <para>The call stack when creating the region viewports:
+<screen>
+ [1] org.apache.fop.layoutmgr.PageLayoutManager.makeRegionViewport (PageLayoutManager.java:832)
+ [2] org.apache.fop.layoutmgr.PageLayoutManager.createPageAreas (PageLayoutManager.java:805)
+ [3] org.apache.fop.layoutmgr.PageLayoutManager.createPage (PageLayoutManager.java:748)
+ [4] org.apache.fop.layoutmgr.PageLayoutManager.makeNewPage (PageLayoutManager.java:467)
+ [5] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:220)
+</screen>
+</para>
+
+<para>At the end of <literal>createPageAreas</literal> the following
+properties of the page have been established:</para>
+
+<para>The page reference rectangle:
+<screen>
+ pageRefRect = {
+ x: 56692
+ y: 56692
+ width: 481891
+ height: 728505
+ serialVersionUID: -4345857070255674764
+}
+</screen>
+</para>
+
+<para>The page reference area:
+<screen>
+ page = {
+ regionBefore: null
+ regionStart: null
+ regionBody: instance of org.apache.fop.area.RegionViewport(id=1279)
+ regionEnd: null
+ regionAfter: null
+ unresolved: null
+}
+</screen>
+
+<screen>
+ page.regionBody = {
+ region: instance of org.apache.fop.area.BodyRegion(id=1280)
+ viewArea: instance of java.awt.Rectangle(id=1281)
+ clip: false
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+
+<screen>
+ page.regionBody.region = {
+ beforeFloat: null
+ mainReference: null
+ footnote: null
+ columnGap: 18000
+ columnCount: 1
+ refIPD: 0
+ org.apache.fop.area.RegionReference.regionClass: 2
+ org.apache.fop.area.RegionReference.ctm: instance of org.apache.fop.area.CTM(id=1282)
+ org.apache.fop.area.RegionReference.blocks: instance of java.util.ArrayList(id=1283)
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+
+<screen>
+ page.regionBody.viewArea = {
+ x: 56692
+ y: 56692
+ width: 481891
+ height: 728505
+ serialVersionUID: -4345857070255674764
+}
+</screen>
+</para>
+
+<para>The <literal>PageViewport</literal> is returned:</para>
+
+<screen>
+ curPage = {
+ page: instance of org.apache.fop.area.Page(id=1261)
+ viewArea: instance of java.awt.Rectangle(id=1289)
+ clip: false
+ pageNumber: null
+ idReferences: null
+ unresolved: null
+ pendingResolved: null
+ markerFirstStart: null
+ markerLastStart: null
+ markerFirstAny: null
+ markerLastEnd: null
+ markerLastAny: null
+}
+</screen>
+
+<para>When <literal>makeNewPage</literal> returns, the Page
+LayoutManager has a Page Viewport and a Body Region object. The layout
+dimensions have been calculated:</para>
+
+<screen>
+ this = {
+ pageNumberGenerator: instance of org.apache.fop.fo.pagination.PageNumberGenerator(id=1003)
+ pageCount: 1
+ pageNumberString: "1"
+ isFirstPage: false
+ bFirstPage: false
+ curPage: instance of org.apache.fop.area.PageViewport(id=1288)
+ curBody: instance of org.apache.fop.area.BodyRegion(id=1280)
+ curSpan: null
+ curSpanColumns: 0
+ curFlow: null
+ flowBPD: 728505
+ flowIPD: 0
+ areaTree: instance of org.apache.fop.area.AreaTree(id=1005)
+ pageSequence: instance of org.apache.fop.fo.pagination.PageSequence(id=1006)
+ currentSimplePageMaster: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=1007)
+ staticContentLMs: instance of java.util.HashMap(id=1008)
+ lmls: instance of org.apache.fop.layoutmgr.LayoutManagerLS(id=1009)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.userAgent: instance of org.apache.fop.apps.FOUserAgent(id=1010)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.parentLM: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.fobj: instance of org.apache.fop.fo.pagination.PageSequence(id=1006)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.foID: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.markers: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.bFinished: false
+ org.apache.fop.layoutmgr.AbstractLayoutManager.curChildLM: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.childLMiter: instance of org.apache.fop.layoutmgr.LMiter(id=1011)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.bInited: false
+}
+</screen>
+
+<para>The method <literal>createBodyMainReferenceArea()</literal> adds
+a <literal>MainReferenceArea</literal> to the body region:</para>
+
+<screen>
+ curBody = {
+ beforeFloat: null
+ mainReference: instance of org.apache.fop.area.MainReference(id=1293)
+ footnote: null
+ columnGap: 18000
+ columnCount: 1
+ refIPD: 0
+ org.apache.fop.area.RegionReference.regionClass: 2
+ org.apache.fop.area.RegionReference.ctm: instance of org.apache.fop.area.CTM(id=1282)
+ org.apache.fop.area.RegionReference.blocks: instance of java.util.ArrayList(id=1283)
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+
+<screen>
+ curBody.mainReference = {
+ spanAreas: instance of java.util.ArrayList(id=1294)
+ columnGap: 0
+ width: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+
+<screen>
+ curBody.mainReference.spanAreas = "[]"
+</screen>
+
+<para>After <literal>createSpan(1)</literal>:</para>
+
+<screen>
+ curBody.mainReference.spanAreas = "[org.apache.fop.area.Span@1581e80]"
+</screen>
+
+<screen>
+ curBody.mainReference.spanAreas.get(0) = {
+ flowAreas: instance of java.util.ArrayList(id=1299)
+ height: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+
+ </section>
+ </section>
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/book.xml b/src/documentation/content/xdocs/DnI/book.xml
new file mode 100644
index 000000000..a528fe31b
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/book.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY ch.overview SYSTEM "overview.xml">
+<!ENTITY ch.preparation SYSTEM "preparation.xml">
+<!ENTITY ch.fotree SYSTEM "fotree.xml">
+<!ENTITY ch.areatree SYSTEM "areatree.xml">
+<!ENTITY ch.getnextbreakposs SYSTEM "getnextbreakposs.xml">
+<!ENTITY ch.addareas SYSTEM "addareas.xml">
+<!ENTITY ch.rendering SYSTEM "rendering.xml">
+<!ENTITY ch.foptrees SYSTEM "foptrees.xml">
+<!ENTITY ch.properties SYSTEM "properties.xml">
+<!ENTITY ch.fonts SYSTEM "fonts.xml">
+<!ENTITY ch.configuration SYSTEM "configuration.xml">
+]>
+
+<book>
+ <bookinfo>
+
+ <title>FOP's Design and Implementation</title>
+
+ <authorgroup>
+ <author>
+ <firstname>Simon</firstname>
+ <surname>Pepping</surname>
+ <affiliation>
+ <orgname>FOP team</orgname>
+ <orgdiv>Apache Software Foundation</orgdiv>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2004</year>
+ <holder>The Apache Software Foundation</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>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
+
+<screen>
+ <ulink url="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</ulink>
+</screen>
+
+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.</para>
+ </legalnotice>
+
+ <revhistory>
+ <revision>
+ <revnumber>0.x</revnumber>
+ <date>2003, 2004</date>
+ <revremark>Various early, partial versions</revremark>
+ </revision>
+ <revision>
+ <revnumber>1.0</revnumber>
+ <date>01 August 2004</date>
+ <revremark>Committed to the FOP code repository</revremark>
+ </revision>
+ </revhistory>
+
+ <abstract>
+ <simpara>FOP is a Formatting Object Processor of the Apache
+project. It aims to provide a standards compliant implementation of
+XSL-FO. It understands Unicode, has bidirectional writing
+capabilities, and implements a wide range of rendering
+formats.</simpara>
+
+ <simpara>FOP is a work in progress. Its code is under continuing
+development. This documentation describes the state of the code at the
+time the documentation was written. At the time you read this
+documentation the code may be different. Note also that different
+parts of the documentation were written or revised at different
+times.</simpara>
+
+ </abstract>
+
+ </bookinfo>
+
+&ch.overview;
+&ch.preparation;
+&ch.fotree;
+&ch.areatree;
+&ch.getnextbreakposs;
+&ch.addareas;
+&ch.rendering;
+&ch.foptrees;
+&ch.properties;
+&ch.fonts;
+&ch.configuration;
+
+</book>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/configuration.xml b/src/documentation/content/xdocs/DnI/configuration.xml
new file mode 100644
index 000000000..0e857836a
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/configuration.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+<chapter>
+ <title>Configuration</title>
+
+ <para>Configuration is based on the <literal>Configurable</literal>
+and <literal>Configuration</literal> interfaces of
+<literal>avalon</literal>:
+
+<screen>
+org.apache.avalon.framework.configuration.Configurable
+org.apache.avalon.framework.configuration.Configuration
+</screen>
+
+A type that implements <literal>Configurable</literal> can be
+configured by calling its method <literal>configure(Configuration
+configuration)</literal>, where the argument is the
+<literal>Configuration</literal> object that holds the user
+configuration settings. It can also be configured by calling the
+static method <literal>ContainerUtil.configure(object, cfg)</literal>
+of the class
+
+<screen>
+ContainerUtil = org.apache.avalon.framework.container.ContainerUtil
+</screen>
+
+This method checks if <literal>object</literal> implements
+<literal>Configurable</literal>. If not, no configuration is
+attempted.</para>
+
+<para>The following classes implement <literal>Configurable</literal>:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>render.AbstractRenderer</literal> and its
+subclasses (all renderers). Only
+<literal>render.pdf.PDFRenderer</literal> and
+<literal>render.ps.PSRenderer</literal> have meaningful
+implementations of the <literal>configure</literal> method. The
+command line module configures each renderer from the user
+configuration file with the subconfiguration
+<literal>renderers/renderer[@mime=$mimetype]</literal>.</para>
+ </listitem>
+ <listitem>
+ <para><literal>svg.PDFTranscoder</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>svg.PDFDocumentGraphics2D</literal>. This class
+is configured by <literal>svg.PDFTranscoder</literal> via
+<literal>ContainerUtil.configure(graphics, this.cfg)</literal>.
+</para>
+ </listitem>
+ </itemizedlist></para>
+
+<para>In addition <literal>render.ps.AbstractPSTranscoder</literal>
+has a member <literal>Configuration cfg</literal>. It configures
+graphics via <literal>ContainerUtil.configure(graphics,
+this.cfg)</literal>. The graphics are of type
+<literal>render.ps.AbstractPSDocumentGraphics2D</literal>, which does
+not implement <literal>Configurable</literal>, so that no
+configuration takes place.</para>
+
+<para><literal>render.pdf.PDFRenderer</literal> and
+<literal>svg.PDFDocumentGraphics2D</literal> both call
+<literal>fonts.FontSetup.buildFontListFromConfiguration(cfg)</literal>
+and
+<literal>pdf.PDFFilterList.buildFilterMapFromConfiguration(cfg)</literal>.</para>
+
+<para>Configuration info is used by: <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>fonts.FontSetup.buildFontListFromConfiguration(cfg)</literal>. It
+uses <literal>fonts/font/font-triplet</literal> from the renderer
+subconfiguration.</para>
+ </listitem>
+ <listitem>
+ <para><literal>pdf.PDFFilterList.buildFilterMapFromConfiguration(cfg)</literal>. It
+uses <literal>filterList/value</literal> from the renderer
+subconfiguration</para>
+ </listitem>
+ <listitem>
+ <para><literal>render.ps.PSRenderer.configure(cfg)</literal>. It
+uses <literal>auto-rotate-landscape</literal> as a Boolean.
+</para>
+ </listitem>
+ </itemizedlist></para>
+
+</chapter>
diff --git a/src/documentation/content/xdocs/DnI/cust-fo-docbook.xsl b/src/documentation/content/xdocs/DnI/cust-fo-docbook.xsl
new file mode 100644
index 000000000..503b0a81c
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/cust-fo-docbook.xsl
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"
+ version="1.0">
+
+ <xsl:import
+ href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/docbook/xsl/fo/docbook.xsl"/>
+
+ <!-- Add other variable definitions here -->
+ <xsl:variable name="paper.type" select="'A4'"/>
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="section.label.includes.component.label" select="1"/>
+ <xsl:param name="marker.section.level" select="1"/>
+ <xsl:param name="component.title.several.objects" select="1"/>
+ <xsl:param name="fop.extensions" select="1"/>
+ <xsl:param name="draft.mode" select="'no'"/>
+ <xsl:param name="draft.watermark.image"/>
+ <!-- Double sided does not produce good headers and footers -->
+ <xsl:param name="double.sided" select="1"/>
+ <!-- Add to the section title properties -->
+ <xsl:attribute-set name="section.title.properties">
+ <xsl:attribute name="text-align">start</xsl:attribute>
+ <xsl:attribute name="hyphenate">false</xsl:attribute>
+ </xsl:attribute-set>
+ <!-- Reintroduce the attribute set component.title.properties -->
+ <xsl:attribute-set name="component.title.properties">
+ <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+ <xsl:attribute name="space-before.optimum">
+ <xsl:value-of select="$body.font.master"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-before.minimum">
+ <xsl:value-of select="$body.font.master * 0.8"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-before.maximum">
+ <xsl:value-of select="$body.font.master * 1.2"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="text-align">start</xsl:attribute>
+ <xsl:attribute name="hyphenate">false</xsl:attribute>
+ </xsl:attribute-set>
+ <!-- spacing between label and title -->
+ <xsl:attribute-set name="component.title.label.properties">
+ <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">
+ <xsl:value-of select="$body.font.master"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-after.minimum">
+ <xsl:value-of select="$body.font.master * 0.8"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-after.maximum">
+ <xsl:value-of select="$body.font.master * 1.2"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 2.0736"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ </xsl:attribute-set>
+ <xsl:attribute-set name="book.titlepage.author.properties">
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.728"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ </xsl:attribute-set>
+ <xsl:attribute-set name="book.titlepage.affiliation.properties">
+ <xsl:attribute name="space-before">
+ <xsl:value-of select="$body.font.master * 1.2"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="font-style">
+ <xsl:text>italic</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.44"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="font-weight">
+ <xsl:text>normal</xsl:text>
+ </xsl:attribute>
+ </xsl:attribute-set>
+ <!-- No headers and footers on blank pages -->
+ <xsl:param name="headers.on.blank.pages" select="0"/>
+ <xsl:param name="footers.on.blank.pages" select="0"/>
+ <xsl:param name="headers.on.first.pages" select="0"/>
+ <xsl:param name="header.left.width"
+ select="'proportional-column-width(1)'"/>
+ <xsl:param name="header.center.width"
+ select="'proportional-column-width(5)'"/>
+ <xsl:param name="header.right.width"
+ select="'proportional-column-width(1)'"/>
+ <!-- No left margin for titles -->
+ <xsl:param name="title.margin.left" select="'0pc'"/>
+
+ <!--
+ * Similar to mode object.title.markup
+ * but call template substitute-markup with the abbreviated title
+ -->
+ <xsl:template match="*" mode="object.titleabbrev.markup">
+ <xsl:param name="allow-anchors" select="0"/>
+ <xsl:variable name="template">
+ <xsl:apply-templates select="." mode="object.title.template"/>
+ </xsl:variable>
+
+ <xsl:call-template name="substitute-markup">
+ <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+ <xsl:with-param name="template" select="$template"/>
+ <xsl:with-param name="title" select="titleabbrev"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <!--
+ * Construct titleabbrev with mode object.titleabbrev.markup
+ * so that the section label is included
+ -->
+ <xsl:template match="section/title
+ |simplesect/title
+ |sect1/title
+ |sect2/title
+ |sect3/title
+ |sect4/title
+ |sect5/title"
+ mode="titlepage.mode"
+ priority="2">
+ <xsl:variable name="section" select="parent::*"/>
+ <fo:block keep-with-next.within-column="always">
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id">
+ <xsl:with-param name="object" select="$section"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="level">
+ <xsl:call-template name="section.level">
+ <xsl:with-param name="node" select="$section"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="marker">
+ <xsl:choose>
+ <xsl:when test="$level &lt;= $marker.section.level">1</xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="title">
+ <xsl:apply-templates select="$section" mode="object.title.markup">
+ <xsl:with-param name="allow-anchors" select="1"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:variable name="titleabbrev">
+ <xsl:apply-templates select="$section" mode="titleabbrev.markup"/>
+ </xsl:variable>
+
+ <!-- Use for running head only if actual titleabbrev element -->
+ <xsl:variable name="titleabbrev.elem">
+ <xsl:if test="$section/titleabbrev">
+ <xsl:apply-templates select="$section"
+ mode="object.titleabbrev.markup"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:if test="$passivetex.extensions != 0">
+ <fotex:bookmark xmlns:fotex="http://www.tug.org/fotex"
+ fotex-bookmark-level="{$level + 2}"
+ fotex-bookmark-label="{$id}">
+ <xsl:value-of select="$titleabbrev"/>
+ </fotex:bookmark>
+ </xsl:if>
+
+ <xsl:if test="$axf.extensions != 0">
+ <xsl:attribute name="axf:outline-level">
+ <xsl:value-of select="count(ancestor::*)-1"/>
+ </xsl:attribute>
+ <xsl:attribute name="axf:outline-expand">false</xsl:attribute>
+ <xsl:attribute name="axf:outline-title">
+ <xsl:value-of select="$title"/>
+ </xsl:attribute>
+ </xsl:if>
+
+ <xsl:call-template name="section.heading">
+ <xsl:with-param name="level" select="$level"/>
+ <xsl:with-param name="title" select="$title"/>
+ <xsl:with-param name="marker" select="$marker"/>
+ <xsl:with-param name="titleabbrev" select="$titleabbrev.elem"/>
+ </xsl:call-template>
+ </fo:block>
+ </xsl:template>
+
+ <!--
+ * Use the attribute set component.title.properties
+ * Use mode several.objects.title.markup for actual title
+ -->
+
+ <xsl:template name="component.title">
+ <xsl:param name="node" select="."/>
+ <xsl:param name="pagewide" select="0"/>
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id">
+ <xsl:with-param name="object" select="$node"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="title">
+ <xsl:apply-templates select="$node" mode="object.title.markup">
+ <xsl:with-param name="allow-anchors" select="1"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:variable name="titleabbrev">
+ <xsl:apply-templates select="$node" mode="titleabbrev.markup"/>
+ </xsl:variable>
+
+ <xsl:if test="$passivetex.extensions != 0">
+ <fotex:bookmark xmlns:fotex="http://www.tug.org/fotex"
+ fotex-bookmark-level="2"
+ fotex-bookmark-label="{$id}">
+ <xsl:value-of select="$titleabbrev"/>
+ </fotex:bookmark>
+ </xsl:if>
+
+ <fo:block xsl:use-attribute-sets="component.title.properties">
+ <xsl:if test="$pagewide != 0">
+ <!-- Doesn't work to use 'all' here since not a child of fo:flow -->
+ <xsl:attribute name="span">inherit</xsl:attribute>
+ </xsl:if>
+ <xsl:attribute name="hyphenation-character">
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key" select="'hyphenation-character'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="hyphenation-push-character-count">
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key"
+ select="'hyphenation-push-character-count'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="hyphenation-remain-character-count">
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key"
+ select="'hyphenation-remain-character-count'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:if test="$axf.extensions != 0">
+ <xsl:attribute name="axf:outline-level">
+ <xsl:value-of select="count($node/ancestor::*)"/>
+ </xsl:attribute>
+ <xsl:attribute name="axf:outline-expand">false</xsl:attribute>
+ <xsl:attribute name="axf:outline-title">
+ <xsl:value-of select="$title"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$component.title.several.objects != 0">
+ <xsl:apply-templates select="$node"
+ mode="several.objects.title.markup"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$title"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </fo:block>
+ </xsl:template>
+
+ <!--
+ * Docbook-XSL's templates only allow a string value
+ * for the label and title.
+ * We want label and title in different fo elements.
+ * Mode several.objects.title.markup
+ -->
+ <xsl:template match="chapter" mode="several.objects.title.markup">
+
+ <fo:block xsl:use-attribute-sets="component.title.label.properties">
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key" select="'Chapter'"/>
+ </xsl:call-template>
+ <xsl:text>&#xA0;</xsl:text>
+ <xsl:apply-templates select="." mode="insert.label.markup">
+ <xsl:with-param name="label">
+ <xsl:apply-templates select="." mode="label.markup"/>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </fo:block>
+
+ <fo:block>
+ <xsl:apply-templates select="." mode="insert.title.markup">
+ <xsl:with-param name="title">
+ <xsl:apply-templates select="." mode="title.markup">
+ </xsl:apply-templates>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </fo:block>
+
+ </xsl:template>
+
+ <!--
+ * Modify the header content:
+ * chapter number,
+ * section title only on odd pages,
+ * section number also with abbreviated titles
+ -->
+ <xsl:template name="header.content">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="position" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+
+ <fo:block>
+
+ <!-- sequence can be odd, even, first, blank -->
+ <!-- position can be left, center, right -->
+ <xsl:choose>
+ <xsl:when test="$sequence = 'blank'">
+ <!-- nothing on blank pages -->
+ </xsl:when>
+
+ <xsl:when test="$sequence = 'first'">
+ <!-- nothing for first pages -->
+ </xsl:when>
+
+ <xsl:when test="$position='left' or $position='right'">
+ <!-- only draft on the left and right sides -->
+ <xsl:call-template name="draft.text"/>
+ </xsl:when>
+
+ <xsl:when test="($sequence='odd' or $sequence='even')
+ and $position='center'">
+ <xsl:if test="$pageclass != 'titlepage'">
+ <xsl:choose>
+ <xsl:when test="ancestor::book and ($double.sided != 0)
+ and $sequence='odd'">
+ <fo:retrieve-marker retrieve-class-name="section.head.marker"
+ retrieve-position="first-including-carryover"
+ retrieve-boundary="page-sequence"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="." mode="label.markup"/>
+ <xsl:text>.&#xA0;</xsl:text>
+ <xsl:apply-templates select="." mode="titleabbrev.markup"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:when>
+
+ </xsl:choose>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Parametrize the widths of the header components -->
+ <xsl:template name="header.table">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+
+ <!-- default is a single table style for all headers -->
+ <!-- Customize it for different page classes or sequence location -->
+
+ <xsl:choose>
+ <xsl:when test="$pageclass = 'index'">
+ <xsl:attribute name="margin-left">0pt</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:variable name="candidate">
+ <fo:table table-layout="fixed" width="100%">
+ <xsl:call-template name="head.sep.rule">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+
+ <fo:table-column column-number="1"
+ column-width="{$header.left.width}"/>
+ <fo:table-column column-number="2"
+ column-width="{$header.center.width}"/>
+ <fo:table-column column-number="3"
+ column-width="{$header.right.width}"/>
+ <fo:table-body>
+ <fo:table-row height="14pt">
+ <fo:table-cell text-align="left" display-align="before">
+ <xsl:if test="$fop.extensions = 0">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ </xsl:if>
+ <fo:block>
+ <xsl:call-template name="header.content">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="position" select="'left'"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+ </fo:block>
+ </fo:table-cell>
+ <fo:table-cell text-align="center" display-align="before">
+ <xsl:if test="$fop.extensions = 0">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ </xsl:if>
+ <fo:block>
+ <xsl:call-template name="header.content">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="position" select="'center'"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+ </fo:block>
+ </fo:table-cell>
+ <fo:table-cell text-align="right" display-align="before">
+ <xsl:if test="$fop.extensions = 0">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ </xsl:if>
+ <fo:block>
+ <xsl:call-template name="header.content">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="position" select="'right'"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </xsl:variable>
+
+ <!-- Really output a header? -->
+ <xsl:choose>
+ <xsl:when test="$pageclass = 'titlepage' and $gentext-key = 'book'
+ and $sequence='first'">
+ <!-- no, book titlepages have no headers at all -->
+ </xsl:when>
+ <xsl:when test="($sequence = 'blank' and $headers.on.blank.pages = 0)
+ or ($sequence = 'first' and $headers.on.first.pages = 0)">
+ <!-- no output -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$candidate"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- author and affiliation on the titlepage -->
+ <xsl:template match="author" mode="titlepage.mode">
+ <fo:block xsl:use-attribute-sets="book.titlepage.author.properties">
+ <xsl:call-template name="anchor"/>
+ <xsl:call-template name="person.name"/>
+ </fo:block>
+ <xsl:apply-templates select="affiliation" mode="titlepage.mode"/>
+ </xsl:template>
+
+ <xsl:template match="affiliation" mode="titlepage.mode">
+ <fo:block xsl:use-attribute-sets="book.titlepage.affiliation.properties">
+ <xsl:for-each select="*">
+ <xsl:if test="position() != 1">
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ <xsl:apply-templates mode="titlepage.mode"/>
+ </xsl:for-each>
+ </fo:block>
+ </xsl:template>
+
+ <!--
+ * I am not sure about the purpose of this template;
+ * in FOP it causes an extra page, which is not blank.
+ -->
+ <xsl:template name="book.titlepage.separator">
+ <!--
+ <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" break-after="page"/>
+-->
+ </xsl:template>
+
+ <!-- Add revhistory to the verso page -->
+ <xsl:template name="book.titlepage.verso">
+ <xsl:choose>
+ <xsl:when test="bookinfo/title">
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/title"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="title"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/author"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/abstract"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode"
+ select="bookinfo/legalnotice"/>
+ </xsl:template>
+
+ <xsl:template match="revhistory" mode="book.titlepage.verso.auto.mode">
+ <fo:block xsl:use-attribute-sets="book.titlepage.verso.style
+ normal.para.spacing">
+ <xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
+ </fo:block>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/documentation/content/xdocs/DnI/cust-html-docbook.xsl b/src/documentation/content/xdocs/DnI/cust-html-docbook.xsl
new file mode 100644
index 000000000..ce688571e
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/cust-html-docbook.xsl
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:import
+ href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/docbook/xsl/html/chunk.xsl"/>
+ <!-- Use this import if you do not want chunks -->
+ <!--
+ <xsl:import
+ href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/docbook/xsl/html/docbook.xsl"/>
+-->
+
+ <xsl:param name="chunk.section.depth" select="2"/>
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="base.dir" select="'DnI-html/'"/>
+
+</xsl:stylesheet>
diff --git a/src/documentation/content/xdocs/DnI/cust-xhtml-docbook.xsl b/src/documentation/content/xdocs/DnI/cust-xhtml-docbook.xsl
new file mode 100644
index 000000000..0bfb38d6d
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/cust-xhtml-docbook.xsl
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://www.w3.org/1999/xhtml"
+ version="1.0">
+
+ <xsl:import
+ href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/docbook/xsl/xhtml/chunk.xsl"/>
+
+ <!-- Use this import if you do not want chunks -->
+ <!--
+ <xsl:import
+ href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/docbook/xsl/xhtml/docbook.xsl"/>
+-->
+
+ <xsl:param name="chunker.output.encoding" select="'UTF-8'"/>
+ <xsl:param name="chunk.section.depth" select="2"/>
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="base.dir" select="'DnI-xhtml/'"/>
+
+</xsl:stylesheet>
diff --git a/src/documentation/content/xdocs/DnI/fonts.xml b/src/documentation/content/xdocs/DnI/fonts.xml
new file mode 100644
index 000000000..7c2b97263
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/fonts.xml
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>Fonts</title>
+
+ <section>
+ <title>Font setup</title>
+
+ <para>Terminology:
+<itemizedlist>
+ <listitem>
+ <simpara>Index, font index: The index of a character in a
+font, i.e. the place of the glyph for a character in a font.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Code point: The same as font index.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Character value: The two-byte
+(<literal>char</literal>) value by which a character is represented in
+memory and in Unicode. Note that this only works straightforwardly for
+the basal plane (BMP) of Unicode, i.e. for <literal>characters &lt;=
+0xFFFF</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Unicode code point: The same as the character
+value.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>During compilation for each of the 14 base fonts a class is
+generated from the XML font metric files. Each font class contains
+the metric information and an encoding table (a
+<literal>CodePointMapping</literal> object). The metric information is
+static, the encoding table is an object member.</para>
+
+ <para>During compilation also a class
+<literal>CodePointMapping</literal> is generated, which contains the
+known encodings as static values. For each known encoding it contains
+a table as a static final array of int. The array holds an alternation
+of font index and character value; in fact it is a mapping from
+<literal>table[2i]</literal> to <literal>table[2i+1]</literal>, where
+<literal>table[2i]</literal> is the font index and
+<literal>table[2i+1]</literal> is the character.</para>
+
+ <para>When an encoding is needed in the process, a
+<literal>CodePointMapping</literal> object is created from the
+encoding table. It contains a table (<literal>char array</literal>)
+called <literal>latin1Map</literal> of the font indices for the
+characters of the Latin1 range (<literal>0-0xFF</literal>) in
+character value order. It also contains two tables (<literal>char
+array</literal>s), called characters and codepoints, for the higher
+character values. The table characters contains the character values
+in order, and the table codepoints contains the corresponding font
+indexes for this encoding in the same order. The characters can be
+retrieved from these tables as follows:
+
+<screen>char &lt;= 0xFF: index = latin1Map[character]
+char > 0xFF:
+ find i such that characters[i] == char;
+ then index = codepoints[i]
+</screen></para>
+
+ <para>In the code the characters are retrieved from the
+<literal>CodePointMapping</literal> object with its method
+<literal>mapChar(char c)</literal>.</para>
+
+ <para>In FOP's preparation stage the fonts are set up in the
+method <literal>Driver.getContentHandler</literal>. It calls the
+<literal>renderer</literal>'s method
+<literal>setupFontInfo(currentDocument)</literal>. The
+<literal>Document</literal> object <literal>currentDocument</literal>
+(which is the <literal>foTreeControl</literal> object) is able to
+store the font setup info and has methods to access the fonts
+registered with it.</para>
+
+<para>The <literal>PrintRenderer</literal> (PostScript and PDF) then
+calls <literal>FontSetup.setup(fontInfo, fontList)</literal>, where
+<literal>fontInfo</literal> is <literal>the</literal> Document object
+and <literal>fontList</literal> is the list of user configured fonts
+registered with the <literal>renderer</literal> in its member
+<literal>fontList</literal>.
+ <screen>
+ [1] org.apache.fop.fonts.FontSetup.setup (FontSetup.java:98)
+ [2] org.apache.fop.render.PrintRenderer.setupFontInfo (PrintRenderer.java:77)
+ [3] org.apache.fop.apps.Driver.getContentHandler (Driver.java:551)
+ [4] org.apache.fop.apps.Driver.render (Driver.java:602)
+ [5] org.apache.fop.apps.Driver.render (Driver.java:589)
+ [6] org.apache.fop.apps.Fop.main (Fop.java:102)
+</screen></para>
+
+ <para><literal>FontSetup.setup</literal> takes three actions:
+<orderedlist>
+ <listitem>
+ <simpara>An object is created for each of the base 14 fonts
+and registered with the <literal>fontInfo</literal> object in its
+member fonts.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A series of triplets (family, style, weight) is set
+up. To each triplet a font is assigned; this font will be used when a
+font with the characteristics of that triplet is requested. The
+triplets registered with <literal>fontInfo</literal> in its member
+<literal>triplets</literal>. The member <literal>triplets</literal> is
+a map which uses a string of the form
+<literal>family,style,weight</literal> as a key. There is also a class
+<literal>FontTriplet</literal>, which is not used.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>The user configured fonts are added.</simpara>
+ </listitem>
+ </orderedlist></para>
+
+ <para>In the following listing <literal>treeBuilder</literal> is
+the tree builder object set up in the preparation stage, and
+<literal>foTreeControl</literal> is the document object. The list of
+user configured fonts of the <literal>renderer</literal> is empty, and
+the list of used fonts is still empty.
+
+<screen>
+ treeBuilder.foTreeControl.fonts = "{
+ F1=org.apache.fop.fonts.base14.Helvetica@e3c624,
+ F2=org.apache.fop.fonts.base14.HelveticaOblique@e020c9,
+ F3=org.apache.fop.fonts.base14.HelveticaBold@13e58d4,
+ F4=org.apache.fop.fonts.base14.HelveticaBoldOblique@15a6029,
+ F5=org.apache.fop.fonts.base14.TimesRoman@17494c8,
+ F6=org.apache.fop.fonts.base14.TimesItalic@1e57e8f,
+ F7=org.apache.fop.fonts.base14.TimesBold@888e6c,
+ F8=org.apache.fop.fonts.base14.TimesBoldItalic@d3db51,
+ F9=org.apache.fop.fonts.base14.Courier@5f6303,
+ F10=org.apache.fop.fonts.base14.CourierOblique@117f31e,
+ F11=org.apache.fop.fonts.base14.CourierBold@1d7fbfb,
+ F12=org.apache.fop.fonts.base14.CourierBoldOblique@5d9084
+ F13=org.apache.fop.fonts.base14.Symbol@39e5b5,
+ F14=org.apache.fop.fonts.base14.ZapfDingbats@1b5998f,
+}"
+</screen>
+
+<screen>
+ treeBuilder.foTreeControl.triplets = "{
+ Computer-Modern-Typewriter,normal,400=F9,
+ Courier,italic,400=F10,
+ Courier,italic,700=F12,
+ Courier,normal,400=F9,
+ Courier,normal,700=F11,
+ Courier,oblique,400=F10,
+ Courier,oblique,700=F12,
+ Helvetica,italic,400=F2,
+ Helvetica,italic,700=F4,
+ Helvetica,normal,400=F1,
+ Helvetica,normal,700=F3,
+ Helvetica,oblique,400=F2,
+ Helvetica,oblique,700=F4,
+ Symbol,normal,400=F13,
+ Times Roman,italic,400=F6,
+ Times Roman,italic,700=F8,
+ Times Roman,normal,400=F5,
+ Times Roman,normal,700=F7,
+ Times Roman,oblique,400=F6,
+ Times Roman,oblique,700=F8,
+ Times,italic,400=F6,
+ Times,italic,700=F8,
+ Times,normal,400=F5,
+ Times,normal,700=F7,
+ Times,oblique,400=F6,
+ Times,oblique,700=F8,
+ Times-Roman,italic,400=F6,
+ Times-Roman,italic,700=F8,
+ Times-Roman,normal,400=F5,
+ Times-Roman,normal,700=F7,
+ Times-Roman,oblique,400=F6,
+ Times-Roman,oblique,700=F8,
+ ZapfDingbats,normal,400=F14,
+ any,italic,400=F6,
+ any,italic,700=F8,
+ any,normal,400=F5,
+ any,normal,700=F7,
+ any,oblique,400=F6,
+ any,oblique,700=F8,
+ monospace,italic,400=F10,
+ monospace,italic,700=F12,
+ monospace,normal,400=F9,
+ monospace,normal,700=F11,
+ monospace,oblique,400=F10,
+ monospace,oblique,700=F12,
+ sans-serif,italic,400=F2,
+ sans-serif,italic,700=F4,
+ sans-serif,normal,400=F1,
+ sans-serif,normal,700=F3,
+ sans-serif,oblique,400=F2,
+ sans-serif,oblique,700=F4,
+ serif,italic,400=F6,
+ serif,italic,700=F8,
+ serif,normal,400=F5,
+ serif,normal,700=F7,
+ serif,oblique,400=F6
+ serif,oblique,700=F8,
+}"
+</screen>
+
+<screen>
+ treeBuilder.foTreeControl.atModel.renderer.fontList = null
+ treeBuilder.foTreeControl.usedFonts = "{}"
+</screen></para>
+
+ <para>User configured fonts should be listed in the member
+<literal>fontList</literal> of the <literal>renderer</literal>. The
+objects in the list are <literal>EmbedFontInfo</literal> objects. They
+are created from the path to the metrics file, boolean kerning, the
+list of triplets for which this font may be used, the path to the font
+file. The triplets are <literal>FontTriplet</literal> objects. The
+list may be created from an Avalon configuration object with
+<literal>FontSetup.buildFontListFromConfiguration(Configuration
+cfg)</literal>.</para>
+
+ <para><literal>>FontSetup.addConfiguredFonts</literal> creates a
+<literal>LazyFont</literal> font object from each
+<literal>EmbedFontInfo</literal> object. <literal>LazyFont</literal>
+fonts are not loaded until they are actually used. This makes it
+possible to register a large number of fonts at low cost.</para>
+
+ <para>Font weights are integers between 100 and 900.
+<literal>Font.NORMAL</literal> and <literal>Font.BOLD</literal> are
+set to 400 and 700, respectively. See
+<literal>FontUtil.parseCSS2FontWeight</literal>.</para>
+
+ </section>
+
+ <section>
+ <title>Classes and interfaces used in the font package</title>
+
+ <screen>IF FontMetrics
+SubIF FontDescriptor
+
+IF MutableFont
+
+Abstract Class TypeFace: FontMetrics
+Classes Courier etc.
+
+Abstract Class TypeFace: FontMetrics
+Abstract Class CustomFont: FontDescriptor, MutableFont
+Abstract Class CIDFont, Class SingleByteFont
+Class MultiByteFont (sub CIDFont)
+
+Abstract Class TypeFace: FontMetrics
+Abstract Class CustomFont: FontDescriptor, MutableFont
+Class SingleByteFont
+
+Abstract Class TypeFace: FontMetrics
+Class LazyFont: FontDescriptor
+
+Abstract Class TypeFace: FontMetrics
+Class FontMetricsMapper, for AWT fonts
+</screen>
+
+ <para><literal>SingleByteFont</literal>,
+<literal>MultiByteFont</literal>: A font is not really single or
+multibyte. Rather the name <literal>SingleByteFont</literal> indicates
+that the font does not contain more than 256 glyphs; the
+implementation is optimized for this. In
+<literal>MultiByteFont</literal> (actually CIDFont Type2) the
+implementation is optimized for fonts with an unknown number of
+glyphs.</para>
+
+ </section>
+
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/foptrees.xml b/src/documentation/content/xdocs/DnI/foptrees.xml
new file mode 100644
index 000000000..46c70b11c
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/foptrees.xml
@@ -0,0 +1,1065 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>The trees in FOP</title>
+
+ <section>
+ <title>Overview</title>
+
+ <orderedlist>
+ <listitem>
+ <simpara>The FO document. Each XML document and therefore
+also an FO document has a hierarchical structure that can be modeled
+as a tree.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>The FO DOM tree. This tree has the same
+hierarchical structure as an FO document, and is often built from an
+XML document.</simpara>
+ </listitem>
+ </orderedlist>
+
+ <para>FOP can work from either an FO document or an FO DOM tree.
+FOP does not build a DOM tree from an FO document.</para>
+
+ <orderedlist continuation="continues">
+ <listitem>
+ <simpara>The FO tree. FOP builds this tree from either the FO document or
+the FO DOM tree. The FO nodes in this tree correspond to the
+elements in the FO document or the XML nodes in the FO DOM
+tree. Note, however, that they are different from DOM tree
+nodes.</simpara>
+ </listitem>
+ </orderedlist>
+
+ <para>When a sufficient part of the FO tree has been built (in
+current FOP the subtree of a PageSequence FO node), the layout process
+is started. This process builds three trees.</para>
+
+ <orderedlist continuation="continues">
+ <listitem>
+ <simpara>The LM tree. This tree corresponds closely to the FO
+tree because each FO node creates a layout manager. But there are
+deviations. For example, a BlockLayoutManager creates a
+LineLayoutManager for each consecutive sequence of child FO nodes that
+generate inline areas.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>The BP tree. Each layout manager returns zero or more
+BreakPoss to its parent. These BreakPoss are connected to BreakPoss
+that the layout manager received from its child layout managers. This
+is not a real tree. There are many BP without a parent BP. They are
+connected to their siblings by their LM.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>The Area tree. Using the information stored in the BP
+tree and in the LMs connected with the BPs, layout areas are
+constructed. These areas are placed within other areas, which is
+expressed in a tree hierarchy.</simpara>
+ </listitem>
+ </orderedlist>
+
+ </section>
+
+ <section>
+ <title>The tree of BreakPoss</title>
+
+ <para>Each LM contains a list of BPs belonging to and returned
+to it by the childLMs during the <literal>getNextBreakPoss</literal>
+stack. These are the BPs that end an area of the childLM. The BP
+contains an index <literal>position.iLeafPos</literal>, which connects
+it to the BP with that index in the list of BPs of its own LM (the
+childLM).</para>
+
+ <para>For example, BlockLM's list <literal>childBreaks</literal>
+contains the BPs that end a line (if the childLM is a LineLM).
+LineLM's list <literal>vecInlineBreaks</literal> contains the BPs that
+were returned to it as possible linebreaks by TextLM (if the childLM
+is a TextLM). TextLM's list <literal>vecAreaInfo</literal> contains
+<literal>AreaInfo</literal> objects. A BP in BlockLM's list
+<literal>childBreaks</literal> belongs e.g. to a LineLM. Its index
+<literal>position.iLeafPos</literal> points to the BP with that index
+in <literal>vecInlineBreaks</literal> in ListLM. That BP belongs e.g.
+to a TextLM, and its index <literal>position.iLeafPos</literal> points
+to the <literal>AreaInfo</literal> object with that index in
+<literal>vecAreaInfo</literal> in TextLM.</para>
+
+ <screen>
+ +-----------------+
+ LM | bp0 bp1 bp2 bp3 |
+ +-++--++--++--++--+
+ .......................:|..:| :| :|
+ : +----------+ | :| :|
+ : | +----------+ :| :+----------------------+
+ : | | ........:| :....... |
+ : | | : | : |
+ : +----------+---+--+ : +------+------+ : +--------------+------+
+ LM | bp0 bp1 bp2 bp3 | LM | bp0 bp1 bp2 | LM | bp0 bp1 bp2 bp3 bp4 |
+ +-----------------+ +-------------+ +---------------------+
+</screen>
+
+ <para>The BPs are held in a list by the LM shown in front of
+them. They are associated with one of the childLMs, which is shown by
+the dotted lines. Their member <literal>position.iLeafPos</literal>
+connects them with the BP in their LM's list with that index, as shown
+by the dashed lines.</para>
+
+ </section>
+
+
+ <section>
+ <title>Example of an FO and area tree</title>
+
+ <section>
+ <title>The FO file</title>
+
+ <literallayout><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="simpleA4"
+ page-height="29.7cm" page-width="21cm"
+ margin-top="2cm"
+ margin-bottom="2cm" margin-left="2cm"
+ margin-right="2cm">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="simpleA4">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block font-size="16pt" font-weight="bold"
+ space-after="5mm">Test FO
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>]]></literallayout>
+
+ </section>
+
+ <section>
+ <title>The corresponding FO tree</title>
+
+ <para>In the listing below the notation has been shortened;
+<literal>.[n]</literal> denotes the nth child, for which the full
+notation is <literal>.children.elementData[n]</literal> . A number of
+static members are not shown.</para>
+
+ <para>The root:
+
+<screen>
+ root = "fo:root at line 2:44"
+
+ root = {
+ layoutMasterSet: instance of org.apache.fop.fo.pagination.LayoutMasterSet(id=1089)
+ pageSequences: instance of java.util.ArrayList(id=1102)
+ runningPageNumberCounter: 0
+ foTreeControl: instance of org.apache.fop.apps.Document(id=1103)
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1104)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1105)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: instance of java.util.ArrayList(id=1106)
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 2
+ org.apache.fop.fo.FObj.column: 44
+ org.apache.fop.fo.FONode.parent: null
+ org.apache.fop.fo.FONode.name: "fo:root"
+}
+</screen>
+</para>
+
+ <para>The root has no properties; the namespace nodes do not result in
+properties:
+
+<screen>
+ root.propertyList = "{}"
+</screen>
+</para>
+
+ <para>The root has two children:
+
+<screen>
+ root.children = "[
+ fo:layout-master-set at line 3:25
+ fo:page-sequence at line 12:49
+]"
+</screen>
+</para>
+
+ <para>The first child of root is the layout master set:
+
+<screen>
+ root.[0] = "fo:layout-master-set at line 3:25"
+
+ root.[0] = {
+ simplePageMasters: instance of java.util.HashMap(id=1111)
+ pageSequenceMasters: instance of java.util.HashMap(id=1112)
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1113)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1114)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: instance of java.util.ArrayList(id=1115)
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 3
+ org.apache.fop.fo.FObj.column: 25
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.pagination.Root(id=1088)
+ org.apache.fop.fo.FONode.name: "fo:layout-master-set"
+}
+
+ root.[0].propertyList = "{}"
+</screen>
+</para>
+
+ <para>The layout master set contains a simple page master:
+
+<screen>
+ root.[0].children = "[
+ fo:simple-page-master at line 8:28
+]"
+
+ root.[0].[0] = "fo:simple-page-master at line 8:28"
+
+ root.[0].[0] = {
+ regions: instance of java.util.HashMap(id=1120)
+ masterName: "simpleA4"
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1122)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1123)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: null
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 8
+ org.apache.fop.fo.FObj.column: 28
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.pagination.LayoutMasterSet(id=1089)
+ org.apache.fop.fo.FONode.name: "fo:simple-page-master"
+}
+</screen>
+</para>
+
+ <para>The properties of the simple page master:
+
+<screen>
+ root.[0].[0].propertyList = "{
+ master-name=org.apache.fop.fo.StringProperty@1958bf9
+ margin-top=org.apache.fop.fo.LengthProperty@118958e
+ margin-right=org.apache.fop.fo.LengthProperty@102b2b6
+ margin-bottom=org.apache.fop.fo.LengthProperty@22d166
+ margin-left=org.apache.fop.fo.LengthProperty@1e1962d
+ page-width=org.apache.fop.fo.LengthProperty@14a75bb
+ page-height=org.apache.fop.fo.LengthProperty@17779e3
+}"
+
+ root.[0].[0].propertyList.get("master-name") = {
+ str: "simpleA4"
+ org.apache.fop.fo.Property.specVal: null
+}
+
+ root.[0].[0].propertyList.get("page-height") = {
+ length: instance of org.apache.fop.datatypes.FixedLength(id=1329)
+ org.apache.fop.fo.Property.specVal: null
+}
+
+ root.[0].[0].propertyList.get("page-height").length = "841889mpt"
+</screen>
+</para>
+
+ <para>The simple page master has only one region, the body:
+
+<screen>
+ root.[0].[0].regions = "{body=fo:region-body at line 9:24}"
+</screen>
+</para>
+
+ <para>The region body:
+
+<screen>
+ root.[0].[0].regions.get("body") = "fo:region-body at line 9:24"
+
+ root.[0].[0].regions.get("body") = {
+ backgroundColor: null
+ org.apache.fop.fo.pagination.Region.layoutMaster: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=1082)
+ org.apache.fop.fo.pagination.Region.regionName: "xsl-region-body"
+ org.apache.fop.fo.pagination.Region.overflow: 8
+ org.apache.fop.fo.pagination.Region.wm: 49
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1344)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1345)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: null
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 9
+ org.apache.fop.fo.FObj.column: 24
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=1082)
+ org.apache.fop.fo.FONode.name: "fo:region-body"
+}
+
+ root.[0].[0].regions.get("body").propertyList = "{}"
+</screen>
+</para>
+
+ <para>The second child of root is the page sequence:
+
+<screen>
+ root.[1] = "fo:page-sequence at line 12:49"
+
+ root.[1] = {
+ root: instance of org.apache.fop.fo.pagination.Root(id=1088)
+ layoutMasterSet: instance of org.apache.fop.fo.pagination.LayoutMasterSet(id=1089)
+ flowMap: instance of java.util.HashMap(id=1090)
+ sequenceStarted: true
+ ipnValue: "auto"
+ currentPageNumber: 1
+ explicitFirstNumber: 0
+ firstPageNumber: 1
+ pageNumberGenerator: instance of org.apache.fop.fo.pagination.PageNumberGenerator(id=1074)
+ forcePageCount: 8
+ pageCount: 0
+ isForcing: false
+ pageNumberType: 1
+ thisIsFirstPage: true
+ simplePageMaster: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=1082)
+ pageSequenceMaster: null
+ mainFlow: instance of org.apache.fop.fo.pagination.Flow(id=1092)
+ titleFO: null
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1096)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1097)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: instance of java.util.ArrayList(id=1098)
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 12
+ org.apache.fop.fo.FObj.column: 49
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.pagination.Root(id=1088)
+ org.apache.fop.fo.FONode.name: "fo:page-sequence"
+}
+</screen>
+</para>
+
+ <para>The page-sequence has one property, the reference to the page master:
+
+<screen>
+ root.[1].propertyList = "{
+ master-reference=org.apache.fop.fo.StringProperty@104e28b
+}"
+
+ root.[1].propertyList.get("master-reference") = {
+ str: "simpleA4"
+ org.apache.fop.fo.Property.specVal: null
+}
+</screen>
+</para>
+
+ <para>The page-sequence has one child, the flow:
+
+<screen>
+ root.[1].children = "[
+ fo:flow at line 13:42
+]"
+
+ root.[1].[0] = "fo:flow at line 13:42"
+
+ root.[1].[0] = {
+ pageSequence: instance of org.apache.fop.fo.pagination.PageSequence(id=1081)
+ markerSnapshot: null
+ flowName: "xsl-region-body"
+ contentWidth: 0
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1367)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1368)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: instance of java.util.ArrayList(id=1369)
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 13
+ org.apache.fop.fo.FObj.column: 42
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.pagination.PageSequence(id=1081)
+ org.apache.fop.fo.FONode.name: "fo:flow"
+}
+</screen>
+</para>
+
+ <para>The flow has one property, the flow name:
+
+<screen>
+ root.[1].[0].propertyList = "{
+ flow-name=org.apache.fop.fo.StringProperty@6458a6
+}"
+
+ root.[1].[0].propertyList.get("flow-name") = {
+ str: "xsl-region-body"
+ org.apache.fop.fo.Property.specVal: null
+}
+</screen>
+</para>
+
+ <para>The flow has one child, a block:
+
+<screen>
+ root.children.elementData[1].children.elementData[0].children = "[
+ fo:block at line 15:28
+]"
+
+ root.[1].[0].[0] = "fo:block at line 15:28"
+
+ root.[1].[0].[0] = {
+ align: 0
+ alignLast: 0
+ breakAfter: 0
+ lineHeight: 0
+ startIndent: 0
+ endIndent: 0
+ spaceBefore: 0
+ spaceAfter: 0
+ textIndent: 0
+ keepWithNext: 0
+ backgroundColor: null
+ blockWidows: 0
+ blockOrphans: 0
+ id: null
+ span: 59
+ wsTreatment: 41
+ lfTreatment: 98
+ bWScollapse: true
+ anythingLaidOut: false
+ firstInlineChild: null
+ org.apache.fop.fo.FObjMixed.textInfo: instance of org.apache.fop.fo.TextInfo(id=1377)
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: instance of org.apache.fop.fo.PropertyList(id=1378)
+ org.apache.fop.fo.FObj.propMgr: instance of org.apache.fop.fo.PropertyManager(id=1379)
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: instance of java.util.ArrayList(id=1380)
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 15
+ org.apache.fop.fo.FObj.column: 28
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.pagination.Flow(id=1092)
+ org.apache.fop.fo.FONode.name: "fo:block"
+}
+
+ root.[1].[0].[0].propertyList = "{
+ font-size=org.apache.fop.fo.LengthProperty@ae4646
+ font-weight=org.apache.fop.fo.StringProperty@187b287
+ space-after=org.apache.fop.fo.SpaceProperty@1d9e2c7
+}"
+</screen>
+</para>
+
+ <para>The block has two children:
+
+<screen>
+ root.[1].[0].[0].children = "[
+ fo:text at line 15:35
+ fo:text at line 16:7
+]"
+
+ root.[1].[0].[0].[0] = "fo:text at line 15:35"
+
+ root.[1].[0].[0].[0] = {
+ ca: instance of char[7] (id=1386)
+ start: 0
+ length: 7
+ textInfo: instance of org.apache.fop.fo.TextInfo(id=1377)
+ lastFOTextProcessed: instance of org.apache.fop.fo.FOText(id=1387)
+ prevFOTextThisBlock: null
+ nextFOTextThisBlock: instance of org.apache.fop.fo.FOText(id=1387)
+ ancestorBlock: instance of org.apache.fop.fo.flow.Block(id=1375)
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: null
+ org.apache.fop.fo.FObj.propMgr: null
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: null
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 15
+ org.apache.fop.fo.FObj.column: 35
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.flow.Block(id=1375)
+ org.apache.fop.fo.FONode.name: "fo:text"
+}
+</screen>
+</para>
+
+ <para>This text node contains the text "Test FO":
+
+<screen>
+ root.[1].[0].[0].[0].ca = {
+T, e, s, t, , F, O
+}
+
+ root.[1].[0].[0].[1] = "fo:text at line 16:7"
+
+ root.[1].[0].[0].[1] = {
+ ca: instance of char[1] (id=1390)
+ start: 0
+ length: 1
+ textInfo: instance of org.apache.fop.fo.TextInfo(id=1377)
+ lastFOTextProcessed: instance of org.apache.fop.fo.FOText(id=1387)
+ prevFOTextThisBlock: instance of org.apache.fop.fo.FOText(id=1384)
+ nextFOTextThisBlock: null
+ ancestorBlock: instance of org.apache.fop.fo.flow.Block(id=1375)
+ org.apache.fop.fo.FObj.propertyListTable: instance of org.apache.fop.fo.Property$Maker[248] (id=1094)
+ org.apache.fop.fo.FObj.propertyList: null
+ org.apache.fop.fo.FObj.propMgr: null
+ org.apache.fop.fo.FObj.id: null
+ org.apache.fop.fo.FObj.children: null
+ org.apache.fop.fo.FObj.markers: null
+ org.apache.fop.fo.FObj.systemId: "file:/path/to/fo-file"
+ org.apache.fop.fo.FObj.line: 16
+ org.apache.fop.fo.FObj.column: 7
+ org.apache.fop.fo.FONode.parent: instance of org.apache.fop.fo.flow.Block(id=1375)
+ org.apache.fop.fo.FONode.name: "fo:text"
+}
+</screen>
+</para>
+
+ <para>This text node contains the text "\n":
+
+<screen>
+ root.[1].[0].[0].[1].ca = {
+}
+</screen>
+</para>
+ </section>
+
+ <section>
+ <title>The corresponding area tree</title>
+
+ <para><itemizedlist>
+ <listitem>
+ <simpara>PageViewport has a Page page and a Rectangle2D
+viewArea (reference/viewport pair).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Page has five RegionViewports.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>RegionViewport has a RegionReference region and a
+Rectangle2D viewArea (reference/viewport pair).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>BodyRegion has a MainReference mainReference, a
+BeforeFloat beforeFloat, and a Footnote footnote.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>MainReference has a list of Spans.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Span has a list of Flows.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Flow has a list of Blocks.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Block has a list of Blocks or LineAreas.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>LineArea has a list of InlineAreas.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Text Area (subclass of InlineArea) has text.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The structure of the area tree is as follows:
+
+<screen>
+PageViewport
+|
++-Page
+ |
+ +-RegionViewport
+ |
+ +-BodyRegion
+ |
+ +-MainReference
+ | |
+ | +-Span
+ | | |
+ | | +-Flow
+ | |
+ | +-Span
+ | | |
+ | | +-Flow
+ | | |
+ | | +-Block
+ | | | |
+ | | | +-LineArea
+ | | | |
+ | | | +-TextArea
+ | | |
+ | | +-Block
+ | |
+ | +-Span
+ | | |
+ | | +-Flow
+ | |
+ | +-Span
+ | | |
+ | | +-Flow
+ | |
+ | +-Span
+ | |
+ | +-Flow
+ |
+ +blocks
+ |
+ +CTM
+</screen>
+</para>
+
+ <para>In the listing below members of an
+<literal>arraylist</literal> are indicated by <literal>[n]</literal>,
+which stands for <literal>get(n)</literal>. If the
+<literal>arraylist</literal> is called <literal>children</literal>,
+the word <literal>children</literal> has been omitted, so that
+<literal>[n]</literal> then stands for
+<literal>children.get(n)</literal>.</para>
+
+ <para>Type: <literal>org.apache.fop.area.PageViewport</literal>:
+<screen>
+ curPage = "PageViewport: page=1"
+
+ curPage = {
+ page: instance of org.apache.fop.area.Page(id=1394)
+ viewArea: instance of java.awt.Rectangle(id=1395)
+ clip: false
+ pageNumber: "1"
+ idReferences: null
+ unresolved: null
+ pendingResolved: null
+ markerFirstStart: null
+ markerLastStart: null
+ markerFirstAny: null
+ markerLastEnd: null
+ markerLastAny: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Page</literal>:
+<screen>
+ curPage.page = {
+ regionBefore: null
+ regionStart: null
+ regionBody: instance of org.apache.fop.area.RegionViewport(id=1397)
+ regionEnd: null
+ regionAfter: null
+ unresolved: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.RegionViewport</literal>:
+<screen>
+ curPage.page.regionBody = {
+ region: instance of org.apache.fop.area.BodyRegion(id=1077)
+ viewArea: instance of java.awt.Rectangle(id=1399)
+ clip: false
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.BodyRegion</literal>:
+<screen>
+ curPage.page.regionBody.region = {
+ beforeFloat: null
+ mainReference: instance of org.apache.fop.area.MainReference(id=1401)
+ footnote: null
+ columnGap: 18000
+ columnCount: 1
+ refIPD: 0
+ org.apache.fop.area.RegionReference.regionClass: 2
+ org.apache.fop.area.RegionReference.ctm: instance of org.apache.fop.area.CTM(id=1402)
+ org.apache.fop.area.RegionReference.blocks: instance of java.util.ArrayList(id=1403)
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.MainReference</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference = {
+ spanAreas: instance of java.util.ArrayList(id=1405)
+ columnGap: 0
+ width: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>The main reference contains five span areas. Four are
+empty. Number 1 contains the text of this page.
+
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas = "[
+ org.apache.fop.area.Span@53c3f5
+ org.apache.fop.area.Span@101ac93
+ org.apache.fop.area.Span@125d61e
+ org.apache.fop.area.Span@155d3a3
+ org.apache.fop.area.Span@718242
+]"
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Span</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[0] = {
+ flowAreas: instance of java.util.ArrayList(id=1409)
+ height: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[0].flowAreas = "[
+ org.apache.fop.area.Flow@e33e18
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.Flow</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[0].flowAreas[0] = {
+ stacking: 2
+ width: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 0
+ org.apache.fop.area.BlockParent.height: 0
+ org.apache.fop.area.BlockParent.children: null
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Span</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1] = {
+ flowAreas: instance of java.util.ArrayList(id=1412)
+ height: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[0].flowAreas = "[
+ org.apache.fop.area.Flow@e33e18
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.Flow</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0] = {
+ stacking: 2
+ width: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 0
+ org.apache.fop.area.BlockParent.height: 0
+ org.apache.fop.area.BlockParent.children: instance of java.util.ArrayList(id=1416)
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].children = "[
+ org.apache.fop.area.Block@61f533
+ org.apache.fop.area.Block@12922f6
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.Block</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[0] = {
+ stacking: 2
+ positioning: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 481891
+ org.apache.fop.area.BlockParent.height: 19200
+ org.apache.fop.area.BlockParent.children: instance of java.util.ArrayList(id=1419)
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[0].children = "[
+ org.apache.fop.area.LineArea@9f0d
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.LineArea</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[0].[0] = {
+ stacking: 0
+ startIndent: 0
+ length: 0
+ lineHeight: 19200
+ baseLine: 0
+ inlineAreas: instance of java.util.ArrayList(id=1422)
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[0].[0].inlineAreas = "[
+ org.apache.fop.area.inline.TextArea@21d23b
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.inline.TextArea</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[0].[0].inlineAreas[0] = {
+ text: "Test FO"
+ iTSadjust: 0
+ org.apache.fop.area.inline.InlineArea.height: 14800
+ org.apache.fop.area.inline.InlineArea.contentIPD: 59568
+ org.apache.fop.area.inline.InlineArea.verticalPosition: 13688
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: instance of java.util.HashMap(id=1426)
+}
+</screen>
+</para>
+
+ <para>
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[0].[0].inlineAreas[0].props = "{
+ 4=16000
+ 3=F3
+ 7=#000000
+}"
+</screen>
+<variablelist>
+ <varlistentry>
+ <term>3</term>
+ <listitem>
+ <simpara><literal>org.apache.fop.area.Trait.FONT_NAME</literal></simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>4</term>
+ <listitem>
+ <simpara><literal>org.apache.fop.area.Trait.FONT_SIZE</literal></simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>7</term>
+ <listitem>
+ <simpara><literal>org.apache.fop.area.Trait.COLOR</literal></simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Block</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[1].flowAreas[0].[1] = {
+ stacking: 2
+ positioning: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 0
+ org.apache.fop.area.BlockParent.height: 14173
+ org.apache.fop.area.BlockParent.children: null
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 0
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Span</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[2] = {
+ flowAreas: instance of java.util.ArrayList(id=1429)
+ height: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[2].flowAreas = "[
+ org.apache.fop.area.Flow@c72243
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.Flow</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[2].flowAreas[0] = {
+ stacking: 2
+ width: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 0
+ org.apache.fop.area.BlockParent.height: 0
+ org.apache.fop.area.BlockParent.children: null
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Span</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[3] = {
+ flowAreas: instance of java.util.ArrayList(id=1433)
+ height: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[3].flowAreas = "[
+ org.apache.fop.area.Flow@dc9766
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.Flow</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[3].flowAreas[0] = {
+ stacking: 2
+ width: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 0
+ org.apache.fop.area.BlockParent.height: 0
+ org.apache.fop.area.BlockParent.children: null
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <para>Type: <literal>org.apache.fop.area.Span</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[4] = {
+ flowAreas: instance of java.util.ArrayList(id=1436)
+ height: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[4].flowAreas = "[
+ org.apache.fop.area.Flow@1ec58a
+]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.Flow</literal>:
+<screen>
+ curPage.page.regionBody.region.mainReference.spanAreas[4].flowAreas[0] = {
+ stacking: 2
+ width: 0
+ org.apache.fop.area.BlockParent.xOffset: 0
+ org.apache.fop.area.BlockParent.yOffset: 0
+ org.apache.fop.area.BlockParent.width: 0
+ org.apache.fop.area.BlockParent.height: 0
+ org.apache.fop.area.BlockParent.children: null
+ org.apache.fop.area.BlockParent.orientation: 0
+ org.apache.fop.area.Area.areaClass: 0
+ org.apache.fop.area.Area.ipd: 481891
+ org.apache.fop.area.Area.props: null
+}
+</screen>
+</para>
+
+ <screen>
+ curPage.page.regionBody.region.blocks = "[]"
+</screen>
+
+ <para>Type: <literal>org.apache.fop.area.CTM</literal>:
+<screen>
+ curPage.page.regionBody.region.ctm = {
+ a: 1.0
+ b: 0.0
+ c: 0.0
+ d: 1.0
+ e: 56692.0
+ f: 56692.0
+ CTM_LRTB: instance of org.apache.fop.area.CTM(id=1439)
+ CTM_RLTB: instance of org.apache.fop.area.CTM(id=1440)
+ CTM_TBRL: instance of org.apache.fop.area.CTM(id=1441)
+}
+</screen>
+</para>
+
+ </section>
+ </section>
+
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/fotree.xml b/src/documentation/content/xdocs/DnI/fotree.xml
new file mode 100644
index 000000000..d0b7e6cf1
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/fotree.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>Phase 1: Building the FO tree</title>
+
+ <section>
+ <title>Creating the FO nodes</title>
+
+ <para>FOP's first task is building a suitable data structure from
+the XML input, which is an XML file with formatting objects or a
+result tree with formatting objects from an XSLT transformation. One
+could call this FOP's data binding. The data structure is an FO tree,
+i.e., a tree of FONode objects. The structure of the FO tree exactly
+parallels the structure of the XML file or the corresponding DOM tree,
+but instead of XML nodes its nodes are objects of type
+<literal>org.apache.fop.fo.FONode</literal>. The FO tree is built on
+the basis of SAX parser events. The parser is responsible for parsing
+the XML document; it calls FOP's callbacks when SAX events
+occur.</para>
+
+ <para>FOP's callbacks are implemented by the
+<literal>FOTreeBuilder</literal> <literal>treebuilder</literal>
+object, which is a SAX content handler. It was constructed in the
+preparation phase, and registered with the parser as the content
+handler. It has meaningful implementations of the methods
+<literal>startDocument</literal>, <literal>endDocument</literal>,
+<literal>startElement</literal>, <literal>endElement</literal>, and
+<literal>characters</literal>.</para>
+
+ <para><literal>treebuilder</literal> delegates its
+<literal>startDocument</literal> and <literal>endDocument</literal>
+methods to its <literal>FOTreeHandler</literal> object
+<literal>foInputHandler</literal>. <literal>FOTreeHandler</literal> is
+a subclas of <literal>FOInputHandler</literal>.
+<screen>
+ treebuilder.foInputHandler = {
+ runtime: instance of java.lang.Runtime(id=635)
+ pageCount: 0
+ initialMemory: 0
+ startTime: 0
+ foTreeListeners: instance of java.util.HashSet(id=636)
+ org.apache.fop.fo.FOInputHandler.foTreeControl: instance of org.apache.fop.apps.Document(id=634)
+ org.apache.avalon.framework.logger.AbstractLogEnabled.m_logger: instance of org.apache.avalon.framework.logger.ConsoleLogger(id=342)
+}
+</screen></para>
+
+ <para>The first important task of <literal>treebuilder</literal> is
+creating a suitable FO node for each element in the XML document. This
+is done in its <literal>startElement</literal> method. Its most
+important tool in this process is its <literal>fobjTable</literal>
+object. <literal>fobjTable</literal> is a map of maps. For each
+namespace supported by FOP it contains a map of local XML element name
+to a Node maker object <literal>fobjMaker</literal>, of type
+<literal>ElementMapping.Maker</literal>. In addition to the FO
+namespace it contains makers for FOP's extensions namespace, the SVG
+namespace and Batik's extensions namespace.
+<screen>
+ treebuilder.fobjTable = "{
+ http://www.w3.org/1999/XSL/Format={
+ static-content=org.apache.fop.fo.FOElementMapping$SC@39e5b5,
+ table=org.apache.fop.fo.FOElementMapping$Ta@117f31e,
+ external-graphic=org.apache.fop.fo.FOElementMapping$EG@15a6029,
+ table-column=org.apache.fop.fo.FOElementMapping$TC@5f6303,
+ table-and-caption=org.apache.fop.fo.FOElementMapping$TAC@5d9084,
+ table-footer=org.apache.fop.fo.FOElementMapping$TB@bad8a8,
+ declarations=org.apache.fop.fo.FOElementMapping$Dec@e61fd1,
+ wrapper=org.apache.fop.fo.FOElementMapping$W@331059,
+ page-sequence=org.apache.fop.fo.FOElementMapping$PS@766a24,
+ single-page-master-reference=org.apache.fop.fo.FOElementMapping$SPMR@32784a,
+ footnote=org.apache.fop.fo.FOElementMapping$Foot@1774b9b,
+ multi-switch=org.apache.fop.fo.FOElementMapping$MS@104c575,
+ bidi-override=org.apache.fop.fo.FOElementMapping$BO@3fa5ac,
+ layout-master-set=org.apache.fop.fo.FOElementMapping$LMS@95cfbe,
+ float=org.apache.fop.fo.FOElementMapping$F@179dce4,
+ list-item=org.apache.fop.fo.FOElementMapping$LI@1950198,
+ basic-link=org.apache.fop.fo.FOElementMapping$BL@19bb25a,
+ multi-property-set=org.apache.fop.fo.FOElementMapping$MPS@da6bf4,
+ table-row=org.apache.fop.fo.FOElementMapping$TR@1e58cb8,
+ region-end=org.apache.fop.fo.FOElementMapping$RE@179935d,
+ block=org.apache.fop.fo.FOElementMapping$B@b9e45a,
+ leader=org.apache.fop.fo.FOElementMapping$L@3ef810,
+ table-header=org.apache.fop.fo.FOElementMapping$TB@100363,
+ list-item-body=org.apache.fop.fo.FOElementMapping$LIB@14e8cee,
+ multi-properties=org.apache.fop.fo.FOElementMapping$MP@67064,
+ region-after=org.apache.fop.fo.FOElementMapping$RA@bcda2d,
+ multi-case=org.apache.fop.fo.FOElementMapping$MC@97d01f,
+ block-container=org.apache.fop.fo.FOElementMapping$BC@e0a386,
+ title=org.apache.fop.fo.FOElementMapping$T@feb48,
+ retrieve-marker=org.apache.fop.fo.FOElementMapping$RM@11ff436,
+ color-profile=org.apache.fop.fo.FOElementMapping$CP@da3a1e,
+ character=org.apache.fop.fo.FOElementMapping$Ch@11dba45,
+ simple-page-master=org.apache.fop.fo.FOElementMapping$SPM@b03be0,
+ page-sequence-master=org.apache.fop.fo.FOElementMapping$PSM@2af081,
+ footnote-body=org.apache.fop.fo.FOElementMapping$FB@113a53d,
+ marker=org.apache.fop.fo.FOElementMapping$M@c5495e,
+ table-body=org.apache.fop.fo.FOElementMapping$TB@53fb57,
+ inline=org.apache.fop.fo.FOElementMapping$In@19a32e0,
+ table-cell=org.apache.fop.fo.FOElementMapping$TCell@8238f4,
+ list-block=org.apache.fop.fo.FOElementMapping$LB@16925b0,
+ region-start=org.apache.fop.fo.FOElementMapping$RS@297ffb,
+ table-caption=org.apache.fop.fo.FOElementMapping$TCaption@914f6a,
+ conditional-page-master-reference=org.apache.fop.fo.FOElementMapping$CPMR@1f4cbee,
+ list-item-label=org.apache.fop.fo.FOElementMapping$LIL@787d6a,
+ multi-toggle=org.apache.fop.fo.FOElementMapping$MT@71dc3d,
+ initial-property-set=org.apache.fop.fo.FOElementMapping$IPS@1326484,
+ repeatable-page-master-alternatives=org.apache.fop.fo.FOElementMapping$RPMA@16546ef,
+ repeatable-page-master-reference=org.apache.fop.fo.FOElementMapping$RPMR@1428ea,
+ flow=org.apache.fop.fo.FOElementMapping$Fl@18a49e0,
+ page-number=org.apache.fop.fo.FOElementMapping$PN@1f82982,
+ instream-foreign-object=org.apache.fop.fo.FOElementMapping$IFO@16d2633,
+ inline-container=org.apache.fop.fo.FOElementMapping$IC@e70e30,
+ root=org.apache.fop.fo.FOElementMapping$R@154864a,
+ region-before=org.apache.fop.fo.FOElementMapping$RBefore@3c9217,
+ region-body=org.apache.fop.fo.FOElementMapping$RB@9b42e6,
+ page-number-citation=org.apache.fop.fo.FOElementMapping$PNC@14520eb
+ },
+ http://xml.apache.org/fop/extensions={
+ bookmarks=org.apache.fop.fo.extensions.ExtensionElementMapping$B@1d7fbfb,
+ label=org.apache.fop.fo.extensions.ExtensionElementMapping$L@e020c9,
+ outline=org.apache.fop.fo.extensions.ExtensionElementMapping$O@888e6c
+ },
+ http://www.w3.org/2000/svg={
+ &lt;default&gt;=org.apache.fop.fo.extensions.svg.SVGElementMapping$SVGMaker@1742700,
+ svg=org.apache.fop.fo.extensions.svg.SVGElementMapping$SE@acb158
+ },
+ http://xml.apache.org/batik/ext={
+ &lt;default&gt;=org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping$SVGMaker@1af33d6,
+ batik=org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping$SE@17431b9
+ }
+ }"
+</screen></para>
+
+ <para>The values in this map are objects of subclasses of
+<literal>ElementMapping.Maker</literal>.
+<literal>ElementMapping.Maker</literal> is a static nested class of
+<literal>ElementMapping</literal>. It has no members and a single
+object method <literal>FONode make(FONode parent)</literal>. The
+subclasses are static nested classes of
+<literal>FOElementMapping</literal>. Each subclass has its own
+implementation of the <literal>make</literal> method, and returns its
+own subclass of FONode. For example,
+<literal>FOElementMapping$R</literal> returns a
+<literal>org.apache.fop.fo.pagination.Root</literal> object.</para>
+
+ <para><literal>treebuilder</literal> delegates its
+<literal>endElement</literal> method to the node's
+<literal>end</literal> method, which allows FOP to take appropriate
+action at the end of each FO element. The only node type whose
+<literal>end</literal> method takes special action, is
+<literal>org.apache.fop.fo.pagination.PageSequence</literal>. It hands
+control to FOP's next phase, building of the area tree.</para>
+
+ </section>
+
+ <section>
+ <title>Creating the property values</title>
+
+ <para>Formatting objects have many attributes by which the user
+may finetune their behaviour. When the FO tree is built, the
+attributes must be converted to properties. This conversion process
+must implement XSLT's sometimes complicated rules of default values,
+inheritance, shorthand notations etc. This is one of the tasks of the
+property subsystem, which is described in its own <link
+linkend="ch.properties">chapter</link>.</para>
+
+ </section>
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/getnextbreakposs.xml b/src/documentation/content/xdocs/DnI/getnextbreakposs.xml
new file mode 100644
index 000000000..96bd64390
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/getnextbreakposs.xml
@@ -0,0 +1,1227 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>Phase 2a: The <literal>getNextBreakPoss</literal> call
+tree</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para> <itemizedlist spacing="compact">
+ <listitem>
+ <para>Create a new layout context for the children.</para>
+ </listitem>
+ <listitem>
+ <para>Then process the flow: loop until the flow is exhausted
+(isFinished()): <itemizedlist spacing="compact">
+ <listitem>
+ <para>Get the next possible breakpoint (getNextBreakPoss).
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>Loop until the list of child layout
+managers is exhausted: <itemizedlist spacing="compact">
+ <listitem>
+ <para> Get a child layout manager
+(AbstractLayoutManager.getChildLM). The current child layout manager
+is returned until it is finished. Then the layout manager for the next
+child is returned.</para>
+ </listitem>
+ <listitem>
+ <para> Create a new layout context for
+the children.</para>
+ </listitem>
+ <listitem>
+ <para> If the child layout manager is
+not finished, get the next possible breakpoint
+(getNextBreakPoss).</para>
+ </listitem>
+ <listitem>
+ <para> If a breakpoint is returned,
+break the loop and return the breakpoint.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>This finishes a page.</para>
+ </listitem>
+ <listitem>
+ <para>Get the next possible breakpoint
+(getNextBreakPoss) (<emphasis>continued</emphasis>) <itemizedlist spacing="compact">
+ <listitem>
+ <para>Loop until the list of child layout
+managers is exhausted: (<emphasis>continued</emphasis>) <itemizedlist spacing="compact">
+ <listitem>
+ <para>Else if no breakpoint is returned,
+do the next cycle with the next child layout manager.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Mark the layout manager as finished (the
+list of child layout managers is exhausted).</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>At this point a complete (pseudo)tree of possible break
+points for a page has been collected.</para>
+
+ </section>
+
+ <section>
+ <title>How do layout managers get layout managers for the child
+FO nodes?</title>
+
+<para>Child layout managers are created and retrieved in the method
+<literal>AbstractLayoutManager.getChildLM</literal>.</para>
+
+<para>The layout manager has a layout strategy, which has an
+<literal>AddLMVisitor</literal> object, which is responsible for
+creating layout managers for the FO nodes.</para>
+
+<para>The layout manager gets the layout manager for its next child from its
+<literal>LMIter</literal> object <literal>childLMIter</literal>. This
+<literal>LMIter</literal> object contains an iterator over the
+children of the layout manager's FO node. It behaves itself as an
+iterator over the list of layout managers for the children. It
+constructs those layout managers when needed, in its
+<literal>preLoadNext</literal> method. It does so by calling the
+layout strategy's <literal>AddLMVisitor</literal> object's
+<literal>addLayoutManager</literal> method. The
+<literal>LMIter</literal> object gets the layout strategy via the
+current layout manager, which it knows.</para>
+
+<para><literal>AddLMVisitor</literal>'s <literal>addLayoutManager</literal>
+method first registers the LM list in its second argument, i.e. the
+<literal>LMIter</literal> object's LM list, as its own member
+<literal>currentLMlist</literal>. Then it asks the FO node to accept
+it as the <literal>FOTreeVisitor</literal>
+(<literal>acceptVisitor</literal>). The FO node then calls the
+appropriate method of this FO tree visitor, in this case
+(<literal>fo:flow</literal>) the method <literal>serveFlow</literal>
+(<literal>AddLMVisitor.serveFlow</literal>). This method creates a
+<literal>FlowLayoutManager</literal> object and adds it to the
+<literal>currentLMList</literal>. Thus <literal>LMIter</literal> has a
+layout manager for its next child. It returns this layout manager in
+the call to its <literal>next()</literal> method, when the current
+layout manager invokes its <literal>getChildLM</literal> method.</para>
+
+<para>Note that layout manager types may have their own subclass of
+<literal>LMIter</literal>,
+e.g. <literal>BlockLayoutManager$BlockLMiter</literal> and
+<literal>AbstractList$ListItr</literal>, which may implement a
+different method of creating child layout managers.</para>
+
+<para>The method <literal>acceptVisitor</literal> of the FO node calls the
+appropriate method of its visitor. This procedure effectively
+implements an indirect mapping from FO node type to layout
+manager. The indirection allows the <literal>AddLMVisitor</literal>
+object to return its own layout manager for each FO node type. Because
+the <literal>AddLMVisitor</literal> object is part of the layout
+strategy, this indirection allows the layout strategy to provide its
+own layout managers for the layout process. In this manner, a
+different layout strategy can be coupled to the other parts of the
+program.</para>
+
+<para>Note that <literal>AbstractLayoutManager.getChildLM</literal> itself
+does not behave as an iterator. The current child layout manager is
+returned until it is finished. One can safely make multiple calls to
+<literal>getChildLM</literal>. If the current child layout manager is
+unfinished and does nothing in between the calls, it remains
+unfinished, and is returned at every call. If the current child layout
+manager is finished, the next layout manager is loaded, and, because
+it is unfinished, returned at every call. If this is the last child
+layout manager and it is finished, then null is returned because in
+<literal>LMiter.preLoadNext</literal>
+<literal>baseIter.hasNext()</literal> returns false. The latter case
+is used in <literal>BlockLayoutManager.getNextBreakPoss</literal>.</para>
+
+<para>Stack trace: Creating a new layout manager for a child, in
+<literal>LMiter.preLoadNext</literal>, in
+<literal>AbstractLayoutManager.getChildLM</literal>:</para>
+
+<screen>
+ [1] org.apache.fop.layoutmgr.AbstractLayoutManager.&lt;init&gt; (AbstractLayoutManager.java:71)
+ [2] org.apache.fop.layoutmgr.BlockStackingLayoutManager.&lt;init&gt; (BlockStackingLayoutManager.java:70)
+ [3] org.apache.fop.layoutmgr.FlowLayoutManager.&lt;init&gt; (FlowLayoutManager.java:81)
+ [4] org.apache.fop.layoutmgr.AddLMVisitor.serveFlow (AddLMVisitor.java:894)
+ [5] org.apache.fop.fo.pagination.Flow.acceptVisitor (Flow.java:187)
+ [6] org.apache.fop.layoutmgr.AddLMVisitor.addLayoutManager (AddLMVisitor.java:198)
+ [7] org.apache.fop.layoutmgr.LMiter.preLoadNext (LMiter.java:88)
+ [8] org.apache.fop.layoutmgr.LMiter.hasNext (LMiter.java:77)
+ [9] org.apache.fop.layoutmgr.AbstractLayoutManager.getChildLM (AbstractLayoutManager.java:186)
+ [10] org.apache.fop.layoutmgr.PageLayoutManager.getNextBreakPoss (PageLayoutManager.java:253)
+ [11] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:228)
+</screen>
+
+ </section>
+
+ <section>
+ <title>Block layout managers and their child layout managers</title>
+
+<para>Block LMs are different in their treatment of their child LMs. For
+this purpose <literal>BlockLayoutManager</literal> defines a nested class <literal>BlockLMiter</literal>,
+which is a subclass of <literal>LMiter</literal>.</para>
+
+<para>A <literal>BlockLMiter</literal> object has a member called proxy,
+which is the basic <literal>LMiter</literal> over the children of the
+block. If the proxy produces a child LM that does not generate inline
+areas, the child LM is added to the list of child LMs as normal. But
+if the childLM generates an inline area, a new
+<literal>LineLayoutManager</literal> object is created
+(<literal>BlockLayoutManager.BlockLMiter.createLineManager</literal>). This
+LM asks the proxy to produce more child LMs. As long as these child
+LMs generate inline areas, they are collected by the
+<literal>LineLayoutManager</literal> object. Finally, the
+<literal>LineLayoutManager</literal> object creates its
+<literal>LMiter</literal> object as the
+<literal>ListIterator</literal> over the list of collected child LMs.</para>
+
+ </section>
+
+ <section>
+ <title>About <literal>getNextBreakPoss</literal> and the list of
+child layout managers</title>
+
+<para>Note that the breakpoint may come from a deeply nested child. Each
+layout manager keeps a reference to its current child layout
+manager. The whole list is descended again
+(<literal>getChildLM</literal>) at the next call to
+<literal>getNextBreakPoss</literal>.<warning>
+ <simpara>TO BE IMPROVED</simpara>
+ </warning>
+</para>
+
+<para>Stack of layout managers:
+ <variablelist>
+ <varlistentry>
+ <term><literal>PageSequence</literal></term>
+ <listitem>
+ <simpara><literal>PageLayoutManager</literal></simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Flow</literal></term>
+ <listitem>
+ <simpara><literal>FlowLayoutManager</literal></simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Block</literal></term>
+ <listitem>
+ <simpara><literal>BlockLayoutManager</literal></simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Block</literal></term>
+ <listitem>
+ <simpara><literal>LineLayoutManager</literal></simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>FOText</literal></term>
+ <listitem>
+ <simpara><literal>TextLayoutManager</literal></simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+For <literal>BlockLayoutManager</literal> and
+<literal>LineLayoutManager</literal> <literal>Block</literal> is the
+same, but their <literal>childLMIter</literal> are different:
+<literal>BlockLayoutManager$BlockLMiter</literal> vs
+<literal>AbstractList$ListItr</literal></para>
+
+<screen>
+ [1] org.apache.fop.layoutmgr.TextLayoutManager.getNextBreakPoss (TextLayoutManager.java:270)
+ [2] org.apache.fop.layoutmgr.LineLayoutManager.getNextBreakPoss (LineLayoutManager.java:212)
+ [3] org.apache.fop.layoutmgr.BlockLayoutManager.getNextBreakPoss (BlockLayoutManager.java:229)
+ [4] org.apache.fop.layoutmgr.FlowLayoutManager.getNextBreakPoss (FlowLayoutManager.java:111)
+ [5] org.apache.fop.layoutmgr.PageLayoutManager.getNextBreakPoss (PageLayoutManager.java:261)
+ [6] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:228)
+</screen>
+
+<para>A <literal>TextLayoutManager</literal>:
+<screen>
+ this = {
+ vecAreaInfo: instance of java.util.ArrayList(id=1062)
+ chars: instance of char[13] (id=1064)
+ textInfo: instance of org.apache.fop.fo.TextInfo(id=1065)
+ iAreaStart: 0
+ iNextStart: 0
+ ipdTotal: null
+ spaceCharIPD: 4448
+ hyphIPD: 5328
+ halfWS: instance of org.apache.fop.traits.SpaceVal(id=1066)
+ iNbSpacesPending: 0
+ org.apache.fop.layoutmgr.AbstractLayoutManager.userAgent: instance of org.apache.fop.apps.FOUserAgent(id=1067)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.parentLM: instance of org.apache.fop.layoutmgr.LineLayoutManager(id=1068)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.fobj: instance of org.apache.fop.fo.FOText(id=1069)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.foID: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.markers: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.bFinished: false
+ org.apache.fop.layoutmgr.AbstractLayoutManager.curChildLM: null
+ org.apache.fop.layoutmgr.AbstractLayoutManager.childLMiter: instance of org.apache.fop.layoutmgr.LMiter(id=1070)
+ org.apache.fop.layoutmgr.AbstractLayoutManager.bInited: true
+}
+</screen>
+</para>
+
+<para>Text in <literal>fo:text</literal> is handled by a
+<literal>TextLayoutManager</literal>. Two routines add the text and
+calculate the next possible break.</para>
+
+ </section>
+
+ <section>
+ <title><literal>LineLayoutManager.getNextBreakPoss</literal></title>
+
+ <section>
+ <title>Prepare for the main loop</title>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <simpara>Create a new empty list of possible line endings,
+<literal>vecPossEnd</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Retrieve the <literal>ipd</literal>
+<literal>availIPD</literal> from the layout context.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Create a new layout context (inline layout
+context) for the child layout managers, based on the layout context
+for this layout manager.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Clear the map of previous
+ <literal>ipd</literal>s.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Record the length of
+<literal>vecInlineBreaks</literal>, which we can use to find the last
+breakposs of the previous line.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Set <literal>prevBP</literal> to
+<literal>null</literal>; <literal>prevBP</literal> contains the last
+confirmed breakposs of this line.</simpara>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>The main loop over the list of child layout managers</title>
+
+ <para>Loop until the list of child layout managers is
+exhausted: <itemizedlist spacing="compact">
+ <listitem>
+ <para>Get a child layout manager
+(<literal>AbstractLayoutManager.getChildLM</literal>). The current
+child layout manager is returned until it is finished. Then the layout
+manager for the next child is returned.</para>
+ </listitem>
+ <listitem>
+ <para>Record the last breakposs.</para>
+ </listitem>
+ <listitem>
+ <para>Record whether the breakposs we are going to
+find is the first breakposs of this line.</para>
+ </listitem>
+ <listitem>
+ <para>Record whether it is the first breakposs of
+this child layout manager.</para>
+ </listitem>
+ <listitem>
+ <para>Initialize the inline layout context (note that
+it is not a new layout context, the same inline layout context is used
+by all child layout managers) (method
+<literal>InlineStackingLayout.initChildLC</literal>): <itemizedlist spacing="compact">
+ <listitem>
+ <para>Record whether this is a new area; it is a
+new area if this is the start of a new line or of a new child
+LM.</para>
+ </listitem>
+ <listitem>
+ <para>If this is the start of a new
+line <itemizedlist spacing="compact">
+ <listitem>
+ <para>record whether this is the first area
+of this child LM,</para>
+ </listitem>
+ <listitem>
+ <para>set the leading space as passed by
+argument.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else if this starts a new child
+LM <itemizedlist spacing="compact">
+ <listitem>
+ <para>record that this is the first area,</para>
+ </listitem>
+ <listitem>
+ <para>set the leading space from the previous
+BP.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else set the leading space to
+ <literal>null</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Record on the inline layout context whether
+leading space is supppressed; it is suppressed if this is the start of
+a new line, but not the start of this child LM, and the previous line
+was not ended by a forced break.</para>
+ </listitem>
+ <listitem>
+ <para>Retrieve the next breakposs from the current child
+LM (<literal>getNextBreakPoss</literal> method of child LM). If it is
+not <literal>null</literal>:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>Calculate the <literal>ipd</literal> up to
+the previous BP (method
+<literal>InlineStackingLayout.updatePrevIPD</literal>): <itemizedlist spacing="compact">
+ <listitem>
+ <para>Take an empty <literal>ipd</literal>
+ size.</para>
+ </listitem>
+ <listitem>
+ <para>If this starts a new line: <itemizedlist spacing="compact">
+ <listitem>
+ <para>if it has a leading fence, add
+leading space (?),</para>
+ </listitem>
+ <listitem>
+ <para>list the <literal>ipd</literal>
+for the LM of this BP in the map of previous
+<literal>ipd</literal>s.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else <itemizedlist spacing="compact">
+ <listitem>
+ <para>retrieve the
+<literal>ipd</literal> for the LM of this BP in the map of previous
+<literal>ipd</literal>s,</para>
+ </listitem>
+ <listitem>
+ <para>if that is
+<literal>null</literal> (first BP of this child LM) <itemizedlist spacing="compact">
+ <listitem>
+ <para>retrieve the
+<literal>ipd</literal> for the LM of the previous BP in the map of
+previous <literal>ipd</literal>s,</para>
+ </listitem>
+ <listitem>
+ <para>add the leading space
+of this BP,</para>
+ </listitem>
+ <listitem>
+ <para>add the pending space-end
+(stacking size) of the previous BP,</para>
+ </listitem>
+ <listitem>
+ <para>list the
+<literal>ipd</literal> for the LM of this BP in the map of previous
+<literal>ipd</literal>s.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Add to the <literal>ipd</literal> the
+pending space-end (stacking size) of this BP.</para>
+ </listitem>
+ <listitem>
+ <para>Record whether this BP could end the
+line: <itemizedlist spacing="compact">
+ <listitem>
+ <para>if a break may occur after this BP,
+record true;</para>
+ </listitem>
+ <listitem>
+ <para>else if this BP is suppressible at a
+line break, return false;</para>
+ </listitem>
+ <listitem>
+ <para>else, return whether this is the last
+child LM and it is finished, or the next area could start a new
+line.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If this BP could end the line, add trailing
+space.</para>
+ </listitem>
+ <listitem>
+ <para>If this BP exceeds the line length
+(<literal>bpDim.min > availIPD.max</literal>), <itemizedlist spacing="compact">
+ <listitem>
+ <para>if the text should be justified or if
+this is the first BP of this line, <itemizedlist spacing="compact">
+ <listitem>
+ <para>if we are in a hyphenation try,
+break the loop; we have exhausted our options and one of the previous
+BPs should end the line (<literal>_exit of loop_</literal>);</para>
+ </listitem>
+ <listitem>
+ <para>if this BP could not end the
+line, add it to the list of inline breaks, and continue with the next
+iteration;</para>
+ </listitem>
+ <listitem>
+ <para>prepare to hyphenate: get the
+hyphenation context for the text between the last and this BP (method
+<literal>getHyphenContext</literal>): <itemizedlist spacing="compact">
+ <listitem>
+ <para>add this BP to the list of
+inline breaks; even though this is not a good BP, we add it to the
+list, so that we can retrieve the text between the last and this
+BP;</para>
+ </listitem>
+ <listitem>
+ <para>iterate back to the
+previous BP in this list;</para>
+ </listitem>
+ <listitem>
+ <para>loop over the following
+BPs in this list: <itemizedlist spacing="compact">
+ <listitem>
+ <para>retrieve the text
+between the preceding and this BP.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>remove this BP again from
+the list of inline breaks.</para>
+ </listitem>
+ <listitem>
+ <para>create a hyphenation
+object for the retrieved text, taking the language, country and other
+hyphenation properties into account.</para>
+ </listitem>
+ <listitem>
+ <para>create a hyphenation
+context object from it, and return that.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>store the hyphenation context
+with the inline layout context.</para>
+ </listitem>
+ <listitem>
+ <para>Record on the inline layout
+context that we are in a hyphenation try.</para>
+ </listitem>
+ <listitem>
+ <para>reset the child LMs to the
+previous BP or to the start of the line.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else (if text should not be justified
+and if this is not the first BP of this line) break the loop; one of
+the previous BPs should end the line (<literal>_exit of
+loop_</literal>);</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else (if this BP does not exceed the line
+length): <itemizedlist spacing="compact">
+ <listitem>
+ <para>add this BP to the list of inline
+breaks,</para>
+ </listitem>
+ <listitem>
+ <para>if this BP could end the line,
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>record it as the last confirmed
+BP: set prevBP to this BP.</para>
+ </listitem>
+ <listitem>
+ <para>if this BP is a forced line
+break, break the loop; this BP (or one of the previous BPs?) should
+end the line (<literal>_exit of loop_</literal>).</para>
+ </listitem>
+ <listitem>
+ <para>if this BP may fill the line
+length (<literal>bpDim.max >= availIPD.min</literal>), add it to the
+list of possible line endings, <literal>vecPossEnd</literal>, with a
+cost which is equal to the difference of the optimal values of the
+content length and the line length (<literal>Math.abs(availIPD.opt -
+bpDim.opt)</literal>).</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If we are in a hypenation try, and the hyphenation
+context has no more hyphenation points, break the loop; this or one of
+the previous BPs should end the line (<literal>_exit of
+loop_</literal>).</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>After the main loop</title>
+
+ <para>There are five exit points of the main loop: <orderedlist>
+ <listitem>
+ <simpara>The last BP in the hyphenation try has exceeded
+the line length.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>The last BP has exceeded the line length, and
+we cannot get a hyphenation context.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>The last BP has exceeded the line length, and
+we do not hyphenate.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>The last BP has not exceeded the line length
+but forces a line break.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>We have run out of hyphenation points (and the
+last BP has not exceeded the line length).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Natural end of the while loop: we are through
+the list of child layout managers.</simpara>
+ </listitem>
+ </orderedlist></para>
+
+<para>If the last BP has exceeded the line length, it is not in the
+list of inline breaks, and prevBP points to the last good break;
+otherwise it is in the list of inline breaks, and prevBP points to
+it.</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>If we are through the list of child LMs, mark this
+ LM as finished.</para>
+ </listitem>
+ <listitem>
+ <para>If no BP was produced, return
+<literal>null</literal>. (This should concur with being
+finished?)</para>
+ </listitem>
+ <listitem>
+ <para>If prevBP is <literal>null</literal>, there is not
+last good break; set it to this BP, even though it fails some
+criteria: <itemizedlist spacing="compact">
+ <listitem>
+ <para>it has exceeded the line length in the
+hyphenation try or we cannot get a hyphenation context,</para>
+ </listitem>
+ <listitem>
+ <para>or it cannot end the line but it is the last
+BP of the last child layout manager.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If this BP is not a forced break, and there are
+several possible line breaks, select the best one; make
+<literal>prevBP</literal> point to it. (Could this produce the wrong
+result if the BP has exceeded the line length and at the same time is
+a forced line break? Should <literal>prevBP</literal> be tested for
+being a forced break instead?)</para>
+ </listitem>
+ <listitem>
+ <para>If the last BP is not the actual breakpoint
+<literal>prevBP</literal> (<literal>bp != prevBP</literal>) and the
+material after <literal>prevBP</literal> is not suppressible at the
+end of a line, back up to <literal>prevBP</literal> for a proper start
+of the next line.</para>
+ </listitem>
+ <listitem>
+ <para>If the text should be justified and the breakpoint
+is a forced line break (here <literal>prevBP</literal> is tested) or
+this is the last line of the layout manager, set text alignment to
+left-aligned.</para>
+ </listitem>
+ <listitem>
+ <para>Make a line break and return the associated
+ breakposs.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title><literal>LineLayoutManager.makeLineBreak</literal></title>
+
+ <para>Arguments are: <itemizedlist spacing="compact">
+ <listitem>
+ <para>index in <literal>vecInlineBreaks</literal> of
+ line breaking BP of last line,</para>
+ </listitem>
+ <listitem>
+ <para>target line length,</para>
+ </listitem>
+ <listitem>
+ <para>type of text alignment.</para>
+ </listitem>
+ </itemizedlist></para>
+
+<para>Calculate line dimensions. The Line LayoutManager contains the
+parameters <literal>lineHeight</literal>, <literal>lead</literal> and
+<literal>follow</literal> as members, which it received from its Block
+LayoutManager parent at construction. The Blo ckLayoutManager contains
+these parameters as members as well, and has received them from a
+<literal>TextInfo</literal> object in the method set
+<literal>BlockTextInfo</literal>. The <literal>TextInfo</literal>
+object has a reference to the <literal>Font</literal>
+object. <literal>lead</literal> is the font ascender,
+<literal>follow</literal> is the font descender.</para>
+
+<para>The leading is the difference between
+<literal>lineHeight</literal> and font height = ascender +
+descender. The leading is split in two halves, one for above, the
+other for below the line. The variable <literal>lineLead</literal> is
+calculated as the distance from the baseline to the top of the line,
+the variable <literal>maxtb</literal> is calculated as the distance
+from the baseline to the bottom of the line. The variable
+<literal>middlefollow</literal> set equal to <literal>maxtb</literal>.
+These parameters correspond to the members <literal>lead</literal>,
+<literal>total</literal> and <literal>follow</literal> of the
+breakposs. <warning>
+ <simpara>Find out the exact meaning of these.</simpara>
+ </warning></para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>Loop over the breakposs in
+ <literal>vecInlineBreaks</literal>: <itemizedlist spacing="compact">
+ <listitem>
+ <para>adjust <literal>lineLead</literal>,
+<literal>maxtb</literal> and <literal>middlefollow</literal> if the
+corresponding dimension of the BP is larger;</para>
+ </listitem>
+ <listitem>
+ <para>add the <literal>ipd</literal>s; a BP does
+not just hold the <literal>ipd</literal> of the area since the
+previous BP, but the cumulative <literal>ipd</literal> for all the
+areas contributed by its layout manager; therefore care is taken to
+add only the <literal>ipd</literal> of the last BP of each LM; more
+precisely, the <literal>ipd</literal> of the last BP of the previous
+LM is added when the next LM is encountered;</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Add the <literal>ipd</literal> of the last BP.</para>
+ </listitem>
+ <listitem>
+ <para>Resolve the trailing space of the last BP.</para>
+ </listitem>
+ <listitem>
+ <para>Adjust <literal>middlefollow</literal> if it is
+smaller than <literal>maxtb - lineHeight</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>Calculate the stretch or shrink factor
+<literal>ipdAdjust</literal> for the stretch- and shrinkable elements
+in this line: <itemizedlist spacing="compact">
+ <listitem>
+ <para>if content optimum is larger than line
+ length optimum, <itemizedlist spacing="compact">
+ <listitem>
+ <para>if content minimum is smaller than
+ line length optimum, <itemizedlist spacing="compact">
+ <listitem>
+ <para>calculate
+<literal>ipdAdjust</literal> between 0 and -1, real line length = line
+length optimum,</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>else (content minimum is larger than
+ line length optimum) <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>ipdAdjust =
+-1</literal>, real line length = content minimum,</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>else (content optimum is smaller than line
+ length optimum), <itemizedlist spacing="compact">
+ <listitem>
+ <para>if content maximum is larger than line
+ length optimum, <itemizedlist spacing="compact">
+ <listitem>
+ <para>calculate
+<literal>ipdAdjust</literal> between 0 and 1, real line length = line
+length optimum,</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>else (content maximum is smaller than
+ line length optimum), <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>ipdAdjust =
+1</literal>, real line length = content maximum.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Calculate the stretch or shrink factor
+<literal>dAdjust</literal> for white space and the indent:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>justify: calculate
+<literal>dAdjust</literal>,</para>
+ </listitem>
+ <listitem>
+ <para>center or end: calculate the required
+ indent.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Create a new <literal>LineBreakPosition</literal>
+based on this LM, the last BP in <literal>vecInlineBreaks</literal>
+and the calculated dimensions; use <literal>lineLead</literal> for the
+baseline position and <literal>lineLead + middlefollow</literal> for
+the <literal>lineHeight</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>Create a <literal>BreakPoss</literal> from this
+ <literal>LineBreakPosition</literal> object.</para>
+ </listitem>
+ <listitem>
+ <para>Mark the BP as last if this LM is finished.</para>
+ </listitem>
+ <listitem>
+ <para>Set the stacking size of the BP
+(<literal>bpd</literal>) equal to <literal>lineLead +
+middlefollow</literal>.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Line LayoutManager, a sequence of breakposs</title>
+
+<para>The text is: "waterstaatsingenieur ministersportefeuille
+aandachtstrekker. Vernederlandste vakliteratuur" etc. It consists of a
+few long Dutch words, which can be found in the hyphenation exceptions
+in <filename>nl.xml</filename>. The column width is 8cm. This text and
+width have been chosen so that they force many hyphenations.</para>
+
+<para>This text is contained in a single <literal>FOText</literal>
+node, and is dealt with by a single Text LayoutManager, which is a
+child layout manager for the Line LayoutManager. The Text
+LayoutManager maintains a list of area information objects,
+<literal>vecAreaInfo</literal>, and the Line LayoutManager maintains a
+list of breakposs, <literal>vecInlineBreaks</literal>. Each breakposs
+refers to an area, in its <literal>position.iLeafPos</literal>
+member.</para>
+
+<para>During the process of finding suitable line breaks, breakposs
+are generated until one is found that exceeds the line length. Then
+the Line LayoutManager backs up to the previous BP, either to start a
+hyphenation try or to create the line break. When it creates a line
+break, the last breakposs, which exceeds the line length, is not added
+to the list of inline breaks. When it starts a hyphenation try, the
+breakposs is added to that list, and removed again after the text for
+hyphenation has been obtained. Each time, the corresponding area info
+is left in the list of area information objects. As a consequence the
+list <literal>vecAreaInfo</literal> is longer than the list
+<literal>vecInlineBreaks</literal>, and some areas have no
+corresponding breakposs.</para>
+
+<screen>
+wa-ter-staats-in-ge-nieur mi-nis-ters-por-te-feuil-le aandachtstrekker.
+0 2 5 1 1 1 2 2 2 2 3 3 3 4 4 6
+ 1 3 5 0 3 6 9 0 3 5 0 2 0
+
+text: waterstaatsingenieur wa ter staats in |
+AreaInfo: 0: 0-20 (removed) 0: 0-2 1: 2-5 2: 5-11 3: 11-13 |
+InlineBreaks: 0 (removed) 0 1 2 3 |
+ too long, hyphenate, |
+ back up V
+
+gen genieur _ministersportefeuille _mi nis |
+4: 13-15 5: 13-20 6: 20-42 7: 20-23 8: 23-26 |
+ 4 5 (removed) 5 6 |
+too long, too long, hyphenate |
+line break, back up |
+back up v
+
+ters tersportefeuille_ ter s por
+9: 26-30 10: 26-42 11: 26-29 12: 29-30 13: 30-33
+ 7 (removed) 7 8 9
+too long, too long, hyphenate, hyphenation
+line break, back up error
+back up
+
+te feuil | le | _aandachtstrekker.
+14: 33-35 15: 35-40 | 16: 40-42 | 17: 42-60
+10 11 | 12 | 13 (removed)
+ last hyphenpoint, | | too long,
+ line break v | hyphenation fails,
+ | line break,
+ v back up
+
+aandachtstrekker. | etc.
+18: 43-60 |
+13 |
+too long, |
+hyphenation fails, |
+first BP, |
+line break v
+</screen>
+
+<para>A few remarkable points: <orderedlist>
+
+<listitem>
+<simpara>The first AreaInfo object is removed from the list during backing
+ up. This is because the previous BP, which is
+ <literal>null</literal>, does not belong to this child layout
+ manager, and therefore the whole child LM is reset.</simpara>
+</listitem>
+
+<listitem>
+<simpara>The last BP, no. 18, exceeds the line length, but because it is the
+ first BP of this line, it is accepted for the line break.</simpara>
+</listitem>
+
+<listitem>
+<simpara>BP 7 at position 29 falls at a point that is not a good hyphenation
+ point. This is probably caused by the fact that for this line only
+ the partial word is subjected to hyphenation. On the previous line
+ the complete word was subjected to hyphenation, and there was no BP
+ at position 29.</simpara>
+</listitem>
+
+<listitem>
+<simpara>For the word "aandachtstrekker." hyphenation fails
+ (<literal>hyph == null</literal> is returned). This may be due to
+ the period not being separated from the word. When the period is
+ removed, the word is properly broken.</simpara>
+</listitem>
+ </orderedlist></para>
+ </section>
+
+ <section>
+ <title><literal>TextLayoutManager.getNextBreakPoss</literal></title>
+
+ <para> <itemizedlist spacing="compact">
+ <listitem>
+ <para>If this is the first call to this Text
+LayoutManager, initialize <literal>ipdTotal</literal> and record that
+this breakposs is the first in <literal>iFlags</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>If leading spaces must be suppressed, suppress all
+leading space characters <literal>U+20</literal>. Return if this
+finished the text.</para>
+ </listitem>
+ <listitem>
+ <para>For the remaining leading space characters,
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>If this is a space <literal>U+20</literal>
+ or a non-breaking space <literal>U+A0</literal>,
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>count it;</para>
+ </listitem>
+ <listitem>
+ <para>if this is the first character and this
+ is the first breakposs, <itemizedlist spacing="compact">
+ <listitem>
+ <para>if the context has leading spaces,
+add it (or <literal>halfWS</literal>?);</para>
+ </listitem>
+ <listitem>
+ <para>else add it (or
+<literal>halfWS</literal>?) to the pending space, and add the pending
+space to the <literal>space</literal> ipd.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>add the space width to the word
+<literal>ipd</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>set the pending space to
+ <literal>halfWS</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>if this is a non-breaking space
+<literal>U+A0</literal>, register it in
+<literal>bSawNonSuppressible</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else (other space characters), <itemizedlist spacing="compact">
+ <listitem>
+ <para>register it in
+ <literal>bSawNonSuppressible</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>add the pending space to the space
+<literal>ipd</literal>, and clear the pending space.</para>
+ </listitem>
+ <listitem>
+ <para>add the character width to the word
+ <literal>ipd</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If this finishes the text, <itemizedlist spacing="compact">
+ <listitem>
+ <para>register whether there were any
+nonsuppressible spaces (<literal>bSawNonSuppressible</literal>) in
+<literal>iFlags</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>pass all the info to
+ <literal>makeBreakPoss</literal> and
+ <literal>_return_</literal> its breakposs.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else, <itemizedlist spacing="compact">
+ <listitem>
+ <para>add pending space.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If hypenation is on, get the size of the next
+ syllable: <itemizedlist spacing="compact">
+ <listitem>
+ <para>get the size of the next syllable,
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>if successful, add the flags
+<literal>BreakPoss.CAN_BREAK_AFTER</literal> and
+<literal>BreakPoss.CAN_BREAK_AFTER</literal> in
+<literal>iFlags</literal>,</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>add the syllable length to the word
+ <literal>ipd</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else look for a legal line-break: breakable
+white-space and certain characters such as '-' which can serve as word
+breaks; don't look for hyphenation points here though, <itemizedlist spacing="compact">
+ <listitem>
+ <para>for all following characters: <itemizedlist spacing="compact">
+ <listitem>
+ <para>If this is a newline character
+<literal>U+0A</literal>, or if <literal>textInfo.bWrap</literal> and
+this is a breakable space, or if this is one of the linebreak
+characters ("-/") and it is the first character or the preceding
+character is a letter or a digit, <itemizedlist spacing="compact">
+ <listitem>
+ <para>add the flag
+<literal>BreakPoss.CAN_BREAK_AFTER</literal> to
+<literal>iFlags</literal>,</para>
+ </listitem>
+ <listitem>
+ <para>if this is not a space
+ <literal>U+20</literal>, <itemizedlist spacing="compact">
+ <listitem>
+ <para>move the counter to the next
+ character,</para>
+ </listitem>
+ <listitem>
+ <para>if this is a newline
+<literal>U+0A</literal>, add the flag
+<literal>BreakPoss.FORCE</literal> to
+<literal>iFlags</literal>,</para>
+ </listitem>
+ <listitem>
+ <para>else add the character width
+to the word <literal>ipd</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>if the rest of the text consists
+of spaces <literal>U+20</literal>, register that the rest is
+suppressible at a line break
+(<literal>BreakPoss.REST_ARE_SUPPRESS_AT_LB</literal>) in
+<literal>iFlags</literal>,</para>
+ </listitem>
+ <listitem>
+ <para>pass all the info to
+<literal>makeBreakPoss</literal> and <literal>_return_</literal> its
+breakposs.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else add the character width to the word
+ <literal>ipd</literal>,</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>and continue with the cycle for the next
+ character.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>At the end of the text, pass all the info to
+<literal>makeBreakPoss</literal> and <literal>_return_</literal> its
+breakposs.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title><literal>TextLayoutManager.makeBreakPoss</literal></title>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>Make word <literal>ipd</literal> into a
+ <literal>MinOptMax</literal> object.</para>
+ </listitem>
+ <listitem>
+ <para>Add space <literal>ipd</literal> to it.</para>
+ </listitem>
+ <listitem>
+ <para>Add total <literal>ipd</literal> from previous texts
+ to it.</para>
+ </listitem>
+ <listitem>
+ <para>Create an <literal>AreaInfo</literal> object for this
+text fragment and add it to the vector of <literal>AreaInfo</literal>
+objects.</para>
+ </listitem>
+ <listitem>
+ <para>Create a breakposs for this text fragment.</para>
+ </listitem>
+ <listitem>
+ <para>Set the total <literal>ipd</literal> to the current
+ <literal>ipd</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>If the flags contain
+<literal>BreakPoss.HYPHENATED</literal>, set the stacking size to the
+<literal>ipd</literal> plus the width of the hyphen character,</para>
+ </listitem>
+ <listitem>
+ <para>Else set the stacking size to the
+ <literal>ipd</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>Set the non-stacking size to the line height, from the
+ text info.</para>
+ </listitem>
+ <listitem>
+ <para>Register the descender and ascender with the breakposs
+object; this is currently commented out.</para>
+ </listitem>
+ <listitem>
+ <para>If this is the end of the text, <itemizedlist spacing="compact">
+ <listitem>
+ <para>add <literal>BreakPoss.ISLAST</literal> to the
+ flags,</para>
+ </listitem>
+ <listitem>
+ <para>declare the LM finished.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Register the flags with the breakposs object</para>
+ </listitem>
+ <listitem>
+ <para>Register the pending space or the absence thereof with
+the breakposs object.</para>
+ </listitem>
+ <listitem>
+ <para>Register the leading space or the absence thereof with
+the breakposs object.</para>
+ </listitem>
+ <listitem>
+ <para>Return the breakposs object.</para>
+ </listitem>
+ </itemizedlist>
+
+ </section>
+
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/overview.xml b/src/documentation/content/xdocs/DnI/overview.xml
new file mode 100644
index 000000000..aff1bc6c3
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/overview.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+
+ <title>Overview</title>
+
+ <para>A FOP process has three stages:<orderedlist>
+ <listitem>
+ <simpara> building the FO tree,</simpara>
+ </listitem>
+ <listitem>
+ <simpara>building the Area tree,</simpara>
+ <orderedlist numeration="loweralpha">
+ <listitem>
+ <simpara>The getNextBreakPoss call tree</simpara>
+ </listitem>
+ <listitem>
+ <simpara>The addAreas call tree</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Finishing the page</simpara>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ <listitem>
+ <simpara>rendering the pages.</simpara>
+ </listitem>
+ </orderedlist></para>
+
+<para>These stages are preceded by two other stages:<itemizedlist>
+ <listitem>
+ <simpara>0. <emphasis>preparation:</emphasis> the objects for
+the FOP process are constructed; this phase may be done by FOP (apps
+package), or by the calling application;</simpara>
+ </listitem>
+ <listitem>
+ <simpara>X. <emphasis>parsing:</emphasis> this phase is done
+by a SAX parser; FOP's own preparation stage uses a JAXP
+SAXParserFactory to call an available SAX parser.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><emphasis>Stage 0.</emphasis> The preparation stage occurs
+before the other stages. When it is completed it starts the parsing
+stage by calling the parser's <literal>parse</literal> method.</para>
+
+ <para>The parsing stage and stages 1, 2, 3 run concurrently. Each stage
+calls into the following stage at appropriate points in its
+process. It is feasible that stages 2 and 3 will run in separate
+threads.</para>
+
+ <para><emphasis>Stage X.</emphasis> The parser now takes control.
+It parses the FO document or walks over the DOM tree. When it
+encounters XML events such as the start or end of the document, the
+start or end of an XML element, or character data, it makes a call
+back into the FO tree builder.</para>
+
+ <para><emphasis>Stage 1.</emphasis> The FO tree builder now takes
+control to create or finish the FO node for which the XML event was
+fired. When it is done, it returns control to the parser.</para>
+
+ <para>The end events of a few XML elements invoke further actions
+of the FO tree builder. When a page-sequence FO node is finished, the
+FO tree builder notifies its tree listeners (of which there usually is
+only one, the Area tree builder) of this event. Each listener in turn
+takes control to process the page sequence.</para>
+
+ <para><emphasis>Stage 2.</emphasis> The Area tree builder (which
+is the tree listener) now takes control to lay out the page sequence
+and construct the Area tree for it. This stage is divided in three
+substages.</para>
+
+ <para><emphasis>Stage 2a.</emphasis> The (pseudo)tree of possible
+break points is created. Each node in the FO tree creates a Layout
+Manager of the appropriate type. The resulting tree of Layout Managers
+is recursed. Each Layout Manager asks each of its child Layout
+Managers in turn to return a possible break point, until all child
+Layout Managers are finished. This process is started by the Page
+Layout Manager, which is tied to the page-sequence FO node that was
+just completed in stage 1. Each time when its current child Layout
+Manager returns a possible break point, a complete (pseudo)tree of
+possible break points for a page has been collected. The next
+substage takes control.</para>
+
+ <para><emphasis>Stage 2b.</emphasis> Now the area tree is
+created. The (pseudo)tree of possible break points and their Layout
+Managers is recursed. Each possible break point may create an area. It
+then calls the possible break points of the child LM that fall in this
+area, to create and return their area, and adds those areas to its own
+area. This process is started by the Page Layout Manager after the
+previous substage has finished. When its possible break point returns
+its area, the area tree for the flow of the page is complete.</para>
+
+ <para><emphasis>Stage 2c.</emphasis> The Page Layout Manager adds
+the static areas and hands the page to the Area tree builder, which
+adds it to the root area. The Area tree builder now inspects the set
+of complete pages, and fills in forward references to the page just
+finished. Pages which are now complete including the forward
+references contained in them, are handed over to the renderer, which
+now takes control. When the renderer returns control, the Page Layout
+Manager starts again in stage 2a to lay out the next page in the page
+sequence.</para>
+
+ <para>When all pages of this page sequence are done, this stage
+finishes, and the Area tree builder returns control to the FO tree
+builder.</para>
+
+ <para><emphasis>Stage 3.</emphasis> The renderer now takes control
+to render the finished pages. When it is done with those pages, it
+returns control to the Area tree builder.</para>
+
+ <para>This process model is FOP's default process model. It is
+completely configurable, through the objects constructed in the
+preparation stage. Stage 1 is configured by the content handler that
+is registered with the parser. Stage 2 is configured by the listeners
+that are registered with the FO tree builder. The layout process in
+stage 2 is also configured by the layout strategy that is registered
+with the Area tree builder. [It might be more appropriate to say that
+stage 2 is controlled by the tree control object. The actual Area tree
+builder is assigned by the layout strategy.] Stage 3 is configured by
+the selected renderer or output format.</para>
+
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/preparation.xml b/src/documentation/content/xdocs/DnI/preparation.xml
new file mode 100644
index 000000000..e34b5452a
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/preparation.xml
@@ -0,0 +1,470 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter>
+ <title>Phase 0: Preparation</title>
+
+ <para>This chapter describes the structure of FOP as it was in the
+first quarter of 2004. In the second quarter of that year the top
+level structure was strongly refactored. The new situation is not
+described here.</para>
+
+ <section>
+ <title>The preparation process</title>
+
+ <para>FOP's processing model is the SAX parsing model:<itemizedlist>
+ <listitem>
+ <simpara>Construct a suitable content handler object of type
+<literal>org.xml.sax.ContentHandler</literal>,</simpara>
+ </listitem>
+ <listitem>
+ <simpara>create a parser of type
+<literal>org.xml.sax.XMLReader</literal>,</simpara>
+ </listitem>
+ <listitem>
+ <simpara>register the content handler with the parser,</simpara>
+ </listitem>
+ <listitem>
+ <simpara>call the parser's parse method on the input
+source.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>From there on the parser takes control. For every XML
+event it passes control to the appropriate content handler methods.
+When these methods return, parsing continues until the next XML event
+is encountered. Once the parser has taken control, its content handler
+is the only entry point into FOP's data structures and methods.</para>
+
+ <para>The preparatory phase of FOP concerns itself with the
+construction of a suitable content handler object, whose methods allow
+FOP's process to handle the FO elements reported by the parser and
+build the required output document.</para>
+
+ <para>An application may choose to deal with the whole
+preparatory phase itself, and then call the parser's
+<literal>parse</literal> method.</para>
+
+ <para>The input source may be an FO file, which may be fed to
+the <literal>parse</literal> method as a string or as an
+<literal>org.xml.sax.InputSource</literal> object. Alternatively, a
+DOM document object may be used as input, e.g. the output of an XSLT
+processor. In that case:<itemizedlist>
+ <listitem>
+ <simpara> the parser should be of type
+<literal>org.apache.fop.tools.DocumentReader</literal>,</simpara>
+ </listitem>
+ <listitem>
+ <simpara>the input source should be of type
+<literal>org.apache.fop.tools.DocumentInputSource</literal>, created
+with the DOM document as the argument of the constructor.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The classes <literal>Fop</literal> and
+<literal>Driver</literal> contain methods which applications may use
+as more convenient entry points into FOP.</para>
+
+ <para>The method <literal>Fop.main</literal> may be called with
+the input and output file names as arguments. This is mainly useful
+for starting Fop from the command line.</para>
+
+ <para>The class <literal>Driver</literal> contains a method
+<literal>getContentHandler</literal>, which can be used to create a
+suitable content handler. It also contains three
+<literal>render</literal> methods which are convenient entry points
+for applications.</para>
+
+ <para>These 4 methods may be invoked on a driver object which
+already has the following members: <literal>userAgent</literal>,
+<literal>renderer</literal>, <literal>log</literal>,
+<literal>stream</literal>. In addition, the driver object may have the
+following members: a <literal>TreeBuilder</literal> object having a
+member <literal>userAgent</literal>, and a <literal>Document</literal>
+object, which may have a member <literal>layoutStrategy</literal>.
+Using one's own <literal>TreeBuilder</literal> and
+<literal>Document</literal> objects allows one to customize FOP's
+behaviour in a major way.</para>
+
+ <para>The <literal>render</literal> methods invoke
+<literal>getContentHandler</literal> to create a suitable content
+handler. They register it as the content handler of the parser. They
+register the member <literal>currentDocument</literal> as a tree
+listener to the member <literal>foInputHandler</literal>.</para>
+
+ <para>A suitable <literal>org.xml.sax.ContentHandler</literal>
+object for FOP processing is an object of type
+<literal>org.apache.fop.fo.FOTreeBuilder</literal> and has the
+following structure:
+<screen>
+ treeBuilder
+ |
+ +--------------+------------------+
+ | | |
+foInputHandler userAgent foTreeControl
+ | |
+foTreeControl driver
+foTreeListeners: usedFonts
+ [foTreeControl] triplets
+ fonts
+ layoutStrategy -- foTreeControl
+ areaTree -- atModel, foTreeControl
+ atModel -- renderer
+ foInputHandler
+</screen>
+</para>
+
+ <para>The <literal>driver</literal> and
+<literal>renderer</literal> objects are complex objects:
+<screen>
+ driver renderer
+ | |
+ treeBuilder foTreeControl
+ renderer userAgent
+ foInputHandler fontList
+ ostream ostream
+ userAgent
+ foTreeControl
+</screen>
+</para>
+
+ </section>
+
+ <section>
+ <title>A detailed overview of the objects</title>
+
+ <screen>
+ treeBuilder = {
+ fobjTable: instance of java.util.HashMap(id=589)
+ namespaces: instance of java.util.HashSet(id=590)
+ currentFObj: null
+ rootFObj: null
+ foInputHandler: instance of org.apache.fop.fo.FOTreeHandler(id=591)
+ userAgent: instance of org.apache.fop.apps.FOUserAgent(id=592)
+ foTreeControl: instance of org.apache.fop.apps.Document(id=593)
+ class$org$apache$fop$fo$ElementMapping: instance of java.lang.Class(reflected class=org.apache.fop.fo.ElementMapping, id=450)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foInputHandler = {
+ collectStatistics: true
+ MEM_PROFILE_WITH_GC: false
+ runtime: instance of java.lang.Runtime(id=595)
+ pageCount: 0
+ initialMemory: 0
+ startTime: 0
+ foTreeListeners: instance of java.util.HashSet(id=596)
+ org.apache.fop.fo.FOInputHandler.foTreeControl: instance of org.apache.fop.apps.Document(id=593)
+ org.apache.avalon.framework.logger.AbstractLogEnabled.m_logger: instance of org.apache.avalon.framework.logger.ConsoleLogger(id=597)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl = "org.apache.fop.apps.Document@125844f"
+ treeBuilder.foInputHandler.foTreeListeners = "[org.apache.fop.apps.Document@125844f]"
+</screen>
+
+ <screen>
+ treeBuilder.userAgent = {
+ log: instance of org.apache.avalon.framework.logger.ConsoleLogger(id=597)
+ defaults: instance of java.util.HashMap(id=601)
+ handlers: instance of java.util.HashMap(id=602)
+ baseURL: ""
+ pdfEncryptionParams: null
+ px2mm: 0.35277778
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl = {
+ driver: instance of org.apache.fop.apps.Driver(id=587)
+ usedFonts: instance of java.util.HashMap(id=604)
+ triplets: instance of java.util.HashMap(id=605)
+ fonts: instance of java.util.HashMap(id=606)
+ layoutStrategy: instance of org.apache.fop.layoutmgr.LayoutManagerLS(id=607)
+ areaTree: instance of org.apache.fop.area.AreaTree(id=608)
+ atModel: instance of org.apache.fop.area.RenderPagesModel(id=609)
+ bookmarks: null
+ idReferences: instance of java.util.HashSet(id=610)
+ foInputHandler: instance of org.apache.fop.fo.FOTreeHandler(id=591)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl.driver = {
+ NOT_SET: 0
+ RENDER_PDF: 1
+ RENDER_AWT: 2
+ RENDER_MIF: 3
+ RENDER_XML: 4
+ RENDER_PRINT: 5
+ RENDER_PCL: 6
+ RENDER_PS: 7
+ RENDER_TXT: 8
+ RENDER_SVG: 9
+ RENDER_RTF: 10
+ treeBuilder: instance of org.apache.fop.fo.FOTreeBuilder(id=588)
+ rendererType: 1
+ renderer: instance of org.apache.fop.render.pdf.PDFRenderer(id=599)
+ foInputHandler: instance of org.apache.fop.fo.FOTreeHandler(id=591)
+ source: null
+ stream: instance of java.io.BufferedOutputStream(id=600)
+ reader: null
+ log: instance of org.apache.avalon.framework.logger.ConsoleLogger(id=597)
+ userAgent: instance of org.apache.fop.apps.FOUserAgent(id=592)
+ currentDocument: instance of org.apache.fop.apps.Document(id=593)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl.areaTree = {
+ model: instance of org.apache.fop.area.RenderPagesModel(id=609)
+ atControl: instance of org.apache.fop.apps.Document(id=593)
+ idLocations: instance of java.util.HashMap(id=615)
+ resolve: instance of java.util.HashMap(id=616)
+ treeExtensions: instance of java.util.ArrayList(id=617)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl.atModel = {
+ renderer: instance of org.apache.fop.render.pdf.PDFRenderer(id=599)
+ prepared: instance of java.util.ArrayList(id=618)
+ pendingExt: instance of java.util.ArrayList(id=619)
+ endDocExt: instance of java.util.ArrayList(id=620)
+ org.apache.fop.area.StorePagesModel.pageSequence: null
+ org.apache.fop.area.StorePagesModel.titles: instance of java.util.ArrayList(id=621)
+ org.apache.fop.area.StorePagesModel.currSequence: null
+ org.apache.fop.area.StorePagesModel.extensions: instance of java.util.ArrayList(id=622)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl.atModel.renderer = {
+ MIME_TYPE: "application/pdf"
+ pdfDoc: instance of org.apache.fop.pdf.PDFDocument(id=624)
+ pages: null
+ pageReferences: instance of java.util.HashMap(id=625)
+ pvReferences: instance of java.util.HashMap(id=626)
+ ostream: instance of java.io.BufferedOutputStream(id=600)
+ pdfResources: null
+ currentStream: null
+ currentContext: null
+ currentPage: null
+ currentState: null
+ currentFontName: ""
+ currentFontSize: 0
+ pageHeight: 0
+ filterMap: null
+ textOpen: false
+ prevWordY: 0
+ prevWordX: 0
+ prevWordWidth: 0
+ wordAreaPDF: instance of java.lang.StringBuffer(id=627)
+ BPMarginOffset: 0
+ IPMarginOffset: 0
+ org.apache.fop.render.PrintRenderer.fontInfo: instance of org.apache.fop.apps.Document(id=593)
+ org.apache.fop.render.PrintRenderer.fontList: null
+ org.apache.fop.render.AbstractRenderer.userAgent: instance of org.apache.fop.apps.FOUserAgent(id=592)
+ org.apache.fop.render.AbstractRenderer.producer: "FOP 1.0dev"
+ org.apache.fop.render.AbstractRenderer.creator: null
+ org.apache.fop.render.AbstractRenderer.creationDate: null
+ org.apache.fop.render.AbstractRenderer.options: instance of java.util.HashMap(id=629)
+ org.apache.fop.render.AbstractRenderer.currentBPPosition: 0
+ org.apache.fop.render.AbstractRenderer.currentIPPosition: 0
+ org.apache.fop.render.AbstractRenderer.currentBlockIPPosition: 0
+ org.apache.fop.render.AbstractRenderer.containingBPPosition: 0
+ org.apache.fop.render.AbstractRenderer.containingIPPosition: 0
+ org.apache.avalon.framework.logger.AbstractLogEnabled.m_logger: instance of org.apache.avalon.framework.logger.ConsoleLogger(id=597)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl.layoutStrategy = {
+ name: "layoutmgr"
+ addLMVisitor: null
+ org.apache.fop.layout.LayoutStrategy.name: "undefined"
+ org.apache.fop.layout.LayoutStrategy.document: instance of org.apache.fop.apps.Document(id=593)
+}
+</screen>
+
+ <screen>
+ treeBuilder.foTreeControl.atModel.renderer.ostream = {
+ buf: instance of byte[512] (id=632)
+ count: 15
+ java.io.FilterOutputStream.out: instance of java.io.FileOutputStream(id=633)
+}
+</screen>
+
+ <para>For the members <literal>fontList<literal></literal>,
+fonts</literal>, <literal>usedFonts<literal></literal> and
+triplets<literal></literal> of treeBuilder.foTreeControl</literal>,
+see under Fonts.</para>
+ </section>
+
+ <section>
+ <title>A detailed overview of the entry methods</title>
+
+ <para>Already created (e.g. in <literal>Fop.main</literal>): an
+object of type <literal>Driver</literal> with the members
+<literal>userAgent</literal>, <literal>renderer</literal>,
+<literal>log</literal>, <literal>stream</literal>.</para>
+
+ <para>To create <literal>userAgent</literal> one may use
+<literal>Driver.getUserAgent</literal>: if <literal>driver</literal>
+does not have <literal>userAgent</literal>, create a new
+<literal>UserAgent</literal>.</para>
+
+ <para>To create <literal>renderer</literal> one may use one of
+three methods:<itemizedlist>
+ <listitem>
+ <simpara><literal>setRenderer(int
+renderer)</literal></simpara>
+ </listitem>
+ <listitem>
+ <simpara><literal>setRenderer(String
+rendererClassName)</literal></simpara>
+ </listitem>
+ <listitem>
+ <simpara><literal>setRenderer(Renderer
+renderer)</literal></simpara>
+ </listitem>
+ </itemizedlist> All three methods set the FOP version on the
+<literal>renderer</literal>, and register <literal>userAgent</literal>
+with it, which is obtained using
+<literal>Driver.getUserAgent</literal>.</para>
+
+ <para><literal>render(InputHandler inputHandler)</literal>:<itemizedlist>
+ <listitem>
+ <simpara>creates <literal>XMLReader parser</literal>,
+<literal>InputSource source</literal>;</simpara>
+ </listitem>
+ <listitem>
+ <simpara>calls <literal>render(XMLReader parser,
+InputSource source)</literal>.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><literal>render(org.w3c.dom.Document
+document)</literal>:<itemizedlist>
+ <listitem>
+ <simpara>creates <literal>DocumentReader reader</literal>,
+<literal>DocumentInputSource source</literal>;</simpara>
+ </listitem>
+ <listitem>
+ <simpara>calls <literal>render(XMLReader parser,
+InputSource source)</literal>.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><literal>render(XMLReader parser, InputSource
+source)</literal>:<itemizedlist>
+ <listitem>
+ <simpara>creates content handler by calling
+<literal>getContentHandler()</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>registers the content handler with the parser.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Adds <literal>currentDocument</literal> as a tree
+listener to <literal>foInputHandler</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>calls <literal>parser.parse(source)</literal>.</simpara>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><literal>getContentHandler()</literal>:<itemizedlist>
+ <listitem>
+ <simpara>if driver does not have a
+<literal>treeBuilder</literal>, call <literal>initialize()</literal>:
+create a new <literal>TreeBuilder</literal>, set the
+<literal>UserAgent</literal> on it.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>if driver does not have a
+<literal>currentDocument</literal>, create a new
+<literal>Document</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>create a new <literal>FOTreeHandler
+foInputHandler</literal> using <literal>currentDocument</literal> as
+an argument (<literal>currentDocument</literal> is member
+<literal>foTreeControl</literal> in
+<literal>foInputHandler</literal>).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>create a new <literal>AreaTree</literal> using <literal>currentDocument</literal> as an argument, and
+register it with <literal>currentDocument</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>create a new <literal>RenderPagesModel</literal>
+using <literal>renderer</literal> as an argument, and register it with
+<literal>currentDocument</literal> and with
+<literal>currentDocument.areaTree</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>register <literal>currentDocument</literal> with
+the <literal>renderer</literal> (<literal>currentDocument</literal> is
+member <literal>fontInfo</literal> in <literal>renderer</literal>);
+setup <literal>fontList</literal> in
+<literal>currentDocument</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>start the <literal>renderer</literal> with the
+<literal>outputstream</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>register <literal>foInputHandler</literal> with
+<literal>currentDocument</literal>.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>if <literal>currentDocument</literal> does not
+have a <literal>layoutStrategy</literal>, create a new
+<literal>LayoutStrategyLS</literal> for it with
+<literal>currentDocument</literal> as an argument.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>register <literal>userAgent</literal>,
+<literal>foInputHandler</literal> and
+<literal>currentDocument</literal> with <literal>treeBuilder</literal>
+(<literal>currentDocument</literal> is member
+<literal>foTreeControl</literal> in
+<literal>treeBuilder</literal>).</simpara>
+ </listitem>
+ <listitem>
+ <simpara>return <literal>treeBuilder</literal>.</simpara>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/properties.xml b/src/documentation/content/xdocs/DnI/properties.xml
new file mode 100644
index 000000000..632ccf946
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/properties.xml
@@ -0,0 +1,2455 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+ <chapter id="ch.properties">
+ <title>Properties</title>
+
+<section>
+ <title>The basic setup of the property subsystem</title>
+
+ <section>
+ <title>Property values</title>
+
+<para>The FO nodes in the FO tree contain property values as specified
+by the user. Each property value is represented by a object of type
+<literal>org.apache.fop.fo.Property</literal>, or of a subtype
+thereof.</para>
+
+<para>There are various types of property values:
+<literal>CharacterProperty</literal>,
+<literal>ColorTypeProperty</literal>,
+<literal>CondLengthProperty</literal>,
+<literal>EnumProperty</literal>, <literal>KeepProperty</literal>,
+<literal>LengthPairProperty</literal>,
+<literal>LengthProperty</literal>,
+<literal>LengthRangeProperty</literal>,
+<literal>ListProperty</literal>, <literal>NCnameProperty</literal>,
+<literal>NumberProperty</literal>, <literal>NumericProperty</literal>,
+<literal>RelativeNumericProperty</literal>,
+<literal>StringProperty</literal>. The type
+<literal>ToBeImplementedProperty</literal> is used for properties that
+are not yet implemented. Some of these types have subtypes:
+<literal>AutoLength</literal>, <literal>FixedLength</literal>,
+<literal>PercentLength</literal>, <literal>TableColLength</literal>
+are subclasses of <literal>LengthProperty</literal>;
+<literal>SpaceProperty</literal> is a subclass of
+<literal>LengthRangeProperty</literal>. Each of these types is a
+subtype of <literal>org.apache.fop.fo.Property</literal>.
+</para>
+
+ <para>Property values may implement one or more of the interfaces
+defined in the package <literal>org.apache.fop.datatypes</literal>:
+<literal>Numeric</literal>, <literal>Length</literal>,
+<literal>ColorType</literal></para>
+
+ <para>Some properties actually represent a set of properties, such
+as a minimum, an optimum and a maximum. These are represented by a
+property value which implements the
+<literal>CompoundDatatype</literal> interface. They contain a property
+value for each member property.</para>
+
+ </section>
+
+ <section>
+ <title>The property list of an FO node</title>
+
+ <para>Property values are held by the FO node corresponding to
+the fo element on which they are specified by the user. FO nodes
+contain a property list of type <literal>PropertyList</literal>, which
+extends <literal>HashMap</literal>.</para>
+
+ <para>The property types are known by the property
+name as used on the FO element, e.g. <literal>font-size</literal>. For
+efficiency of implementation, each type of property type is also known by
+an <literal>integer</literal>, the <literal>propID</literal>. The
+<literal>propID</literal>s are defined in the interface
+<literal>org.apache.fop.fo.Constants</literal>, which gives them a
+symbolic name of the form <literal>PR_</literal> + property name in
+capitals and spaces replaced by underscores,
+e.g. <literal>PR_FONT_SIZE</literal>. Wherever possible, the code uses
+the <literal>propID</literal>s instead of the property names.</para>
+
+<para>When an FO requests a property, it does so by
+<literal>propId</literal>. The request is eventually answered by
+<literal>PropertyList.getExplicitBaseProp</literal>, but before it can
+do so, it has to retrieve the property name from
+<literal>FOPropertyMapping.getPropertyName</literal>. A particular
+inefficiency as a consequence is found in
+<filename>FopPropValFunction.java</filename> and some other classes in
+the <literal>fo.expr</literal> package:
+
+<screen>
+return pInfo.getPropertyList().get(FOPropertyMapping.getPropertyId(propName))
+</screen>
+
+Here <literal>propName</literal> -> <literal>propId</literal> mapping
+is done, which later is reverted again.</para>
+
+<screen>
+ [1] org.apache.fop.fo.FOPropertyMapping.getPropertyName (FOPropertyMapping.java:486)
+ [2] org.apache.fop.fo.PropertyList.getExplicitBaseProp (PropertyList.java:230)
+ [3] org.apache.fop.fo.Property$Maker.findProperty (Property.java:281)
+ [4] org.apache.fop.fo.Property$Maker.get (Property.java:314)
+ [5] org.apache.fop.fo.PropertyList.get (PropertyList.java:281)
+ [6] org.apache.fop.fo.PropertyList.get (PropertyList.java:267)
+ [7] org.apache.fop.fo.FObj.getProperty (FObj.java:261)
+</screen>
+
+ </section>
+
+ <section>
+ <title>Property makers</title>
+
+ <para>Property value objects are created by a property maker of
+type <literal>org.apache.fop.fo.PropertyMaker</literal>, or of a
+subtype thereof. For each property type there is a property maker
+object, which knows the property type, its default value, and some
+other characteristics.</para>
+
+ <para>The types of property makers are:
+<literal>CharacterProperty.Maker</literal>,
+<literal>ColorTypeProperty.Maker</literal>,
+<literal>CompoundPropertyMaker</literal>,
+<literal>EnumProperty.Maker</literal>,
+<literal>LengthProperty.Maker</literal>,
+<literal>ListProperty.Maker</literal>,
+<literal>NumberProperty.Maker</literal>,
+<literal>StringProperty.Maker</literal>, and
+<literal>ToBeImplementedProperty.Maker</literal>.</para>
+
+<para>The property makers are lazily constructed when the
+<literal>FObj</literal> constructor wants to create its static member
+<literal>propertyListTable</literal>. The constructor calls
+<literal>FOPropertyMapping.getGenericMappings()</literal>, which
+constructs and returns
+<literal>Property.Maker[Constants.PROPERTY_COUNT+1]
+s_generics</literal>. The FObj constructor then copies this array of
+<literal>PropertyMaker</literal>s into
+<literal>propertyListTable</literal>.</para>
+
+ <para><literal>public static PropertyMaker[]
+getGenericMappings()</literal> first creates the shorthand property
+makers, so that they can be used in the creation of the makers of the
+real properties, and a set of generic property makers, which act as
+templates for the real property makers. Next it creates the makers for
+all property types. Related property types are grouped,
+e.g. <literal>createFontProperties()</literal>.</para>
+
+ <para>An example is the creation of the maker for the
+<literal>font-size</literal> property type:
+
+<screen>
+ m = new LengthProperty.Maker(PR_FONT_SIZE);
+ m.setInherited(true);
+ m.setDefault("12pt");
+ m.setPercentBase(LengthBase.INH_FONTSIZE);
+ addPropertyMaker("font-size", m);
+</screen>
+
+Since <literal>font-size</literal> is a length, its maker is a
+<literal>LengthProperty.Maker</literal>. It is inherited, and its
+default value is 12 pt. If the user specifies the
+<literal>font-size</literal> value as a percentage, then the actual
+value is calculated from the <literal>font-size</literal> value
+inherited from the parent FO node.</para>
+
+ </section>
+
+ <section>
+ <title>Shorthand properties</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>Shorthand properties are properties which are shorthand
+for a number of properties. In other words, they specify the value of
+a number of properties in a single attribute. All shorthand properties
+can take a list of values, which are space separated in the FO
+file. The FO spec specifies how this list of values determines the
+values of the properties for which this is the shorthand (the target
+properties.). The length of the list of values for a single shorthand
+property may vary. For each length the attribution of these values to
+the target properties is different.</para>
+
+ <para>When the FO tree is constructed, shorthand property
+values are parsed and stored like any other property value. Because
+the value can be a list, it is always of type
+<literal>ListProperty</literal>.</para>
+
+<para>The meaning of shorthand properties is only dealt with when the
+value of one of the target properties is retrieved. For that purpose
+each target property maker knows the shorthand properties that may set
+its value, and when the target property value is retrieved, its maker
+checks with each of its shorthand property makers if it has a
+value. Note that the value of a shorthand property is never retrieved
+directly, because shorthand properties have no direct meaning for the
+layout.</para>
+
+ <para>When the shorthand property value has been retrieved,
+the value for the target property must be extracted from the
+list. That is done by a shorthand parser, which implements
+<literal>ShorthandParser</literal>. There are two implementing types:
+<literal>GenericShorthandParser</literal> and
+<literal>BoxPropShorthandParser</literal>. Their method
+<literal>convertValueForProperty</literal> knows how each specified value
+determines the value of the possible target properties. A shorthand
+parser object is added to the shorthand property maker when the maker
+is created.</para>
+
+ <para>Note that <literal>CompoundPropertyMaker</literal> also
+has a member <literal>shorthandMaker</literal>. I am not sure if this
+has anything to do with shorthand properties. It seems more related to
+<literal>CompoundPropertyMaker</literal> delegating certain tasks to a
+subproperty maker, viz. the one which is the
+<literal>shorthandMaker</literal>.</para>
+
+
+ </section>
+
+ <section>
+ <title>Example of a shorthand property</title>
+
+ <para>The property <literal>margin</literal> is shorthand for
+the four properties <literal>margin-top</literal>,
+<literal>margin-right</literal>, <literal>margin-bottom</literal>,
+<literal>margin-left</literal>. Its value can consist of 1 to 4 width
+values.</para>
+
+<para>When the property maker for <literal>margin</literal> is
+created, it gets a <literal>BoxPropShorthandParser</literal> as
+shorthand parser:
+<screen>
+m = new ListProperty.Maker(PR_MARGIN);
+m.setInherited(false);
+m.setDefault("");
+m.setDatatypeParser(new BoxPropShorthandParser());
+m.setPercentBase(LengthBase.BLOCK_WIDTH);
+addPropertyMaker("margin", m);
+</screen>
+
+When the property maker for <literal>margin-top</literal> is created,
+the <literal>margin</literal> maker is registered with it as a
+shorthand maker:
+<screen>
+m = new LengthProperty.Maker(PR_MARGIN_TOP);
+m.setInherited(false);
+m.setDefault("0pt");
+m.addShorthand(s_generics[PR_MARGIN]);
+m.setPercentBase(LengthBase.BLOCK_WIDTH);
+addPropertyMaker("margin-top", m);
+</screen>
+</para>
+
+ <para>The maker for <literal>border-top-width</literal> has
+three shorthands: <literal>border-top</literal>,
+<literal>border-width</literal>, and <literal>border</literal>:
+<screen>
+ this.shorthands = instance of org.apache.fop.fo.properties.PropertyMaker[3] (id=772)
+ this.shorthands[0] = "org.apache.fop.fo.properties.ListProperty$Maker@1e1dadb"
+ this.shorthands[0].propId = 52
+ this.shorthands[1] = "org.apache.fop.fo.properties.ListProperty$Maker@bac9b9"
+ this.shorthands[1].propId = 56
+ this.shorthands[2] = "org.apache.fop.fo.properties.ListProperty$Maker@8ceeea"
+ this.shorthands[2].propId = 18
+</screen></para>
+
+ </section>
+
+ <section>
+ <title>Parsing a shorthand property</title>
+
+ <para>The value of a shorthand property is parsed and the value of a
+target property is extracted in this call stack:
+
+<screen>
+ [1] org.apache.fop.fo.BoxPropShorthandParser.convertValueForProperty (BoxPropShorthandParser.java:80)
+ [2] org.apache.fop.fo.GenericShorthandParser.getValueForProperty (GenericShorthandParser.java:93)
+ [3] org.apache.fop.fo.properties.PropertyMaker.getShorthand (PropertyMaker.java:617)
+ [4] org.apache.fop.fo.properties.PropertyMaker.findProperty (PropertyMaker.java:277)
+ [5] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:305)
+ [6] org.apache.fop.fo.PropertyList.get (PropertyList.java:282)
+ [7] org.apache.fop.fo.PropertyList.get (PropertyList.java:268)
+ [8] org.apache.fop.fo.PropertyManager.getMarginProps (PropertyManager.java:301)
+</screen>
+</para>
+
+ <para>The extraction proceeds as follows:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>PropertyMaker.getShorthand</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parser.getValueForProperty(propId,
+listprop, propertyMaker, propertyList)</literal>;
+<literal>propId</literal> is the ID of the target property,
+<literal>listprop</literal> is the shorthand property value, of type
+<literal>ListProperty</literal>, which was retrieved <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>if the shorthand value is
+<literal>inherit</literal>, get the value for the target property from
+the parent.</para>
+ </listitem>
+ <listitem>
+ <para>else
+<literal>convertValueForProperty(propId, listProperty, maker,
+propertyList)</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para>get from the shorthand list of
+values the value that corresponds to the target property</para>
+ </listitem>
+ <listitem>
+ <para>if the retrieved value is not
+<literal>null</literal>, convert the property,
+<literal>maker.convertShorthandProperty(propertyList, p,
+null)</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para>first try to convert it in
+the normal way: <literal>maker.convertProperty(prop, propertyList,
+fo)</literal></para>
+ </listitem>
+ <listitem>
+ <para>if this gives a
+<literal>null</literal> value, test if the value is an enumerated
+value or a keyword; if so, process it.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+
+ </section>
+
+ </section>
+
+ <section>
+ <title>Corresponding properties</title>
+
+ <para>A number of traits can be specified by two alternative
+properties, e.g. <literal>border-left-width</literal> and
+<literal>border-start-width</literal>. These are called corresponding
+properties. One of a pair of corresponding properties is an absolute
+property, the other is a relative property. The meaning of the
+relative property depends on the writing mode. When the value of a
+property is retrieved that has a corresponding property, the value of
+that corresponding property should also be taken into account.</para>
+
+ <para>Corresponding properties are registered with the property
+maker when it is created:
+
+<screen>
+bwm = new BorderWidthPropertyMaker(PR_BORDER_LEFT_WIDTH);
+bwm.useGeneric(genericBorderWidth);
+bwm.setBorderStyleId(PR_BORDER_LEFT_STYLE);
+bwm.addShorthand(s_generics[PR_BORDER_LEFT]);
+bwm.addShorthand(s_generics[PR_BORDER_WIDTH]);
+bwm.addShorthand(s_generics[PR_BORDER]);
+corr = new CorrespondingPropertyMaker(bwm);
+corr.setCorresponding(PR_BORDER_START_WIDTH, PR_BORDER_END_WIDTH,
+ PR_BORDER_AFTER_WIDTH);
+addPropertyMaker("border-left-width", bwm);
+</screen>
+
+There are always three corresponding properties, for the three writing
+modes <literal>lr_tb</literal>, <literal>rl_tb</literal>,
+<literal>tb_rl</literal>, in this order:
+
+<screen>
+ corr = {
+ baseMaker: instance of org.apache.fop.fo.properties.BorderWidthPropertyMaker(id=702)
+ lr_tb: 50
+ rl_tb: 36
+ tb_rl: 22
+ useParent: false
+ relative: false
+}
+</screen>
+</para>
+
+ <para>When a property value is retrieved, the value of the
+corresponding property may have priority. This is determined by the
+method <literal>corresponding.isCorrespondingForced()</literal>. This
+is true if
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>this is a relative property</para>
+ </listitem>
+ <listitem>
+ <para>and the corresponding property has been explicitly
+specified on this FO node</para>
+ </listitem>
+ </itemizedlist>
+Relative properties are marked by the fact that their corresponding
+property maker has its member <literal>relative</literal> set to
+<literal>true</literal>; this is set when the property is
+created.</para>
+
+ <para>If the corresponding property has priority, its value is
+computed. Otherwise, if the value of the property itself has been
+explicitly specified on this FO node, it is used. Otherwise, the
+corresponding property is computed. Computation in this connection
+means that also the shorthand properties are checked.</para>
+
+<para>Because shorthand properties only exist for absolute properties,
+the values are effectively checked in this order:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>An absolute property <itemizedlist spacing="compact">
+ <listitem>
+ <para>The explicit value of this property.</para>
+ </listitem>
+ <listitem>
+ <para>The explicit value of the corresponding
+property.</para>
+ </listitem>
+ <listitem>
+ <para>The value of this property from the shorthand
+properties.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+
+ <listitem>
+ <para>A relative property <itemizedlist spacing="compact">
+ <listitem>
+ <para>The explicit value of the corresponding
+property.</para>
+ </listitem>
+ <listitem>
+ <para>The explicit value of this property.</para>
+ </listitem>
+ <listitem>
+ <para>The value of the corresponding property from
+the shorthand properties.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist>
+</para>
+
+ </section>
+
+ <section>
+ <title>Mapping between property names, IDs and makers</title>
+
+<para>The property subsystem is set up in the class
+<literal>FOPropertyMapping</literal>. It creates a property maker
+object for each property type, and it creates mappings of
+the names, IDs and makers of the property types. It holds the
+following static maps:
+
+<screen>
+property name &lt;=&gt; property ID =&gt; property maker
+ | |
+ s_htSubPropNames (&lt;-) s_htGeneric
+ s_htPropIds (-&gt;)
+</screen>
+
+Each type of FObj holds a copy of <literal>s_htGeneric</literal> as
+its static member <literal>FObj.propertyListTable</literal>. According
+to design documents an FObj type may have its own specific makers for
+certain property types. Probably this is the reason that
+<literal>FObj</literal> holds its own copy of the list of makers. This
+allows subclasses to hold their own modified copy. As far as I know,
+this is not currently the case.</para>
+
+<para>The mappings are filled in the static method
+
+<screen>
+ private static void addPropertyMaker(String name, Property.Maker maker) {
+ s_generics[maker.getPropId()] = maker;
+ s_htPropNames.put(name, new Integer(maker.getPropId()));
+ s_htPropIds.put(new Integer(maker.getPropId()), name);
+ }
+</screen>
+
+which is called for each property type.</para>
+
+<para>The constants for property IDs are defined in the interface
+<literal>org.apache.fop.fo.Constants</literal>:
+
+<screen>
+ int PR_ABSOLUTE_POSITION = 1;
+ int PR_ACTIVE_STATE = 2;
+ ...
+ int PR_FONT_SIZE = 94;
+ ...
+ int PROPERTY_COUNT = 247;
+</screen>
+</para>
+
+<para>Composite properties are defined by a compound number:
+
+<screen>
+ int COMPOUND_SHIFT = 9;
+ int CP_MAXIMUM = 5 &lt;&lt; COMPOUND_SHIFT;
+ int CP_MINIMUM = 6 &lt;&lt; COMPOUND_SHIFT;
+ int CP_OPTIMUM = 7 &lt;&lt; COMPOUND_SHIFT;
+ ...
+</screen>
+</para>
+
+ <para>Enumerated property values are also defined here:
+
+<screen>
+ int ABSOLUTE = 1;
+ int ABSOLUTE_COLORMETRIC = 2;
+ ...
+ int VISIBLE = 105;
+ int WRAP = 106;
+</screen></para>
+
+ <para>For fast access to important characteristic of property
+inheritance, <literal>PropertyList</literal> maintains a static array
+<literal>boolean[Constants.PROPERTY_COUNT + 1]
+inheritableProperty</literal>, which lists for each property type if
+it is inherited. It is constructed by asking the maker of each
+property type if it is inherited.</para>
+
+<para>A few members of the array of <literal>PropertyMaker</literal>s
+<literal>s_generics</literal>. It is indexed by the
+<literal>propID</literal>. Member 0 is <literal>null</literal>, and
+serves for unknown property types. Member 1 is for
+<literal>absolute-position</literal>, member 94 for
+<literal>font-size</literal>.
+
+<screen>
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_generics
+ org.apache.fop.fo.FOPropertyMapping.s_generics = instance of org.apache.fop.fo.Property$Maker[248] (id=651)
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_generics[0]
+ org.apache.fop.fo.FOPropertyMapping.s_generics[0] = null
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_generics[1]
+ org.apache.fop.fo.FOPropertyMapping.s_generics[1] = "org.apache.fop.fo.EnumProperty$Maker@12884e0"
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_generics[94]
+ org.apache.fop.fo.FOPropertyMapping.s_generics[94] = "org.apache.fop.fo.LengthProperty$Maker@32efa7"
+</screen>
+</para>
+
+ <para>A few members of the mapping <literal>s_htPropIds</literal>
+from <literal>propID</literal> to property name. The
+<literal>s_htPropIds</literal> for compound properties are shifted:
+
+<screen>
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_htPropIds
+ org.apache.fop.fo.FOPropertyMapping.s_htPropIds = "{
+ 1=absolute-position
+ ...
+ 94=font-size
+ ...
+ 247=z-index
+ 512=block-progression-direction
+ 1024=conditionality
+ ...
+ 5632=within-page
+ }"
+</screen>
+</para>
+
+<para>A few members of the mappings <literal>s_htPropNames</literal>
+and <literal>s_htSubPropNames</literal> from property name to
+<literal>propID</literal>. The <literal>propIds</literal> for
+compound properties are shifted:
+
+<screen>
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_htPropNames
+ org.apache.fop.fo.FOPropertyMapping.s_htPropNames = "{
+ absolute-position=1
+ ...
+ font-size=94
+ ...
+ z-index=247
+ }"
+</screen>
+
+<screen>
+main[1] print org.apache.fop.fo.FOPropertyMapping.s_htSubPropNames
+ org.apache.fop.fo.FOPropertyMapping.s_htSubPropNames = "{
+ block-progression-direction=512
+ conditionality=1024
+ ...
+ within-page=5632
+ }"
+</screen>
+</para>
+
+ </section>
+
+ <section>
+ <title>Storing the property values based on their
+<literal>PropID</literal></title>
+
+ <para>The class <literal>PropertySets</literal> contains a setup
+by which property values may be retrieved by their
+<literal>PropId</literal> instead of their name. In this setup
+<literal>PropertyList</literal> no longer extends
+<literal>HashMap</literal> but contains an array of property objects,
+called <literal>values</literal>. In order to prevent that each FObj
+should contain an array of size
+<literal>Constants.PROPERTY_COUNT</literal>, a mapping is setup from a
+static array for all FO types and all property types to an index for
+the possible properties of an FO type,
+<literal>PropertySets.mapping</literal>.</para>
+
+<para><literal>PropertySets.mapping</literal> is a
+<literal>short[Constants.ELEMENT_COUNT+1][]</literal> matrix, which
+for each FO type contains a mapping from <literal>PropID</literal> to
+a sparse array of indices, which enumerates the properties that are
+valid for this FO type.</para>
+
+<para>For an element <literal>fo:bar</literal> which supports 2
+properties, <literal>foo</literal>, whose <literal>PropID</literal> is
+21, and <literal>baz</literal>, whose <literal>PropID</literal> is
+137, the array of indices has the values
+
+<screen>
+ indices[21] = 1
+ indices[137] = 2
+</screen>
+
+and all other values are 0. Here indices denotes the row in
+<literal>mapping</literal> which corresponds to FO type bar.</para>
+
+<para>The values are indices into the array
+<literal>PropertyList.values</literal>, which then looks like this:
+
+<screen>
+ values[0] = null // always null.
+ values[1] = reference to a 'foo' Property instance
+ values[2] = reference to a 'baz' Property instance
+</screen>
+</para>
+
+<para>Example of <literal>PropertySets.mapping</literal>:
+
+<screen>
+PropID -> | 0 1 2 3 4 5 ... (Contants.PR_XXX)
+Element | |
+ v |
+-----------------|--------------------------------------------------
+FO_BASIC_LINK | 2 0 1 0 2 0
+FO_BIDI_OVERRIDE | 3 0 0 1 2 3
+FO_BLOCK | 2 1 0 0 2 0
+... | ....
+ |
+</screen>
+</para>
+
+<para>A property value of an <literal>FONode</literal> can then be
+retrieved as <literal>PropertyList.values[indices[propId]]</literal>,
+where <literal>indices = PropertySets.getPropertySet(elementId) =
+PropertySets.mapping[elementId].</literal></para>
+
+<para>The matrix <literal>PropertySets.mapping</literal> is
+constructed in the routine
+<literal>PropertySets.initialize()</literal>.</para>
+
+<para>First it constructs the <literal>elements</literal> array. For
+each FO type this array contains an <literal>Element</literal>
+object. This object contains a list of properties which are valid for
+this type of FO, and a list of child <literal>Element</literal>
+objects. Each child <literal>Element</literal> object corresponds to
+an FO type that may occur as a child of this FO type.</para>
+
+<para>Then the <literal>for (boolean dirty = true; dirty; )</literal>
+loop is executed. It effect is as follows (from an email by Finn
+Bock). For each FO type the <literal>BitSet</literal> of allowed
+properties is merged with the <literal>BitSet</literal> of allowed
+properties of its possible direct children. When for any FO type the
+<literal>merge</literal> subroutine modifies its
+<literal>BitSet</literal>, it sets the boolean variable
+<literal>dirty</literal> to <literal>true</literal> to signal that
+another iteration of the loop is required. By iterating over the loop
+until no further modifications are made, one makes sure that the
+merging process propagates from below to the top, that is, from any FO
+type to its farthest possible ancestor. This ensures that every FO
+type registers the allowed properties of itself and of all FO types
+that may ever appear in its subtree.</para>
+
+<para>The matrix <literal>PropertySets.mapping</literal> is still not
+used in <literal>PropertyList</literal>, and the array
+<literal>values</literal> does not yet exist (19 May 2004). The
+properties are held by name in <literal>PropertyList</literal>, which
+extends <literal>HashMap</literal>.</para>
+
+ </section>
+
+ </section>
+
+ <section id="sec.properties.create">
+ <title>Creating a property value</title>
+
+ <section>
+ <title>General</title>
+
+ <para>A property value is created by the maker for the property type,
+in its method
+<literal>PropertyMaker.make(PropertyList, String, FObj)</literal>,
+where the second argument is the property value as a string:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>If the specified value is <literal>inherit</literal>,
+get the property value from the parent FObj.</para>
+ </listitem>
+ <listitem>
+ <para>Else if the value is an enumerated value, the corresponding
+property value is retrieved (for each possible enumerated value only
+one property value object exists, of type EnumProperty).</para>
+ </listitem>
+ <listitem>
+ <para>If this does not retrieve a property value, <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>If the value is a shorthand keyword, it is
+converted to the corresponding value.</para>
+ </listitem>
+ <listitem>
+ <para>The value is parsed, and a property value is
+created.</para>
+ </listitem>
+ <listitem>
+ <para>The method
+<literal>PropertyMaker.convertProperty</literal> is called, which is overridden
+in subclasses of PropertyMaker. CompoundPropertyMaker uses this method
+to convert the simple property value constructed to a compound
+property value: <itemizedlist spacing="compact">
+ <listitem>
+ <para>Make a compound property value based on
+default values: <literal>PropertyMaker.makeCompound</literal>,
+overridden in CompoundPropertyMaker.</para>
+ </listitem>
+ <listitem>
+ <para>Set all components equal to the
+simple property value that is being converted.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If this is a compound property maker, convert it to
+a compound property as above. (Is this the second time the property
+value is converted?)</para>
+ </listitem>
+ </itemizedlist>
+The property may also record the value as specified in the fo element,
+as this may influence the traits of the areas created by this FO node
+and FO nodes in the subtree.</para>
+
+<para>Subclasses of <literal>PropertyMaker</literal> may override this
+method. For example, <literal>StringProperty.Maker</literal> has a
+much simpler method.</para>
+
+<para>Attributes of the fo elements are converted to property value
+objects in <literal>PropertyList.convertAttributeToProperty</literal>:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>If the property is not a component of a compound
+property, <itemizedlist spacing="compact">
+ <listitem>
+ <para>Ask the maker for the property to create the
+property value.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Else if the property is a component of a compound
+property, <itemizedlist spacing="compact">
+ <listitem>
+ <para>Find the base property by a call to
+<literal>Propertylist.findBaseProperty</literal>: <itemizedlist
+ spacing="compact">
+ <listitem>
+ <para>If the base property value already exists,
+return it to <literal>convertAttributeToProperty</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>If the base attribute is also specified
+(later) in the list of attributes, retrieve it, ask the maker for the
+base property to create the base property value, and return it to
+<literal>convertAttributeToProperty</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>Return
+null to <literal>convertAttributeToProperty</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Ask the maker for the subproperty to create the
+subproperty value by a call to <literal>PropertyMaker.make(Property,
+int, PropertyList, String, FObj)</literal>, where the second argument
+is the subproperty ID and the fourth argument is the specified
+value. This method is overridden in
+<literal>CompoundPropertyMaker</literal>: <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>If the base property value does not yet
+exist, ask its maker to create it with default values for the
+components: <literal>PropertyMaker.makeCompound</literal>, which is
+overridden in <literal>CompoundPropertyMaker</literal>: <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>Create an empty property value.</para>
+ </listitem>
+ <listitem>
+ <para>Create property values for the
+subproperties with default values, and insert them into the compound
+property value.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Create the specified subproperty value and
+insert it into the compound property value, where it replaces the
+default subproperty value.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>Add the property to the property list.
+</para>
+ </listitem>
+ </itemizedlist></para>
+
+ </section>
+
+ <section>
+ <title>Example of a compound property</title>
+
+<para>In this example we illustrate the case where first the
+base attribute of a compound property is specified, and then the
+attribute for one of the components.</para>
+
+<para>First the user specifies the attribute value
+<literal>leader-length="120pt"</literal>.</para>
+
+<para>A simple length property value is constructed first:
+<screen>
+ p.getClass() = "class org.apache.fop.fo.properties.FixedLength"
+ p = {
+ millipoints: 120000
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+ p = "120000mpt"
+</screen></para>
+
+<para>Then it is converted into a compound property value. First a
+compound property with default component values is created:
+<screen>
+ p.getClass() = "class org.apache.fop.fo.properties.LengthRangeProperty"
+ p = {
+ minimum: instance of org.apache.fop.fo.properties.FixedLength(id=759)
+ optimum: instance of org.apache.fop.fo.properties.FixedLength(id=760)
+ maximum: instance of org.apache.fop.fo.properties.PercentLength(id=761)
+ bfSet: 0
+ bChecked: true
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+ p = "LengthRange[min:0mpt, max:100.0%, opt:12000mpt]"
+</screen>
+
+Then all components are set equal to the simple property value:
+<screen>
+ prop.getClass() = "class org.apache.fop.fo.properties.LengthRangeProperty"
+ prop = {
+ minimum: instance of org.apache.fop.fo.properties.FixedLength(id=744)
+ optimum: instance of org.apache.fop.fo.properties.FixedLength(id=744)
+ maximum: instance of org.apache.fop.fo.properties.FixedLength(id=744)
+ bfSet: 7
+ bChecked: true
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+ prop = "LengthRange[min:120000mpt, max:120000mpt, opt:120000mpt]"
+</screen></para>
+
+<para>The property makers involved:
+<screen>
+ this = "org.apache.fop.fo.properties.LengthRangeProperty$Maker@55a338"
+ this.subproperties = instance of org.apache.fop.fo.properties.PropertyMaker[11] (id=766)
+ getSubpropMaker(org.apache.fop.fo.Constants.CP_MINIMUM) = "org.apache.fop.fo.properties.LengthProperty$Maker@955cd5"
+ getSubpropMaker(org.apache.fop.fo.Constants.CP_MAXIMUM) = "org.apache.fop.fo.properties.LengthProperty$Maker@1bde4"
+ getSubpropMaker(org.apache.fop.fo.Constants.CP_OPTIMUM) = "org.apache.fop.fo.properties.LengthProperty$Maker@a77106"
+</screen></para>
+
+<para>Stack dump when making the compound property:
+<screen>
+ [1] org.apache.fop.fo.properties.CompoundPropertyMaker.makeCompound (CompoundPropertyMaker.java:258)
+ [2] org.apache.fop.fo.properties.CompoundPropertyMaker.convertProperty (CompoundPropertyMaker.java:173)
+ [3] org.apache.fop.fo.properties.LengthRangeProperty$Maker.convertProperty (LengthRangeProperty.java:68)
+ [4] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:392)
+ [5] org.apache.fop.fo.properties.CompoundPropertyMaker.make (CompoundPropertyMaker.java:206)
+ [6] org.apache.fop.fo.PropertyList.convertAttributeToProperty (PropertyList.java:418)
+ [7] org.apache.fop.fo.PropertyList.addAttributesToList (PropertyList.java:374)
+ [8] org.apache.fop.fo.FObj.addProperties (FObj.java:133)
+ [9] org.apache.fop.fo.FObj.processNode (FObj.java:96)
+ [10] org.apache.fop.fo.FOTreeBuilder.startElement (FOTreeBuilder.java:234)
+</screen>
+</para>
+
+<para>Subsequently, the user specifies a component,
+<literal>leader-length.maximum="200pt"</literal>.</para>
+
+<para>First the subproperty is constructed as a simple length property:
+<screen>
+ p.getClass() = "class org.apache.fop.fo.properties.FixedLength"
+ p = {
+ millipoints: 200000
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+ p = "200000mpt"
+</screen>
+</para>
+
+ <para>Then it is added to the compound property as the component
+<literal>maximum</literal>:
+<screen>
+ prop.getClass() = "class org.apache.fop.fo.properties.LengthRangeProperty"
+ prop = {
+ minimum: instance of org.apache.fop.fo.properties.FixedLength(id=755)
+ optimum: instance of org.apache.fop.fo.properties.FixedLength(id=755)
+ maximum: instance of org.apache.fop.fo.properties.FixedLength(id=767)
+ bfSet: 7
+ bChecked: true
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+ prop = "LengthRange[min:120000mpt, max:200000mpt, opt:120000mpt]"
+</screen>
+</para>
+
+<para>Stack dump when making the property:
+<screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:378)
+ [2] org.apache.fop.fo.properties.CompoundPropertyMaker.make (CompoundPropertyMaker.java:235)
+ [3] org.apache.fop.fo.PropertyList.convertAttributeToProperty (PropertyList.java:423)
+ [4] org.apache.fop.fo.PropertyList.addAttributesToList (PropertyList.java:374)
+ [5] org.apache.fop.fo.FObj.addProperties (FObj.java:133)
+ [6] org.apache.fop.fo.FObj.processNode (FObj.java:96)
+ [7] org.apache.fop.fo.FOTreeBuilder.startElement (FOTreeBuilder.java:234)
+</screen></para>
+
+ </section>
+
+<section>
+ <title>Enumerated property values</title>
+
+ <para>The interface <literal>Constants</literal> defines values
+for each possible enumerated value of a property:
+<screen>
+ int ABSOLUTE = 1;
+ int ABSOLUTE_COLORMETRIC = 2;
+ ...
+ int VISIBLE = 105;
+ int WRAP = 106;
+</screen></para>
+
+ <para>In <literal>FOPropertyMapping</literal> a property value
+object is constructed for each possible enumerated value. See the
+<literal>Property</literal> array <literal>enums</literal> and the
+method <literal>makeEnumProperty</literal>. During its construction,
+each property maker that can have enumerated values gets a member
+<literal>enums</literal>, which, for each of its possible enumerated
+values, gets a reference to the appropriate enumerated property value
+object. See the method <literal>PropertyMaker.addEnum</literal>.</para>
+
+ <para>Example: The properties <literal>hyphenate</literal> and
+<literal>precedence</literal> both have the possible value
+<literal>true</literal>. Their makers have a reference to the same
+property value object:
+<screen>
+ org.apache.fop.fo.FOPropertyMapping.s_generics
+ [org.apache.fop.fo.Constants.PR_HYPHENATE].
+ enums.get("true").hashCode() = 9236202
+ org.apache.fop.fo.FOPropertyMapping.s_generics
+ [org.apache.fop.fo.Constants.PR_PRECEDENCE].
+ enums.get("true").hashCode() = 9236202
+ org.apache.fop.fo.FOPropertyMapping.s_generics
+ [org.apache.fop.fo.Constants.PR_HYPHENATE].enums.get("true") = "100"
+ org.apache.fop.fo.FOPropertyMapping.s_generics
+ [org.apache.fop.fo.Constants.PR_HYPHENATE].enums.get("true") = {
+ value: 100
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+</screen></para>
+
+<para>Example: <literal>leader-pattern="rule"</literal>.
+<screen>
+ this = "org.apache.fop.fo.properties.EnumProperty$Maker@25c828"
+ this.enums = "{rule=82, use-content=104, dots=21, space=88}"
+ this.enums.get("rule").getClass() = "class org.apache.fop.fo.properties.EnumProperty"
+ this.enums.get("rule") = "82"
+ this.enums.get("rule") = {
+ value: 82
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+</screen></para>
+
+<para>The maker's method <literal>checkEnumValues</literal> returns
+the appropriate property value object
+<literal>enums.get(value)</literal>: <literal>newProp =
+"82"</literal>.</para>
+
+ <screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.checkEnumValues (PropertyMaker.java:480)
+ [2] org.apache.fop.fo.properties.EnumProperty$Maker.checkEnumValues (EnumProperty.java:50)
+ [3] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:383)
+ [4] org.apache.fop.fo.PropertyList.convertAttributeToProperty (PropertyList.java:418)
+ [5] org.apache.fop.fo.PropertyList.addAttributesToList (PropertyList.java:374)
+</screen>
+
+ </section>
+
+<section>
+ <title>Example of a property with keywords</title>
+
+<para>The value of the property <literal>border-top-width</literal>
+can be set to a width, but it can also be indicated by one of the
+keywords <literal>thin</literal>, <literal>medium</literal> and
+<literal>thick</literal>. The width values to which these keywords
+correspond are by default set by the implementation. When the property
+maker is constructed in <literal>FOPropertyMapping</literal>, it gets
+a hash map of keyword values.
+<screen>
+ this = "org.apache.fop.fo.properties.BorderWidthPropertyMaker@1cf4a2c"
+ this.propId = 55
+ this.keywords = "{medium=1pt, thin=0.5pt, thick=2pt}"
+}
+</screen>
+</para>
+
+<para>The method <literal>checkValueKeywords</literal> returns the
+mapped value: <literal>value = "1pt"</literal>. Subsequently a
+property value object is created as if that value had been specified.
+
+ <screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.checkValueKeywords (PropertyMaker.java:499)
+ [2] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:387)
+ [3] org.apache.fop.fo.PropertyList.convertAttributeToProperty (PropertyList.java:418)
+ [4] org.apache.fop.fo.PropertyList.addAttributesToList (PropertyList.java:374)
+ [5] org.apache.fop.fo.FObj.addProperties (FObj.java:133)
+</screen>
+</para>
+
+ </section>
+
+ <section>
+ <title>Parsing a property with an absolute value</title>
+
+ <para>Property values are parsed in
+<literal>PropertyParser.parseProperty</literal>:
+ <screen>
+ [1] org.apache.fop.fo.expr.PropertyParser.parseProperty (PropertyParser.java:111)
+ [2] org.apache.fop.fo.expr.PropertyParser.parse (PropertyParser.java:88)
+ [3] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:389)
+ [4] org.apache.fop.fo.PropertyList.convertAttributeToProperty (PropertyList.java:418)
+ [5] org.apache.fop.fo.PropertyList.addAttributesToList (PropertyList.java:374)
+ [6] org.apache.fop.fo.FObj.addProperties (FObj.java:133)
+</screen></para>
+
+ <para>Example: <literal>&lt;fo:simple-page-master
+master-name="simpleA4" margin="4pt"></literal>, property being parsed:
+<literal>margin="4pt"</literal>, <literal>propId</literal> = 134.</para>
+
+<para>The PropertyParser object:
+<screen>
+ this = "org.apache.fop.fo.expr.PropertyParser@8530b8"
+ this = {
+ propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=729)
+ org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: null
+ org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt"
+ org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: false
+}
+</screen></para>
+
+ <para>It has a member of type <literal>PropertyInfo</literal>,
+which contains contextual information:
+<screen>
+ propInfo = "org.apache.fop.fo.expr.PropertyInfo@1abcc03"
+ propInfo = {
+ maker: instance of org.apache.fop.fo.properties.ListProperty$Maker(id=705)
+ plist: instance of org.apache.fop.fo.PropertyList(id=737)
+ fo: instance of org.apache.fop.fo.pagination.LayoutMasterSet(id=738)
+ stkFunction: null
+}
+</screen>
+<literal>fo</literal> is the parent FO.</para>
+
+<para>The property list of the current FO node:
+<screen>
+ propInfo.plist = {
+ writingModeTable: null
+ writingMode: 0
+ inheritableProperty: null
+ parentPropertyList: instance of org.apache.fop.fo.PropertyList(id=743)
+ namespace: "http://www.w3.org/1999/XSL/Format"
+ elementName: "fo:simple-page-master"
+ fobj: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=746)
+}
+</screen>
+The property list up to now:
+<screen>
+ propInfo.plist = "{master-name=simpleA4}"
+</screen>
+</para>
+
+ <para>Property <literal>master-name</literal>'s maker is
+<literal>StringPropertyMaker</literal>, which does not parse its
+value.</para>
+
+ <para>PropertyParser.parseProperty <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>next(), which scans the next token; at its return:
+<screen>
+ this = {
+ propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=667)
+ org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 12
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: "4pt"
+ org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt"
+ org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: true
+}
+</screen>
+i.e. the whole expression is a single token, it is of type
+<literal>PropertyTokenizer.TOK_NUMERIC</literal> (= 12), the unit is 2
+chars long.</para>
+ </listitem>
+ <listitem>
+ <para>Loop forever. <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>Analyse the expression. Start with
+<literal>parseAdditiveExpr</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parseMultiplicativeExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parseUnaryExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parsePrimaryExpr</literal>;
+the unit may be a relative unit (em) which must be resolved against
+the font size <itemizedlist spacing="compact">
+ <listitem>
+ <para>construct a property
+value object:
+<screen>
+ prop = "4000mpt"
+ prop.getClass() = "class org.apache.fop.fo.properties.FixedLength"
+</screen></para>
+ </listitem>
+ <listitem>
+ <para><literal>next()</literal>:
+scan the next token;
+<screen>
+ this = {
+ propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=729)
+ org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: null
+ org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt"
+ org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: true
+}
+</screen>
+the next token is of type <literal>currentToken =
+PropertyTokenizer.TOK_EOF</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If <literal>currentToken =
+PropertyTokenizer.TOK_EOF</literal>, break the loop.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist>
+Return the property: <literal>p = "4000mpt"</literal>.</para>
+ </section>
+
+ </section>
+
+<section>
+ <title>Retrieving a property value</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>For all FO types the FO spec specifies a large number of
+property types for which the user may specify a value in order to
+modify the resulting layout of the document. Many of these properties
+have a default value, many others inherit their value from the parent
+FO if they are not specified. In principle the layout process must
+retrieve the value of each possible property type of an FO node in
+order to determine the appropriate value of the corresponding
+trait.</para>
+
+ <para>Retrieving a property value goes through these steps:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>First determine if the property value was specified
+in one or other way. This is done in the method
+<literal>propertyMaker.findProperty</literal> <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>if this property has a corresponding property
+and if the corresponding property is forced, i.e. if this property is
+relative and if a value for the corresponding property was explicitly
+specified, compute and return it.</para>
+ </listitem>
+ <listitem>
+ <para>else <itemizedlist spacing="compact">
+ <listitem>
+ <para>if a value for this property was
+explicitly specified, compute and return it</para>
+ </listitem>
+ <listitem>
+ <para>else if this property has a
+corresponding property, compute its value; if it is not null return
+it</para>
+ </listitem>
+ <listitem>
+ <para>else if a value for a relevant shorthand
+property was specified, compute and return it</para>
+ </listitem>
+ <listitem>
+ <para>else if this property is inheritable,
+find it at the parent; this repeats the whole process on the parent,
+and possibly its parents, up to the root node; if successful, return
+the found property value</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If no property value is found, a default property
+value object is made; the default value is stored in the property
+maker as <literal>defaultValue</literal>: <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>if the default property value object was
+calculated earlier, it was cached as
+<literal>defaultProperty</literal>; return it</para>
+ </listitem>
+ <listitem>
+ <para>else make it in the same way as property value
+objects are made when the FO tree is constructed, in
+<literal>propertyMaker.make</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>Compute corresponding, as used in
+<literal>findProperty</literal>, proceeds as follows: <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>use parent's property list or this property
+list?</para>
+ </listitem>
+ <listitem>
+ <para>check explicit or shorthand for corresponding</para>
+ </listitem>
+ <listitem>
+ <para>convert property</para>
+ </listitem>
+ </itemizedlist></para>
+
+<para><literal>PropertyManager</literal>,
+<literal>CommonBorderAndPadding</literal>,
+<literal>CommonBackground</literal>,
+<literal>CommonMarginBlock</literal>,
+<literal>CommonHyphenation</literal> are convenience classes used in
+the calculation of the traits. <literal>PropertyManager</literal> has
+methods to return objects of these types. A
+<literal>CommonBorderAndPadding</literal> object and a
+<literal>CommonHyphenation</literal> object are cached. A
+<literal>CommonBackground</literal> object and a
+<literal>CommonMarginBlock</literal> object are calculated when
+requested. Similarly for many other convenience classes
+<literal>Common*</literal> for which
+<literal>PropertyManager</literal> can return an object. These classes
+are in package <literal>fo.properties</literal>. Similar classes
+called <literal>*Props</literal> are in package
+<literal>traits</literal>. Of these <literal>PropertyManager</literal>
+can only return a <literal>BlockProps</literal> object.</para>
+
+ </section>
+
+ <section>
+ <title>Detailed overview</title>
+
+ <para>The retrieval of a property value is started with a call
+to <literal>PropertyList.get(int propId)</literal>, which calls
+<literal>PropertyList.get(propId, true, true)</literal>.</para>
+
+<para><literal>PropertyList.get(int propId, boolean bTryInherit,
+boolean bTryDefault)</literal>:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>Find the maker for this property as
+<literal>FObj.propertyListTable[propId]</literal>, variable
+<literal>propertyMaker</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>propertyMaker.get(int subpropId,
+PropertyList propertyList, boolean bTryInherit, boolean
+bTryDefault)</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propertyMaker.findProperty(PropertyList
+propertyList, boolean bTryInherit)</literal> <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>if corresponding and corresponding is
+forced <itemizedlist spacing="compact">
+ <listitem>
+ <para>evaluate condition:
+<literal>CorrespondingPropertyMaker.isCorrespondingForced
+(PropertyList propertyList)</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para> <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>return false if this is
+not a relative property
+(<literal>corresponding.relative</literal>)</para>
+ </listitem>
+ <listitem>
+ <para>return true if
+corresponding property was explicitly specified on this node or on its
+parent, depending on the type of property
+(<literal>corresponding.useParent</literal>)</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para><literal>corresponding.compute(PropertyList
+propertyList)</literal>; this subroutine and the subroutines it calls
+refer to the corresponding property <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propertyList.getExplicitOrShorthand(correspondingId)</literal>;
+propertyList is that of this node or of the parent, depending on the
+type of property (corresponding.useParent) <itemizedlist
+spacing="compact">
+ <listitem>
+ <para><literal>propertyList.getExplicitBaseProp(int
+correspondingId)</literal> (see below)</para>
+ </listitem>
+ <listitem>
+ <para>if
+<literal>(null)</literal> <literal>propertyList.getShorthand(int
+correspondingId)</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propertyMaker.getShorthand(this)</literal>
+(see below)</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(not
+null)</literal> convert property</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>else <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propertyList.getExplicitBaseProp(int
+propId)</literal> from <literal>propertyList</literal> as a hash map;
+note that this requires a conversion from <literal>propId</literal> to
+<literal>propName</literal> via <literal>s_htPropNames</literal>;
+example: <literal>propertyList =
+"{master-name=simpleA4}"</literal></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(null)</literal>
+<literal>propertyMaker.compute(PropertyList propertyList)</literal>:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>if
+<literal>(corresponding)</literal>
+<literal>corresponding.compute(PropertyList propertyList)</literal>,
+as above</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(null)</literal>
+<literal>propertyMaker.getShorthand(PropertyList
+propertyList)</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para>if
+<literal>(maker.shorthands)</literal> then for each shorthand
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propertyList.getExplicit(int
+shorthand.propId)</literal>; a shorthand must be
+<literal>ListProperty</literal></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(not
+null)</literal> parse the shorthand property value,
+<literal>parser.getValueForProperty(propId, listprop, propertyMaker,
+this, propertyList)</literal>; here <literal>propId</literal> is the
+<literal>propId</literal> of this property, not of the shorthand; a
+shorthand may contain values for several properties, and this method
+retrieves the value for the current property; if <literal>(not
+null)</literal> return it</para>
+ </listitem>
+ </itemizedlist>Note: the first
+shorthand property maker in <literal>maker.shorthands</literal> that
+returns a good property is used</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(null &amp;&amp;
+bTryInherit)</literal>
+<literal>propertyMaker.findProperty(parentPropertyList,
+true)</literal>: the whole process is repeated on the parent, and
+possibly its parents, up to the root node.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(null &amp;&amp; bTryDefault)</literal>
+<literal>propertyMaker.make(PropertyList propertyList)</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>if there is a cached value,
+<literal>defaultProperty</literal>, return it</para>
+ </listitem>
+ <listitem>
+ <para><literal>propertyMaker.make(PropertyList
+propertyList, String value, FObj fo)</literal>;
+<literal>value</literal> is the default value stored in the property
+maker, <literal>fo</literal> is the parent FO <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>if default value is
+<literal>inherit</literal>,
+propertyList.getFromParent(<literal>propId</literal>)
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>if
+<literal>(parentPropertyList != null)</literal>
+<literal>parentPropertyList.get(propId)</literal>; the whole process
+is repeated on the parent, and possibly its parents, up to the root
+node.</para>
+ </listitem>
+ <listitem>
+ <para><literal>propertyMaker.make(PropertyList
+propertyList)</literal>; this seems to create an endless recursion;
+<literal>parentPropertyList == null</literal> in the root node.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>else check enumerated values
+<literal>propertyMaker.checkEnumValues(value)</literal>: get the
+enumerated property from <literal>propertyMaker.enums</literal></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(null)</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propertyMaker.checkValueKeywords(String
+value)</literal>; check if the value is a keyword in
+<literal>propertyMaker.keywords</literal>; if so, substitute the value
+with the value for which the keyword stands</para>
+ </listitem>
+ <listitem>
+ <para>parse the value <literal>p =
+PropertyParser.parse(pvalue, new PropertyInfo(propertyMaker,
+propertyList, fo))</literal></para>
+ </listitem>
+ <listitem>
+ <para>convert the property
+<literal>propertyMaker.convertProperty(p, propertyList,
+fo)</literal></para>
+ </listitem>
+ <listitem>
+ <para>if <literal>(null)</literal>
+throw <literal>org.apache.fop.fo.expr.PropertyException</literal>,
+which immediately is catched and rethrown as
+<literal>FOPException</literal> (why?)</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>catch <literal>FOPException</literal>; this
+means that this method may return a <literal>null</literal>
+property</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>catch <literal>FOPException</literal>; this means that
+this method may return a <literal>null</literal> property</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The call stack at the <literal>findProperty</literal> and
+<literal>make</literal>calls is:
+<screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.findProperty (PropertyMaker.java:240)
+ [2] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:282)
+ [3] org.apache.fop.fo.PropertyList.get (PropertyList.java:252)
+ [4] org.apache.fop.fo.PropertyList.get (PropertyList.java:238)
+ [5] org.apache.fop.fo.FObj.getProperty (FObj.java:163)
+ [6] org.apache.fop.layoutmgr.PageLayoutManager.createPageAreas (PageLayoutManager.java:745)
+</screen>
+<screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:387)
+ [2] org.apache.fop.fo.properties.PropertyMaker.make (PropertyMaker.java:369)
+ [3] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:285)
+ [4] org.apache.fop.fo.PropertyList.get (PropertyList.java:252)
+ [5] org.apache.fop.fo.PropertyList.get (PropertyList.java:238)
+ [6] org.apache.fop.fo.FObj.getProperty (FObj.java:163)
+ [7] org.apache.fop.layoutmgr.PageLayoutManager.createPageAreas (PageLayoutManager.java:745)
+</screen>
+For properties whose maker is compound property maker:
+<screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.findProperty (PropertyMaker.java:240)
+ [2] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:282)
+ [3] org.apache.fop.fo.properties.CompoundPropertyMaker.get (CompoundPropertyMaker.java:146)
+ [4] org.apache.fop.fo.PropertyList.get (PropertyList.java:252)
+ [5] org.apache.fop.fo.PropertyList.get (PropertyList.java:238)
+ [6] org.apache.fop.fo.flow.Leader.getLength (Leader.java:135)
+ [7] org.apache.fop.layoutmgr.AddLMVisitor.getLeaderAllocIPD (AddLMVisitor.java:305)
+ [8] org.apache.fop.layoutmgr.AddLMVisitor$2.getAllocationIPD (AddLMVisitor.java:290)
+ [9] org.apache.fop.layoutmgr.LeafNodeLayoutManager.getNextBreakPoss (LeafNodeLayoutManager.java:143)
+</screen></para>
+
+ </section>
+
+ <section>
+ <title>Examples: Retrieving border and padding values</title>
+
+<para>In this section we follow in detail how the border and padding
+values for the body region are retrieved. The relevant part of the
+input FO file is:
+
+<screen>
+<![CDATA[<fo:simple-page-master master-name="simpleA4" margin="4pt">
+<fo:region-body margin="4pt+20%" border="3pt solid black"
+ border-before-width="2pt" border-right-width="4pt"
+ border-start-width="inherit"/>
+</fo:simple-page-master>]]>
+</screen>
+</para>
+
+ <para>This section was written after I added the cache to the
+look-up of property values.</para>
+
+ <section>
+
+ <title>Retrieving the <literal>margin-top</literal> value on
+<literal>region-body</literal></title>
+
+<para>This what we are retrieving:
+
+<screen>
+ propertyList.getFOName() = "fo:region-body"
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(propId) = "margin-top"
+</screen>
+
+The margin values are retrieved by the method
+<literal>PropertyManager.getMarginProps</literal>. This is the call
+stack that leads up to it and on to the retrieval of the value of
+<literal>margin-top</literal>:
+
+<screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.findProperty (PropertyMaker.java:240)
+ [2] org.apache.fop.fo.PropertyList.findProperty (PropertyList.java:289)
+ [3] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:291)
+ [4] org.apache.fop.fo.PropertyList.get (PropertyList.java:261)
+ [5] org.apache.fop.fo.PropertyList.get (PropertyList.java:247)
+ [6] org.apache.fop.fo.PropertyManager.getMarginProps (PropertyManager.java:264)
+ [7] org.apache.fop.fo.pagination.RegionBody.getViewportRectangle (RegionBody.java:58)
+ [8] org.apache.fop.layoutmgr.PageLayoutManager.makeRegionViewport (PageLayoutManager.java:811)
+ [9] org.apache.fop.layoutmgr.PageLayoutManager.createPageAreas (PageLayoutManager.java:784)
+ [10] org.apache.fop.layoutmgr.PageLayoutManager.createPage (PageLayoutManager.java:721)
+ [11] org.apache.fop.layoutmgr.PageLayoutManager.makeNewPage (PageLayoutManager.java:441)
+ [12] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:191)
+</screen>
+</para>
+
+<para>The retrieval proceeds as follows:
+<itemizedlist spacing="compact">
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Is the value in
+the cache? No.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>:
+<literal>corresponding != null</literal>? No.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>: Is this property
+explicitly specified? No.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>: Can the
+corresponding property be computed? No, there is no corresponding
+property.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>: Is a shorthand
+property for this property specified? Yes, <literal>margin</literal>
+is a shorthand for it. The property value is retrieved as:
+<screen>
+ listprop = "[(4000mpt +20.0%)]"
+</screen>
+It is a list property as are all shorthand properties. The
+value for <literal>margin-top</literal> is extracted from it as:
+<screen>
+ p = "(4000mpt +20.0%)"
+</screen>
+</para>
+</listitem>
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Add the value to
+the cache.</para>
+</listitem>
+ </itemizedlist>
+</para>
+ </section>
+
+ <section>
+ <title>Retrieving the <literal>border-before-style</literal>
+value on <literal>region-body</literal></title>
+
+<para>This what we are retrieving:
+
+<screen>
+ propertyList.getFOName() = "fo:region-body"
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(propId) = "border-before-style"
+</screen>
+
+The border values are retrieved by the method
+<literal>PropertyManager.getBorderAndPadding</literal>. This is the call
+stack that leads up to it and on to the retrieval of the value of
+<literal>border-before-style</literal>:
+
+<screen>
+ [1] org.apache.fop.fo.properties.PropertyMaker.findProperty (PropertyMaker.java:240)
+ [2] org.apache.fop.fo.PropertyList.findProperty (PropertyList.java:289)
+ [3] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:291)
+ [4] org.apache.fop.fo.PropertyList.get (PropertyList.java:261)
+ [5] org.apache.fop.fo.PropertyList.get (PropertyList.java:247)
+ [6] org.apache.fop.fo.PropertyManager.initBorderInfo (PropertyManager.java:155)
+ [7] org.apache.fop.fo.PropertyManager.getBorderAndPadding (PropertyManager.java:143)
+ [8] org.apache.fop.fo.PropertyManager.getMarginProps (PropertyManager.java:289)
+ [9] org.apache.fop.fo.pagination.RegionBody.getViewportRectangle (RegionBody.java:58)
+ [10] org.apache.fop.layoutmgr.PageLayoutManager.makeRegionViewport (PageLayoutManager.java:811)
+ [11] org.apache.fop.layoutmgr.PageLayoutManager.createPageAreas (PageLayoutManager.java:784)
+ [12] org.apache.fop.layoutmgr.PageLayoutManager.createPage (PageLayoutManager.java:721)
+ [13] org.apache.fop.layoutmgr.PageLayoutManager.makeNewPage (PageLayoutManager.java:441)
+ [14] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:191)
+</screen>
+</para>
+
+<para>The retrieval proceeds as follows:
+<itemizedlist spacing="compact">
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Is the value in
+the cache? No.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>:
+<literal>corresponding != null</literal>, but
+<literal>corresponding.isCorrespondingForced()</literal> returns
+<literal>false</literal>. The corresponding property is
+<literal>border-top-style</literal>, which is not specified:
+
+<screen>
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(correspondingId) = "border-top-style"
+</screen>
+This is the corresponding property maker:
+<screen>
+ this = {
+ baseMaker: instance of org.apache.fop.fo.properties.EnumProperty$Maker(id=816)
+ lr_tb: 54
+ rl_tb: 54
+ tb_rl: 43
+ useParent: false
+ relative: true
+}
+</screen>
+</para>
+ </listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>: Is this property
+explicitly specified? No.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>: Can the
+corresponding property be computed? Yes, it can be derived from the
+property <literal>border</literal>, which is a shorthand for the
+corresponding property <literal>border-top-style</literal>. The
+returned value is <literal>87</literal>, which stands for
+<literal>SOLID</literal>.</para>
+<para>Note that the shorthand was not used in the
+computation of
+<literal>corresponding.isCorrespondingForced()</literal>, but it is in
+the computation of the specified value of the corresponding
+property.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Add the value to
+the cache.</para>
+</listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Retrieving the <literal>border-before-width</literal>
+value on <literal>region-body</literal></title>
+
+<para>This what we are retrieving:
+
+<screen>
+ propertyList.getFOName() = "fo:region-body"
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(propId) = "border-before-width"
+</screen>
+
+The border values are retrieved by the method
+<literal>PropertyManager.getBorderAndPadding</literal>. This is the call
+stack that leads up to it and on to the retrieval of the value of
+<literal>border-before-width</literal>:
+
+<screen>
+main[1] where
+ [1] org.apache.fop.fo.properties.PropertyMaker.findProperty (PropertyMaker.java:240)
+ [2] org.apache.fop.fo.PropertyList.findProperty (PropertyList.java:289)
+ [3] org.apache.fop.fo.properties.PropertyMaker.get (PropertyMaker.java:291)
+ [4] org.apache.fop.fo.properties.CompoundPropertyMaker.get (CompoundPropertyMaker.java:146)
+ [5] org.apache.fop.fo.PropertyList.get (PropertyList.java:261)
+ [6] org.apache.fop.fo.PropertyList.get (PropertyList.java:247)
+ [7] org.apache.fop.fo.PropertyManager.initBorderInfo (PropertyManager.java:157)
+ [8] org.apache.fop.fo.PropertyManager.getBorderAndPadding (PropertyManager.java:143)
+ [9] org.apache.fop.fo.PropertyManager.getMarginProps (PropertyManager.java:289)
+ [10] org.apache.fop.fo.pagination.RegionBody.getViewportRectangle (RegionBody.java:58)
+ [11] org.apache.fop.layoutmgr.PageLayoutManager.makeRegionViewport (PageLayoutManager.java:811)
+ [12] org.apache.fop.layoutmgr.PageLayoutManager.createPageAreas (PageLayoutManager.java:784)
+ [13] org.apache.fop.layoutmgr.PageLayoutManager.createPage (PageLayoutManager.java:721)
+ [14] org.apache.fop.layoutmgr.PageLayoutManager.makeNewPage (PageLayoutManager.java:441)
+ [15] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:191)
+</screen>
+
+The difference with the call stack for
+<literal>border-before-style</literal> is that
+<literal>border-before-width</literal> is a compound property, with
+a <literal>minimum</literal>, an <literal>optimum</literal> and a
+<literal>maximum</literal> value.
+</para>
+
+<para>The retrieval proceeds as follows:
+<itemizedlist spacing="compact">
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Is the value in
+the cache? No.</para>
+</listitem>
+ <listitem>
+<para><literal>PropertyMaker.findProperty</literal>:
+<literal>corresponding != null</literal>, but
+<literal>corresponding.isCorrespondingForced()</literal> returns
+<literal>false</literal>. The corresponding property is
+<literal>border-top-width</literal>, which is not specified:
+
+<screen>
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(correspondingId) = "border-top-width"
+</screen>
+</para>
+ </listitem>
+ <listitem>
+ <para><literal>PropertyMaker.findProperty</literal>: Is
+this property explicitly specified? Yes. The property value is
+retrieved as:
+<screen>
+ p = "CondLength[2000mpt]"
+</screen>
+The specified value was <literal>2pt</literal>. When this attribute
+value was added to the property list, it was converted to a
+<literal>CondLength</literal> type.
+</para>
+ </listitem>
+
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Add the value to
+the cache.</para>
+</listitem>
+ </itemizedlist>
+</para>
+ </section>
+
+ <section>
+ <title>Retrieving the <literal>border-end-width</literal>
+value on <literal>region-body</literal></title>
+
+<para>This what we are retrieving:
+
+<screen>
+ propertyList.getFOName() = "fo:region-body"
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(propId) = "border-end-width"
+</screen>
+
+The border values are retrieved by the method
+<literal>PropertyManager.getBorderAndPadding</literal>. The call stack
+that leads up to it and on to the retrieval of the value of
+<literal>border-end-width</literal> is identical to the call stack for
+<literal>border-before-width</literal>.
+</para>
+
+<para>The retrieval proceeds as follows:
+<itemizedlist spacing="compact">
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Is the value in
+the cache? No.</para>
+</listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>:
+<literal>corresponding != null</literal>, and
+<literal>corresponding.isCorrespondingForced()</literal> returns
+<literal>true</literal>. The corresponding property is
+<literal>border-right-width</literal>, which is explicitly specified:
+
+<screen>
+ org.apache.fop.fo.FOPropertyMapping.getPropertyName(correspondingId) = "border-right-width"
+</screen>
+</para>
+ </listitem>
+<listitem>
+<para><literal>PropertyMaker.findProperty</literal>: Compute the
+corresponding property value. It is retrieved as:
+<screen>
+ p = "CondLength[discard, 4000mpt]"
+</screen>
+The specified value was <literal>4pt</literal>. When this attribute
+value was added to the property list, it was converted to a
+<literal>CondLength</literal> type.</para>
+ </listitem>
+<listitem>
+<para><literal>PropertyList.findProperty</literal>: Add the value to
+the cache.</para>
+</listitem>
+ </itemizedlist>
+</para>
+ </section>
+
+ </section>
+
+ </section>
+
+<!--
+The implementation before bug 26778: Properties leader-length
+
+leader-length.maximum="30%"
+leader-length.minimum="20%"
+leader-length.optimum="25%"
+
+basePropertyName = "leader-length"
+subPropertyName = "maximum"
+propId = 124
+subpropId = 2560
+
+main[1] where
+ [1] org.apache.fop.fo.flow.Leader.getLength (Leader.java:167)
+ [2] org.apache.fop.layoutmgr.AddLMVisitor.getLeaderAllocIPD (AddLMVisitor.java:361)
+ [3] org.apache.fop.layoutmgr.AddLMVisitor$2.getAllocationIPD (AddLMVisitor.java:342)
+ [4] org.apache.fop.layoutmgr.LeafNodeLayoutManager.getNextBreakPoss (LeafNodeLayoutManager.java:166)
+ [5] org.apache.fop.layoutmgr.LineLayoutManager.getNextBreakPoss (LineLayoutManager.java:215)
+ [6] org.apache.fop.layoutmgr.BlockLayoutManager.getNextBreakPoss (BlockLayoutManager.java:240)
+ [7] org.apache.fop.layoutmgr.FlowLayoutManager.getNextBreakPoss (FlowLayoutManager.java:111)
+ [8] org.apache.fop.layoutmgr.PageLayoutManager.getNextBreakPoss (PageLayoutManager.java:261)
+ [9] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:226)
+
+propId = Constants.PR_LEADER_LENGTH | Constants.CP_MAXIMUM
+ = 2684 = 124 + 2560
+
+In this older implementation the base value is obtained from the
+layout context and propagated to the calculation:
+
+LeafNodeLayoutManager.getNextBreakPoss:
+ ipd = getAllocationIPD(context.getRefIPD());
+AddLMVisitor.getLeaderAllocIPD:
+ node.getLength(Constants.PR_LEADER_LENGTH | Constants.CP_MAXIMUM, ipd);
+Leader.getLength:
+ length = (int)(((PercentLength) maxlength).value() * dim);
+
+This is wrong because it does not find out at which node the property
+is specified and from which node the base length should be
+obtained. In the new implementation LengthBase contains this
+information as member parentFO:
+main[1] dump maxlength
+ maxlength = {
+ factor: 0.3
+ lbase: instance of org.apache.fop.datatypes.LengthBase(id=773)
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+main[1] dump maxlength.lbase
+ maxlength.lbase = {
+ parentFO: instance of org.apache.fop.fo.flow.Block(id=776)
+ propertyList: instance of org.apache.fop.fo.PropertyList(id=777)
+ iBaseType: 3
+}
+
+Result:
+ipd = "MinOptMax: min=67520; opt=84400; max=101280"
+-->
+
+ <section>
+ <title>Percent-based and mixed property values</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>Properties may have relative values, expressed as a
+percentage. The value is relative to a trait of the layout. Therefore
+relative values can only be evaluated when the layout is
+created. The FO tree must store them as an expression.</para>
+
+ <para>The FO spec specifies for each property that can have a
+relative value, which trait is the basis for the evaluation of the
+relative value. FOP maintains that information in the property maker,
+in its member <literal>percentBase</literal>. This is set when the
+maker is created, see <literal>FOPropertyMapping</literal>.</para>
+
+ <para>When the maker creates a relative property value object,
+it stores its own member <literal>percentBase</literal> in the
+property as member <literal>iBaseType</literal>. In this way the
+property value contains the information that is needed at layout time to
+find the trait that is the basis for the calculation of the actual
+value.</para>
+
+ <para>The possible values of the member
+<literal>percentBase</literal> are listed in class
+<literal>LengthBase</literal>. Both the interface
+<literal>PercentBase</literal> and the class
+<literal>LengthBase</literal> define static constants which are used
+as types. The difference is as follows (from an email by Finn Bock,
+edited by me): The idea is that the <literal>PercentBase.XXX</literal>
+types name the stored values and the <literal>LengthBase.XXX</literal>
+types name the algorithms for looking up a base value. Most of the
+time these map one-to-one to each other, but for some I imaged that
+they would be different. For example, <literal>margin-top</literal>
+should really use an algorithm like
+<literal>BLOCK_IPD_OR_PAGEHEIGHT</literal>, which would look for
+either <literal>PercentBase.BLOCK_IPD</literal> or
+<literal>PercentBase.PAGE_HEIGHT</literal>, depending on the FO
+element.</para>
+
+ <para>A <literal>LengthBase</literal> object contains a
+reference to a parent FO node and a reference to a property list. In
+this manner the <literal>LengthBase</literal> value contains the
+information that is needed at layout time to locate the FO node or
+property list which contains the trait that is the basis for the
+calculation of the actual value, irrespective of the FO node at which
+the property is resolved.</para>
+
+ <para>The method <literal>LengthBase.getBaselength</literal>
+uses the base type, member <literal>iBaseType</literal>, to determine
+relative to which layout trait the value should be resolved. If the
+trait is a property value, it is retrieved from the property list, in
+the usual manner. If it is a layout dimension, it is taken from the
+parent FO.</para>
+
+ <para>The interface <literal>Numeric</literal>, which is
+implemented by all classes that can participate in numeric operations,
+uses the notion of <literal>dimension</literal>, which denotes the
+type of numeric: for integers <literal>dimension = 0</literal>, for
+lengths <literal>dimension = 1</literal>.</para>
+
+ <para>The constructor of
+<literal>RelativeNumericProperty</literal> calculates the dimension of
+the new property value object as a combination of the dimensions of
+the operands, depending on the operation:
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>multiplication adds dimensions: 0+0=0, 0+1=1+0=1,</para>
+ </listitem>
+ <listitem>
+ <para>division subtracts dimensions: 0-0=0, 1-0=1, 1-1=0,</para>
+ </listitem>
+ <listitem>
+ <para>other (addition, subtraction) does not change the
+dimensions</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>A <literal>RelativeProperty</literal> contains the
+operation between the operands in its member
+<literal>operation</literal>. It is an integer. Names for the possible
+integer values are listed as static members of class
+<literal>RelativeProperty</literal>.</para>
+
+ <para>Relative and mixed property values are retrieved in the
+usual manner. After retrieval they must be resolved against the
+relevant layout traits. This happens in the method
+<literal>getValue</literal> of <literal>Property</literal> and its
+subclasses.</para>
+
+ <para>A <literal>RelativeNumericProperty</literal> is resolved
+as follows: <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>RelativeNumericProperty.getValue</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>RelativeNumericProperty.getNumericValue</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>RelativeNumericProperty.getResolved</literal>.
+This evaluates the expression tree by recursion. The nodes in the tree
+are <literal>RelativeNumericProperty</literal> objects. The leaf nodes
+are <literal>FixedLength</literal> and
+<literal>PercentLength</literal> objects. On each node
+<literal>getNumericValue</literal> is called. <itemizedlist
+spacing="compact">
+ <listitem>
+ <para>The relative numeric property
+values call <literal>getResolved</literal> again, which descends the
+tree and calls <literal>getNumericValue</literal> on its child
+nodes.</para>
+ </listitem>
+ <listitem>
+ <para>The fixed lengths return their
+millipoints.</para>
+ </listitem>
+ <listitem>
+ <para>The percent lengths return
+<literal>factor * lbase.getBaseLength()</literal> <itemizedlist
+spacing="compact">
+ <listitem>
+ <para><literal>factor</literal> is
+a member of the percent length object.</para>
+ </listitem>
+ <listitem>
+ <para><literal>LengthBase.getBaselength</literal>
+gets the base length from the parent FO <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>FObj.getLayoutDimension</literal>.
+The value is retrieved from the <literal>Map
+layoutDimension</literal>. If that does not contain the desired layout
+dimension, then its parent is consulted, all the way up to
+<literal>fo:root</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+
+ </section>
+
+ <section>
+ <title>Parsing a mixed property value</title>
+
+ <para>Example: <literal>&lt;fo:region-body
+margin="4pt+20%"/></literal>, property being parsed:
+<literal>margin="4pt+20%"</literal>, <literal>propId</literal> =
+134.</para>
+
+<para><literal>PropertyParser.parseProperty</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>next()</literal>, which scans the next token;
+at its return:
+<screen>
+ this = {
+ propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=736)
+ org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 12
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: "4pt"
+ org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 0
+ org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt+20%"
+ org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 7
+ org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: true
+}
+</screen>
+i.e. the whole expression is a single token, it is of type
+<literal>PropertyTokenizer.TOK_NUMERIC</literal> (= 12), the unit is
+2 chars long.</para>
+ </listitem>
+ <listitem>
+ <para>Loop forever. <itemizedlist spacing="compact">
+ <listitem>
+ <para>Analyse the expression. Start with
+<literal>parseAdditiveExpr</literal> <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parseMultiplicativeExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parseUnaryExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parsePrimaryExpr</literal>;
+the unit may be a relative unit (em) which must be resolved against
+the font size <itemizedlist spacing="compact">
+ <listitem>
+ <para>construct a property
+value object:
+<screen>
+prop = "4000mpt"
+prop.getClass() = "class org.apache.fop.fo.properties.FixedLength"
+</screen></para>
+ </listitem>
+ <listitem>
+ <para><literal>next()</literal>:
+scan for the next token;
+<screen>
+ this = {
+ propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=736)
+ org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 8
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: null
+ org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 3
+ org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt+20%"
+ org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 4
+ org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 7
+ org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: false
+}
+</screen>
+the next token is of type <literal>currentToken =
+PropertyTokenizer.TOK_PLUS</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para><literal>next()</literal>:
+scan for the next token;
+<screen>
+ this = {
+ propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=736)
+ org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 14
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: "20%"
+ org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
+ org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 4
+ org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt+20%"
+ org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 7
+ org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 7
+ org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: true
+}
+</screen>
+the next token is of type <literal>currentToken =
+PropertyTokenizer.TOK_PERCENT</literal>.
+The currentTokenValue <literal>20%</literal> is analysed:</para>
+ </listitem>
+ <listitem>
+ <para><literal>parseMultiplicativeExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parseUnaryExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>parsePrimaryExpr</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propInfo.getPercentBase</literal>:
+create a PercentBase property
+<itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>propInfo.getFunctionPercentBase</literal>
+uses a stack of functions stkFunction, which currently <literal>==
+null</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>if (null)
+maker.getPercentBase(fo, plist)</literal>: create and return a
+<literal>LengthBase</literal> property, which implements
+<literal>PercentBase</literal>
+<screen>
+ pcBase = "org.apache.fop.datatypes.LengthBase@171f189"
+ pcBase = {
+ parentFO: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=786)
+ propertyList: instance of org.apache.fop.fo.PropertyList(id=807)
+ iBaseType: 5
+}
+</screen>
+the value of <literal>iBaseType</literal> is derived from
+<literal>maker.percentBase == 5 ==
+LengthBase.BLOCK_WIDTH</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para><literal>pcBase.getDimension</literal>;
+dimension: type of integer, int &rarr; 0, length &rarr; 1; used by
+<literal>PercentBase</literal> and <literal>NumericProperty</literal>;
+<literal>LengthBase</literal> has a dimension of 1</para>
+ </listitem>
+ <listitem>
+ <para>create a
+<literal>PercentLength(pcval, pcBase)</literal>:
+<screen>
+ prop = "20.0%"
+ prop = {
+ factor: 0.2
+ lbase: instance of org.apache.fop.datatypes.LengthBase(id=751)
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+</screen>
+<literal>factor</literal> comes from <literal>pcval</literal>,
+<literal>lbase = pcBase</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>next()</literal>:
+scan for the next token; the next token is of type
+<literal>currentToken = PropertyTokenizer.TOK_EOF</literal>.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>return the <literal>LengthBase</literal>
+property value object</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para><literal>evalAddition(NumericProperty op1,
+NumericProperty op2)</literal>. <literal>op1</literal> and
+<literal>op2</literal> are now <literal>Numeric</literal>, which is an
+interface implemented by <literal>LengthProperty</literal>, of which
+<literal>FixedLength</literal> and <literal>PercentLength</literal>
+are subclasses:
+<screen>
+op1 = instance of org.apache.fop.fo.properties.FixedLength(id=744)
+op2 = instance of org.apache.fop.fo.properties.PercentLength(id=757)
+</screen> <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>NumericOp.addition</literal>
+<itemizedlist spacing="compact">
+ <listitem>
+ <para>Construct a new
+<literal>RelativeNumericProperty</literal> by adding the two
+properties:
+<literal>RelativeNumericProperty(RelativeNumericProperty.ADDITION,
+op1, op2)</literal></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>If <literal>currentToken =
+PropertyTokenizer.TOK_EOF</literal>, break the loop.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist>
+return the <literal>RelativeNumericProperty</literal>:
+<screen>
+ prop = "(4000mpt +20.0%)"
+ prop = {
+ operation: 1
+ op1: instance of org.apache.fop.fo.properties.FixedLength(id=744)
+ op2: instance of org.apache.fop.fo.properties.PercentLength(id=757)
+ dimension: 1
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+</screen>
+The value 1 for the operation corresponds to
+<literal>RelativeProperty.ADDITION</literal>. The value 1 for the
+dimension indicates that this is a length. PropertyList:
+<screen>
+ this = "{margin=[(4000mpt +20.0%)]}"
+</screen></para>
+ </section>
+
+ <section>
+ <title>Resolving a mixed property value</title>
+
+ <para>Example: Resolving the value of the property
+<literal>margin-left</literal> of the FO node
+<literal>fo:region-body</literal>. This value was specified as
+<literal>&lt;fo:region-body margin="4pt+20%"/></literal>.
+<literal>margin</literal> is a shorthand property for
+<literal>margin-left</literal>.</para>
+
+<para>The property list of <literal>fo:region-body</literal> reads:
+<screen>
+ this = "{margin=[(4000mpt +20.0%)]}"
+</screen>
+The retrieved property value is a
+<literal>RelativeNumericProperty</literal>:
+<screen>
+ prop = "(4000mpt +20.0%)"
+ prop = {
+ operation: 1
+ op1: instance of org.apache.fop.fo.properties.FixedLength(id=817)
+ op2: instance of org.apache.fop.fo.properties.PercentLength(id=818)
+ dimension: 1
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+</screen>
+The value 1 for the operation corresponds to
+<literal>RelativeProperty.ADDITION</literal>. The value 1 for the
+dimension indicates that this is a length.
+<screen>
+ op2 = "20.0%"
+ op2 = {
+ factor: 0.2
+ lbase: instance of org.apache.fop.datatypes.LengthBase(id=751)
+ org.apache.fop.fo.properties.Property.specVal: null
+}
+ lbase = "org.apache.fop.datatypes.LengthBase@171f189"
+ lbase = {
+ parentFO: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=786)
+ propertyList: instance of org.apache.fop.fo.PropertyList(id=807)
+ iBaseType: 5
+}
+</screen>
+</para>
+
+<para>The <literal>RelativeNumericProperty</literal> is resolved in
+the method call
+<screen>
+ props.marginLeft =
+ this.propertyList.get(PR_MARGIN_LEFT).getLength().getValue();
+</screen>
+in <literal>PropertyManager.getMarginProps()</literal>.
+<literal>getLength()</literal> is a sort of cast; it returns the
+property value if it is a length. The <literal>getValue()</literal>
+method invoked is
+<literal>RelativeNumericProperty.getValue()</literal>.
+This calls
+<literal>RelativeNumericProperty.getNumericValue()</literal>, which
+calls <literal>RelativeNumericProperty.getResolved()</literal>. This
+invokes the operation on its two operands,
+<literal>NumericOp.addition2</literal>, which invokes
+<literal>getNumericValue()</literal> on each
+operand. <literal>PercentLength.getNumericValue()</literal> calls
+<literal>LengthBase.getBaseLength</literal> on its member
+<literal>lbase</literal>.</para>
+
+<para>Due to its value <literal>iBaseType == 5 ==
+LengthBase.BLOCK_WIDTH</literal> this invokes
+<literal>parentFO.getLayoutDimension(PercentBase.BLOCK_IPD).intValue()</literal>
+on its parent FO. The simple page master FO node does not have any
+layout dimensions, its member <literal>layoutDimension</literal> is
+<literal>null</literal>. Therefore it consults its parent FO. This
+goes all the way up to the root FO node.</para>
+
+<para>The root FO node does have the required layout dimensions, which
+are the page dimensions. These have been set on it
+by the <literal>PageLayoutManager</literal> when the page was created
+in its
+method <literal>createPageAreas</literal>:
+<screen>
+((FObj) fobj.getParent()).setLayoutDimension(PercentBase.BLOCK_IPD,pageWidth)
+((FObj) fobj.getParent()).setLayoutDimension(PercentBase.BLOCK_BPD,pageHeight)
+PercentBase.BLOCK_IPD = 2, PercentBase.BLOCK_BPD = 3
+</screen>
+As a result:
+<screen>
+ layoutDimension = "{2=576000, 3=792000}"
+ key = "2"
+ getName() = "fo:root"
+</screen>
+</para>
+
+<screen>
+ [1] org.apache.fop.fo.FObj.getLayoutDimension (FObj.java:241)
+ [2] org.apache.fop.datatypes.LengthBase.getBaseLength (LengthBase.java:120)
+ [3] org.apache.fop.fo.properties.PercentLength.getNumericValue (PercentLength.java:82)
+ [4] org.apache.fop.fo.expr.NumericOp.addition2 (NumericOp.java:52)
+ [5] org.apache.fop.fo.expr.RelativeNumericProperty.getResolved (RelativeNumericProperty.java:105)
+ [6] org.apache.fop.fo.expr.RelativeNumericProperty.getNumericValue (RelativeNumericProperty.java:132)
+ [7] org.apache.fop.fo.expr.RelativeNumericProperty.getValue (RelativeNumericProperty.java:170)
+ [8] org.apache.fop.fo.PropertyManager.getMarginProps (PropertyManager.java:267)
+</screen>
+
+<para><literal>PercentLength.getNumericValue()</literal> returns the
+page width, which is multiplied by the requested factor of 0.2, and
+added to the value of the fixed length, 4000. The resulting value is
+returned and used for the variable <literal>marginLeft</literal>:
+
+<screen>
+ value = 119200.0
+ props.marginLeft = 119200
+</screen>
+</para>
+
+ </section>
+
+ </section>
+
+</chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->
diff --git a/src/documentation/content/xdocs/DnI/rendering.xml b/src/documentation/content/xdocs/DnI/rendering.xml
new file mode 100644
index 000000000..82f3b429c
--- /dev/null
+++ b/src/documentation/content/xdocs/DnI/rendering.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright 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$ -->
+
+<!--
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "docbookx.dtd">
+ -->
+
+<chapter>
+ <title>Phase 3: Rendering the pages</title>
+
+ <para>It is the task of the rendering phase to describe the area
+tree in the target page description language, so that viewers for that
+language can render the pages. Rendering is done page by page. For
+each page the rendering system is handed a PageViewport, and it walks
+the area subtree below it. For each area it retrieves the traits and
+data, and generates the required output.</para>
+
+ <para>The layout of a page is not finished until all forward
+references on that page have been resolved. As a consequence pages are
+finished out of pagination order. Some renderers support out of
+order rendering of pages,
+<literal>AbstractRenderer.supportsOutOfOrder()</literal>. If a
+renderer does, a finished page is handed over to it
+immediately. Otherwise, the layout system keeps finished pages until
+all preceding pages are also finished and have been handed over to the
+renderer. In principle, the PDF renderer supports out of order
+rendering. In current FOP (27 June 2004) this has been disabled
+because the support is broken.</para>
+
+ <para>This stack at a deep position, rendering a leader in a block
+in a flow in the body region, shows some details of rendering. Note
+how the hierarchy of the area tree can be recognized. The lower
+frames show how the rendering system is called by the layout system:
+
+<screen>
+main[1] where
+ [1] org.apache.fop.render.pdf.PDFRenderer.renderLeader (PDFRenderer.java:1,266)
+ [2] org.apache.fop.render.AbstractRenderer.serveVisitor (AbstractRenderer.java:832)
+ [3] org.apache.fop.area.inline.Leader.acceptVisitor (Leader.java:118)
+ [4] org.apache.fop.render.AbstractRenderer.renderLineArea (AbstractRenderer.java:610)
+ [5] org.apache.fop.render.pdf.PDFRenderer.renderLineArea (PDFRenderer.java:830)
+ [6] org.apache.fop.render.AbstractRenderer.renderBlocks (AbstractRenderer.java:547)
+ [7] org.apache.fop.render.AbstractRenderer.renderBlock (AbstractRenderer.java:588)
+ [8] org.apache.fop.render.pdf.PDFRenderer.renderBlock (PDFRenderer.java:513)
+ [9] org.apache.fop.render.AbstractRenderer.renderBlocks (AbstractRenderer.java:538)
+ [10] org.apache.fop.render.AbstractRenderer.renderFlow (AbstractRenderer.java:473)
+ [11] org.apache.fop.render.AbstractRenderer.renderMainReference (AbstractRenderer.java:456)
+ [12] org.apache.fop.render.AbstractRenderer.renderBodyRegion (AbstractRenderer.java:392)
+ [13] org.apache.fop.render.AbstractRenderer.renderRegionViewport (AbstractRenderer.java:338)
+ [14] org.apache.fop.render.AbstractRenderer.renderPageAreas (AbstractRenderer.java:310)
+ [15] org.apache.fop.render.pdf.PDFRenderer.renderPage (PDFRenderer.java:471)
+ [16] org.apache.fop.area.RenderPagesModel.addPage (RenderPagesModel.java:117)
+ [17] org.apache.fop.area.AreaTree.addPage (AreaTree.java:143)
+ [18] org.apache.fop.layoutmgr.PageLayoutManager.finishPage (PageLayoutManager.java:532)
+ [19] org.apache.fop.layoutmgr.PageLayoutManager.doLayout (PageLayoutManager.java:231)
+</screen></para>
+
+ <para>Obviously there is a lot to be documented about the rendering
+system, and about each renderer separately. Because I do not (yet)
+know much about the rendering system, I will have to leave that task
+to others. I only add the obvious: Rendering requires precise
+programming: spacing and progress calculations, saving and restoring
+dimensions, etc. It also requires tracking the state in the output
+format.</para>
+
+</chapter>
+
+<!-- Local Variables: -->
+<!-- current-language-environment: UTF-8 -->
+<!-- coding: utf-8 -->
+<!-- default-input-method: TeX -->
+<!-- End: -->