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

Home

Readme
Download
Running FOP
Features
Limitations
Examples
Configuration
Fonts
Extensions

Compiling
Embedding
Getting involved
Architecture

Bugs
FAQ
Resources
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.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
driver.setOutputStream(new FileOutputStream(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

Inline

BasicLink


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 a PropertyListBuilder. There is a separate PropertyListBuilder for each namespace encountered while building the FO tree. Each Builder object contains a hash of property names and their respective makers. It may also contain element-specific property maker hashes; these are based on the local name of the flow object, ie. table-row, not fo:table-row. If an element-specific property mapping exists, it is preferred to the generic mapping.

The base class for all properties is Property, and all the property makers extend Property.Maker. A more complete discussion of the property architecture may be found in Properties.


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.


Renderers
 
PrintRenderer
 

The PrintRenderer is an abstract base class for print type renderers. Currently the PCL, PDF, and TXT renderers extend from this. This allows as much common functionality to be contained in one place as possible (at least as much as I could consolidate fairly quickly). Unfortunately I have not yet been able to make the renderPage and renderWordArea methods common. This is unfortunate because these methods seem to experience the most activity. Maybe soneone else will have a clever solution to this (without breaking them into a bunch of little bits).

It is my hope that this base class will be useful for other renderers as well.


PCLRenderer
 

The PCLRenderer is a FOP renderer that should produce output as close to identical as possible to the printed output of the PDFRenderer within the limitations of the renderer, and output device.

The output created by the PCLRenderer is generic PCL 5 as documented in the "HP PCL 5 Printer Language Technical Reference Manual" (copyright 1990). This should allow any device fully supporting PCL 5 to be able to print the output generated by the PCLRenderer.

Limitations
 
  • Text or graphics outside the left or top of the printable area are not rendered properly. In general things that should print to the left of the printable area are shifted to the right so that they start at the left edge of the printable area and an error message is generated.
  • The Helvetica and Times fonts are not well supported among PCL printers so Helvetica is mapped to Arial and Times is mapped to Times New. This is done in the PCLRenderer, no changes are required in the FO's. The metrics and appearance for Helvetica/Arial and Times/Times New are nearly identical, so this has not been a problem so far.
  • Only the original fonts built into FOP are supported.
  • For the non-symbol fonts, the ISO 8859/1 symbol set is used (PCL set "0N").
  • Multibyte characters are not supported.
  • SVG support is limited. Currently only lines, rectangles (may be rounded), circles, ellipses, text, simple paths, and images are supported. Colors are supported (dithered black and white) but not gradients.
  • Images print black and white only (not dithered). When the renderer prints a color image it uses a threshold value, colors above the threshold are printed as white and below are black. If you need to print a non-monochrome image you should dither it first.
  • Image scaling is accomplished by modifying the effective resolution of the image data. The available resolutions are 75, 100, 150, 300, and 600 DPI.
  • Color printing is not supported. Colors are rendered by mapping the color intensity to one of the PCL fill shades (from white to black in 9 steps).
  • SVG clipping is not supported.

Additional Features
 

There are some special features that are controlled by some public variables on the PCLRenderer class.

orientation

The logical page orientation is controlled by the public orientation variable. Legal values are:

  • 0 Portrait
  • 1 Landscape
  • 2 Reverse Portrait
  • 3 Reverse Landscape
curdiv, paperheight The curdiv and paperheight variables allow multiple virtual pages to be printed on a piece of paper. This allows a standard laser printer to use perforated paper where every perforation will represent an individual page. The paperheight sets the height of a piece of paper in decipoints. This will be divided by the page.getHeight() to determine the number of equal sized divisions (pages) that will fit on the paper. The curdiv variable may be read/written to get/set the current division on the page (to set the starting division and read the ending division for multiple invocations). topmargin, leftmargin The topmargin and leftmargin may be used to increase the top and left margins for printing.


TXTRenderer
 

The TXTRenderer is a FOP renderer that produces plain ASCII text output that attempts to match the output of the PDFRenderer as closely as possible. This was originally developed to accommodate an archive system that could only accept plain text files. Of course when limited to plain fixed pitch text the output does not always look very good.

The TXTRenderer works with a fixed size page buffer. The size of this buffer is controlled with the textCPI and textLPI public variables. The textCPI is the effective horizontal characters per inch to use. The textLPI is the vertical lines per inch to use. From these values and the page width and height the size of the buffer is calculated. The formatting objects to be rendered are then mapped to this grid. Graphic elements (lines, borders, etc) are assigned a lower priority than text, so text will overwrite any graphic element representations.



UML Diagrams
 

You can find UML diagramms for all Fop packages (latest release version) here.


SVG
 

FOP supports some svg rendering. SVG is supported as an instream-foreign-object embedded in an FO document. FOP also supports rendering of an external SVG image.

Since the intream object that contains the SVG returns a single fo area then the construction of the SVG document is handled differently. The SVG is created by calling the createGraphic() on each SVG element. The element is then responsible for loading the necessary information and child elements and creating the corresponding SVG DOM element. When the FO tree is being layed out the SVG tree is turned into the SVG DOM document which is stored for later rendering.

The SVG document is then held as a DOM tree which is then rendered by going through the elements of the tree and rendering then in turn.

For more information see the SVG documentation.



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