aboutsummaryrefslogtreecommitdiffstats
path: root/src/documentation/content/xdocs/design/layout.xml
diff options
context:
space:
mode:
Diffstat (limited to 'src/documentation/content/xdocs/design/layout.xml')
-rw-r--r--src/documentation/content/xdocs/design/layout.xml465
1 files changed, 465 insertions, 0 deletions
diff --git a/src/documentation/content/xdocs/design/layout.xml b/src/documentation/content/xdocs/design/layout.xml
new file mode 100644
index 000000000..0f08bcb66
--- /dev/null
+++ b/src/documentation/content/xdocs/design/layout.xml
@@ -0,0 +1,465 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">
+
+<document>
+ <header>
+ <title>Layout</title>
+ <subtitle>Layout Process in FOP</subtitle>
+ <authors>
+ <person name="Keiron Liddle" email="keiron@aftexsw.com"/>
+ </authors>
+ </header>
+
+ <body>
+<section>
+ <title>FO Layout</title>
+<p>
+The aim of the layout system is to be self contained and allow for
+easy changes or extensions for future development. For example the
+line breaking should be decided at a particular point in the process
+that makes it easier to handle other languages.
+ </p>
+ <p>
+The layout begins once the hierarchy of FO objects has been constructed.
+Note: it may be possible to start immediately after a block formatting
+object has been added to the flow but this is not currently in the scope
+of the layout. It is also possible to layout all pages in a page sequence
+after each page sequence has been added from the xml.
+ </p>
+ <p>
+The layout process is handled by a set of layout managers. The block
+level layout managers are used to create the block areas which are
+added to the region area of a page.
+ </p>
+<section>
+ <title>Layout Managers</title>
+ <p>
+The layout managers are set up from the hierarchy of the formatting
+object tree. A manager represents a hierachy of area producing objects.
+A manager is able to handle the block area(s) that it creates and
+organise or split areas for page breaks.
+ </p>
+ <p>
+Normally any object that creates a block area will have an associated
+layout manager. Other cases are tables and lists, these objects will
+also have layout managers that will manager the group of layout managers
+that make up the object.
+ </p>
+ <p>
+A layout manager is also able to determine height (min/max/optimum)
+and keep status. This will be used when organising the layout on
+a page. The manager will be able to determine the next place a break
+can be made and then be able to organise the height.
+ </p>
+ <p>
+A layout manager is essentially a bridge between the formatting objects
+and the area tree. It will keep a list of line areas inside block areas.
+Each line area will contain a list of inline areas that is able to be
+adjusted if the need arises.
+ </p>
+ <p>
+The objects in the area tree that are organised by the manager will mostly
+contain the information about there layout such as spacing and keeps, this
+information will be thrown away once the layout for a page is finalised.
+ </p>
+ </section>
+<section>
+ <title>Creating Managers</title>
+ <p>
+The managers are created by the page sequence. The top level manager
+is the Page manager. This asks the flow to add all managers in this
+page sequence.
+ </p>
+ <p>
+For block level objects they have a layout manager. Neutral objects
+don't represent any areas but are used to contain a block level
+area and as such these objects will ask the appropriate child to
+create a layout manager.
+ </p>
+ <p>
+Any nested block areas or inline areas may be handled by the layout
+manager at a later stage.
+ </p>
+ </section>
+<section>
+ <title>Using Managers</title>
+ <p>
+Block area layout managers are used to create a block area, other block
+level managers may ask their child layout managers to create block areas
+which are then added to the area tree (subset).
+ </p>
+ <p>
+A manager is used to add areas to a page until the page is full,
+then the manages contain all the information necessary to make
+the decision about page break and spacing. A manager can split an
+area that it has created will keep a status about what has been
+added to the current area tree.
+ </p>
+ </section>
+<section>
+ <title>Page Layout</title>
+ <p>
+Once the Page layout manager, belonging to the page sequence, is ready
+then we can start laying out each page. The page sequence will create
+the current page to put the page data, the next page and if it exists
+a last page.
+ </p>
+ <p>
+The current page will have the areas added to it from the block layout
+managers. The next page will be used when splitting a block that goes
+over the page break. Note: any page break overrides the layout decided
+here. The last page will be necessary if the last block area is added
+to this page. The size of the last page will be considered and the
+areas will be added to the last page instead.
+ </p>
+ <p>
+The first step is to add areas to the current page until the area is full
+and the lines of the last block area contain at least n(orphans) and at least
+n(orphans) + n(widows) in total. This will only be relevant for areas at
+the start or end of a particular reference area.
+ </p>
+ <p>
+ <image src="page.svg"/>
+ </p>
+ <p>
+The spacing between the areas (including spacing in block areas inside
+an inline-container) will be set to the minimum values. This will allow
+the page to have at least all the information it needs to organise the
+page properly.
+ </p>
+ <p>
+This should handle the situation where there are keeps on some
+block areas that go over the end of the page better. It is possible that
+fitting the blocks on the page using a spacing between min and optimum
+would give a closer value to the optimum than putting the blocks on the
+next page and the spacing being between optimum and max. So if the objects
+are placed first at optimum then you will need to keep going to see if
+there is a lower keep further on that has a spacing that is closer to the
+optimum.
+ </p>
+ <p>
+The spacing and keep information is stored so that the area positions
+and sizes can be adjusted.
+ </p>
+ </section>
+<section>
+ <title>Balancing Page</title>
+ <p>
+The page is vertically justified so that it distributes the areas
+on the page for the best result when considering keeps and spacing.
+ </p>
+ </section>
+<section>
+ <title>Finding Break</title>
+ <p>
+First the keeps are checked. The available space on the page may have
+changed due to the presence of before floats or footnotes. The page break
+will need to be at a height &lt;= the available space on the page.
+ </p>
+ <p>
+A page break should be made at the first available position that
+has the lowest keep value when searching from the bottom. Once the first
+possible break is found then the next possible break, with equally low
+keep value, is considered. If the height of the page is closer to the
+optimal spacing then this break will be used instead.
+ </p>
+ <p>
+Keep values include implicit and explicit values when trying to
+split a block area into more than one area. Implicit keeps may
+be such things as widows/orphans.
+ </p>
+ <p>
+If the page contains before floats or footnotes then as each area or line
+area is removed the float/footnote should also be removed. This will
+change the available space and is a one way operation. The footnote
+should be removed first as a footnote may be placed on the next page.
+The lowest keep value may need to be reassessed as each conditional
+area is removed.
+ </p>
+ <p>
+The before float and footnote regions are managed so that the separator
+regions will be present if it contains at least one area.
+ </p>
+ </section>
+<section>
+ <title>Optimising</title>
+ <p>
+Once the areas for the page are finalised then the spacing will
+need to be adjusted. The available height on the page is compared
+with the min and max spacing. All of the spacing in all the areas
+on the page is then adjusted by the appropriate percentage value.
+ </p>
+ </section>
+<section>
+ <title>Multi-Column Pages</title>
+ <p>
+In the case of multi-column pages the column breaks and eventually
+the page break must be found in a slightly different way.
+ </p>
+ <p>
+The columns need to be layed out completely from first to last but
+this can only be done after a rough estimate of all the elements
+on the page in case of before floats or footnotes.
+ </p>
+ <p>
+So first the complete page is layed out with all columns filled
+with areas and the spacing at a minimum. Then if there are any
+before floats or footnotes then the availabe space is adjusted.
+Then each the best break is found for each column starting from
+the first column. If any before floats or footnotes are removed
+as a result of the new breaks and optimised spacing then all the
+columns should still be layed out for the same column height.
+ </p>
+ </section>
+<section>
+ <title>Completing Page</title>
+ <p>
+After the region body has been finished the static areas can be
+layed out. The width of the static area is set and the height is
+inifinite, that is all block areas should be placed in the area
+and their visibility is controlled be other factors.
+ </p>
+ <p>
+The area tree for the region body will contain the information
+about markers that may be necessary for the retrieve marker.
+ </p>
+ <p>
+The ordering of the area tree must be adjusted so that the areas are
+before, start, body, end and after in that order. The body region
+should be in the order before float, main then footnote.
+ </p>
+ </section>
+<section>
+ <title>Line Areas</title>
+ <p>
+Creating a line areas uses a similair concept. Each inline area
+is placed across the available space until there is no room left.
+The line is then split by considering all keeps and spacing.
+ </p>
+ <p>
+Each word (group of adjacent character inline areas) will have keeps
+based on hyphenation. The line break is at the lowest keep value
+starting from the end of the line.
+ </p>
+ <p>
+Once a line has been layed out for a particular width
+then that line is fixed for the page (except for unresolved
+page references).
+ </p>
+ </section>
+<section>
+ <title>Before Floats and Footnotes</title>
+ <p>
+The before float region and footnote region are handled by the page
+layoutmanger. These regions will handle the addition and removal
+of the separator regions when before floats/footnotes area added
+and removed.
+ </p>
+ </section>
+<section>
+ <title>Side Floats</title>
+ <p>
+If a float anchor is present in a particular line area then the available
+space for that line (and other in the block) will be reduced. The side float
+adds to the height of the block area and this height also depends
+on the clear value of subsequent blocks. The keep status of the block is
+also effected as there must be enough space on the page to fit the
+side float.
+ </p>
+ <p>
+<image src="float.svg"/>
+ </p>
+ </section>
+<section>
+ <title>Unresolved Areas</title>
+ <p>
+Once the layout of the page is complete there may be unresolved areas.
+ </p>
+ <p>
+Page number citations and links may require following pages to be
+layed out before they can be resolved. These will remain in the
+area tree as unresolved areas.
+ </p>
+ <p>
+As each page is completed the list of unresolved id's will be checked
+and if the id can be resolved it will be. Once all id's are resolved
+then the page can be rendered.
+ </p>
+ <p>
+Each page contains a map of all unresolved id's and the corresponding
+areas.
+ </p>
+ <p>
+In the case of page number citations. The areas reserves the equivalent
+of 3 number nines in the current font. When the area is resolved
+then the area is adjusted to its proper size and the line area is
+re-aligned to accomodate the change.
+ </p>
+ </section>
+<section>
+ <title>ID and Link Areas</title>
+ <p>
+Any formatting object that has an ID or any inline link defines an area
+that will be required when rendering and resolving id references.
+ </p>
+ <p>
+This area is stored in the parent area and may be a shape that exists
+in more than one page, for example over a page break. This shape consists
+of the boundary of all inline (or block) areas that the shape is defined
+for.
+ </p>
+ </section>
+<section>
+ <title>Inline Areas</title>
+ <p>
+This is the definition of all inline areas that will exist in the
+area.
+ </p>
+ </section>
+<section>
+ <title>Fixed Areas</title>
+ <p>
+instream-foreign-object, external-graphic, inline-container
+ </p>
+ <p>
+These areas have a fixed width and height. They also have a viewport.
+ </p>
+ </section>
+<section>
+ <title>Stretch Areas</title>
+ <p>
+leader, inline space
+ </p>
+ <p>
+These areas have a fixed height but the width may vary.
+ </p>
+ </section>
+<section>
+ <title>Character Areas</title>
+ <p>
+character
+ </p>
+ <p>
+This is an simple character that has fixed properties according to
+the current font. There are implicit keeps with adjacent characters.
+ </p>
+ </section>
+<section>
+ <title>Anchor Areas</title>
+ <p>
+float anchor, footnote anchor
+ </p>
+ <p>
+This area has no size. It keeps the position for footnotes and floats
+and has a keep with the associated inline area.
+ </p>
+ </section>
+<section>
+ <title>Unresolved Page Numbers</title>
+ <p>
+page-number-citation
+ </p>
+ <p>
+A page number area that needs resolving, behaves as a character and
+has the space of 3 normal characters reserved. The size will adjust
+when the value is resolved.
+ </p>
+ </section>
+<section>
+ <title>Block Areas</title>
+ <p>
+The block area has info about the following:
+ <ul>
+ <li><p>
+all anchors including which lines they are on
+ </p></li>
+ <li><p>
+unresolved page references with line info
+ </p></li>
+ <li><p>
+id and link areas
+ </p></li>
+ <li><p>
+height (min/max/optimum) or area including floats
+ </p></li>
+ <li><p>
+holds space before/after and keep information
+ </p></li>
+ <li><p>
+widows and orphans
+ </p></li>
+ </ul>
+ </p>
+ <p>
+Once the layout has been finalised then this information can be
+discarded.
+ </p>
+ </section>
+<section>
+ <title>Page Areas</title>
+ <p>
+Contains inforamtion about all the block areas in the body,
+before area and footer area.
+ </p>
+ <p>
+Has a list of the unresolved page references and a list of id refences
+that can be used to obtain the area associated with that id.
+ </p>
+ </section>
+<section>
+ <title>Test Cases</title>
+ <p>
+Here a few layout possibilities areas explored to determine how the
+layout process will handle these situations.
+ </p>
+<section>
+ <title>Simple Pages</title>
+ <p>
+All blocks (including nested) are placed on the page with minimum spacing
+and the last block has the minimum number of lines past the page end.
+The lowest keep value is then found within the body area limits. Then the next
+equally low keep is found to determine if the spacing will be closer to
+the optimum values.
+ </p>
+ </section>
+<section>
+ <title>Before Floats/Footnotes</title>
+ <p>
+After filling the page with the block areas then the new body height
+is used to find the best position to break. Before each line area or block
+area is remove any associated before floats and footnotes are removed.
+This will then adjust the available space on the page and may allow
+for a different breaking point. Areas are removed towards the new
+breaking point until the areas fit on the page. When finding the
+optimum spacing the removal of before floats and footnotes must also
+be considered.
+ </p>
+ </section>
+<section>
+ <title>Multicolumn</title>
+ <p>
+First the page is filled with all columns for the intial page area.
+Then each column is adjusted for the new height starting from the
+first column. The best break for the column is found then the next
+column is considered, any left over areas a pre-pended to the next
+column. Once all the columns are finished then all the columns are
+adjusted to fit in the same height columns. This handles the situation
+where before floats or footnotes may have been removed.
+ </p>
+ </section>
+<section>
+ <title>Last Page</title>
+ <p>
+If in the process of adding areas to a page it is found that there
+are no more areas in the flow then this page will need to be changed to
+the last page (if applicable). The areas are then placed on a last
+page.
+ </p>
+ </section>
+ </section>
+
+ </section>
+
+ </body>
+</document>
+