http://xml.apache.org/http://www.apache.org/http://www.w3.org/

Home

Readme
Download
Running FOP
Features
Limitations
Bugs
Examples

Compiling
Embedding
Getting involved
Architecture

FAQs
Specifications
License

Introduction
 

The overall process is controlled by org.apache.fop.apps.Driver. In this class, a typical sequence is:

Driver driver = new Driver();

driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer", version);

driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");

driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");

driver.setWriter(new PrintWriter(new FileWriter(args[1])));

driver.buildFOTree(parser, fileInputSource(args[0]));

driver.format();

driver.render();


Formatting Object Tree
 

The class org.apache.fop.fo.FOTreeBuilder is responsible for actually constructing the FO tree. The key SAX events used are

startElement(),

endElement() and characters().

All formatting objects derive from abstract class org.apache.fop.fo.FONode. The other FO classes inherit from FONode as follows:

            FONode

               |

     __________|________

    |                   |

   FObj               FOText

    |

    |___________________

    |                   |

  FObjMixed      SequenceSpecifier

FO's extending FObj:

Package org.apache.fop.fo.pagination:

LayoutMasterSet

PageSequence

RegionAfter

RegionBefore

RegionBody

Root

SequenceSpecification

SimplePageMaster

Package org.apache.fop.fo.flow:

BlockContainer

DisplayGraphic

DisplayRule

DisplaySequence

Flow

InlineGraphic

ListBlock

ListItem

ListItemBody

ListItemLabel

PageNumber

StaticContent

Table

TableBody

TableCell

TableColumn

TableRow

FO's extending SequenceSpecifier:

Package org.apache.fop.fo.pagination:

SequenceSpecifierAlternating

SequenceSpecifierRepeating

SequenceSpecifierSingle

FO's extending FObjMixed:

Package org.apache.fop.fo.flow:

Block

InlineSequence

SimpleLink


FONode
 

The class inheritance described above only describes the nature of the content. Every FO in FOP also has a parent, and a Vector of children. The parent attribute (in the Java sense), in particular, is used to enforce constraints required by the FO hierarchy.

FONode, among other things, ensures that FO's have a parent, that they have children, that they maintain a marker of where the layout was up to (for FObj's it is the child number, and for FOText's it is the character number), and that they have a layout() method.


Making FO's
 

Every FO class has code that looks something like this:

public static class Maker extends FObj.Maker {

   public FObj make(FObj parent, PropertyList propertyList)

     throws FOPException

   {

     return new SimplePageMaster(parent, propertyList);

   }

}

The class also has a static method that resembles

public static FObj.Maker maker()

   {

     return new PageSequence.Maker();

   }

A hash 'fobjTable' exists in FOTreeBuilder, and maps the FO names (such as 'fo:table') to object references to the appropriate factories (such as Table.Maker).

Properties (recall that FO's have properties, areas have traits, and XML nodes have attributes) are also a concern of FOTreeBuilder. It accomplishes this by using PropertyListBuilder, which contains a hash of property names and their respective makers. The base class for properties is Property, and the property makers extend Property.Maker.


FO Formatting
 

FOTreeBuilder calls format() on the root FO, passing it the AreaTree reference. In turn, Root calls format() on each PageSequence, passing it the AreaTree reference.

The PageSequence format() method does the following things:

  1. Makes a Page, using PageMasterFactory to produce a PageMaster, and using makePage() in the latter class. In the simplest picture, a Page has 5 areas represented by AreaContainers;
  2. Handles layout for StaticContent objects in the 'before' and 'after' regions, if set. This uses the layout() method in StaticContent;
  3. If a page break is not forced, it will continue to layout the flow into the body area (AreaContainer) of the current page;
  4. It continues with (1) when layout into the current page is done, but the flow is not empty.

Area Layout
 

FO's that represent actual areas, starting with Flow and StaticContent, have a layout() method, with the following signature:

public Status layout(Area area)

The fundamental role of the layout() method is to manage the layout of children and/or to generate new areas.

Example: the layout() method for Flow generates no new areas - it manages the layout of the flow children.

Example: the layout() method for Block generates a new BlockArea in and of itself, and also manages the layout of the block children, which are added to the BlockArea before that is itself added to its parent Area.

Layout() methods are subject to the general constraint that possibly not all of their children can be accommodated, and they report back accordingly with an appropriate Status.


Rendering
 

This is a separate process. The render() method in Driver is invoked (say, by CommandLine) with the laid-out AreaTree and a PrintWriter as arguments. This actually calls the render() method in a specific implementation of the Renderer interface, typically PDFRenderer or AWTRenderer.

At the highest level PDFRenderer, for example, begins by rendering each Page. The render() method in Page (as is the case for other areas), invokes a particular method in the renderer of choice, e.g. renderPage(). NOTE: this system is bypassed for Page, incidentally.

Rendering will not be discussed further in this document, as most of our current effort must concentrate on layout. Section 4.12 in the XSL WD discusses some issues applicable to rendering.



Copyright © 1999 The Apache Software Foundation. All Rights Reserved.