FOray Users
Module Users

FOray: Developer Information


This page is a collection of items that aren’t big enough yet to require their own page. Most of the items listed are currently goals, not yet realized.

Mailing Lists

If you would like to monitor or help with FOray development, you are welcome to subscribe to the FOray-developer mailing list. This list is used by the development team to discuss issues and announce changes that may affect other developers. Read-only access to this list is available through its public archive.

You may also subscribe to the FOray-commit mailing list, which emails the log of each repository commit. Read-only access to this list is available through its public archive.


Everyone is free to view project wikis. If you would also like to be able to contribute content, please enquire on the developer mailing list. You will need to have a Sourceforge login.

Wikis are used by FOray only for temporary, "brainstorming", white-boarding purposes. Once design issues are settled, the related content should be moved to a more permanent web page, and removed from the wiki.


The following standard abbreviations may be used in the system:

  • BPD = either Block-Progression-Direction or Block-Progression-Dimension (depending on context).
  • BR = Border Rectangle.
  • char = character
  • CR = Content Rectangle
  • hyph = hyphenation
  • IPD = either Inline-Progression-Direction or Inline-Progression-Dimension (depending on context).
  • LAR = Large Allocation Rectangle.
  • LBS = Line-breaking Strategy.
  • LS = Layout Strategy
  • NAR = Normal Allocation Rectangle.
  • PL = Pioneer Layout. The first (and currently only) Layout Strategy implemented directly within FOray.
  • PR = Padding Rectangle.
  • RA = Reference Area
  • VP = Viewport

Outer-Layer API

The API exposed to users should be as simple as possible. There are three major processes that FOray performs for each document. In addition, we want an object that will manage multiple documents. So, we want four objects:

  1. Session. Manages multiple documents.
  2. Document. Manages the process of building the FOTree.
  3. RenderContext. Manages the process of layout.
  4. Renderer. Manages the process of rendering.

RenderContext can actually be inferred from the Renderer(s) chosen. However, it may need to be exposed so that a LayoutStrategy can be chosen.


The division of FOray processing into strict modules with well-defined interfaces is a fundamental part of the design philosophy, for several reasons:

  • It generally results in a cleaner design when the developer must consider in which module a class, variable, or method should reside.
  • Modularization makes the product potentially useful to a wider audience. For example, someone wishing to write a non-FO application might find FOrayFont very useful. Similarly, someone using FO to generate an audio application might find FOrayFOTree useful, even though FOray has no current plans for audio support.
  • There are great potential advantages to being able to mix-and-match components from different systems. At the very least, this kind of flexibility allows rewrites to be done only on the module needing to be rewritten, without disrupting other system components.


Every object fits into a tree of some sort. That is, it has a parent and possibly children, and these are cross-referenced. This concept is true even of classes that mostly do processing. This means that there should in general be no duplication of data, at least for items that are in a common branch. The trick then is to find the optimal place for the data to live and provide access to it. For example, we do not need logger instances in every FO node. Instead store it at the top of the tree, and use a recursive function to get it from the top of the tree when it is needed. The assumption here is that the cost of getting to it is minimal, and is generally more than offset by the benefits of using less memory and having a cleaner design. When these are not true, exceptions should be made.

Here is the diagram of the big tree:

 Document ----------> RenderContext -----------> Renderer
         |                    |
         |--Build FOTree      |--Layout
         |                    |
         |--FOTree            |--AreaTree
             |                    |
             |--PageSequence      |--Page
                |                    |
                |-- etc.             |--Area
                                        |-- etc.]]>

In the diagram above, "Build FOTree" and "Layout" will also likely have sub-trees of objects that should know how to get data out of Session and Document (at least through some appropriate interface).

Independent APIs

In addition to breaking FO processing up into smaller pieces, we want to write totally abstract packages to be used as APIs for developers, and to which our packages would be compliant. If this worked properly, the "best of breed" could be used for each of the components. This is low-priority, but interesting for future efforts toward merging code with FOP and other systems. The packages identified so far that would benefit from such an API are: Fonts, FOTree, AreaTree Bound Input, AreaTree Free Input, AreaTree Output, and Layout.

The work and documentation for this project have been moved to aXSL so that other developers can use it and contribute to it. FOray intends to use the "AreaTree Bound Input" concept described there for its processing.

Data Model

FOray would eventually like to evolve into a WYSIWIG XML editor, comparable to (for example) Adobe FrameMaker. It has therefore adopted a data model that requires it to leave the FO Tree intact. In other words, if you start with an FO document, then process that document in FOray, you should then be able to dump the FO Tree back out unchanged (except for whitespace or pretty-print types of changes).

Settled Development Principles

The items in this section are not hard rules. They can be broken if needed, but the presumption will be against them, i.e. there needs to be a really good reason for breaking them.

  • Don't maintain different versions of code for different platforms. Java has no pre-processing capabilities, and this is probably for the better. If our minimum version is n, and we wish to use a feature in n + 1, we should probably either wait or upgrade the minimum.
  • Don't rewrite the code. Refactor instead. Evolution instead of revolution. If that looks impossible, it is probably due to a lack of imagination on your part. A rewrite is a de facto fork, and it kills projects. Closely related to this is adhering to "release early, release often."
  • Keep working code on the trunk. If portions of code need to be rewritten (as opposed to refactored), that is experimental code until it is ready to be merged back onto the trunk. It is always the responsibility of those writing experimental code to keep it synced (as needed) with the main line of development, not vice versa.


Patches and any other contributions of code or other resources must be owned by the person submitting or contributing. In other words, don’t give it away unless it belongs to you. Submission of a patch or other contribution is an assertion of ownership of the code unless it is cleary stated otherwise.

Patches are most useful when submitted as a unified diff against a recent version of the source code repository.

Patches are managed through the SourceForge Tracker system (thank you SourceForge!). Here are the key links:

To help protect the integrity of code contributions, you will need to log in as a SourceForge user to submit a patch.


Our infrastructure wish list includes the following:

  • The ability to have automated nightly builds, with the results of these builds (including javadoc) made available through our website.
  • An XSLT engine and tools like Cocoon for taking xml documentation and converting it to html in an automated way. (As of 11-1-2004, Sourceforge says they have some web server enhancements coming. These may address this issue).
  • An xml-to-pdf engine (like FOray) available on the web server for generating PDF manuals directly from xml documentation. (This may be addressed by the Sourceforge enhancements noted above).

Miscellaneous Notes

Coordinates to locations on a page are described using the Cartesian system. That is, the point of origin (0, 0) is the lower left corner of the page. An increased X value describes a point farther right on the page. An increased Y value describes a point higher on the page. Example: The point (72000, 0) describes a point at the bottom edge of the page (Y = 0) and 1 inch to the right of left edge of the page (X = 72000). Units are expressed in millipoints (1/1000 of a point).