Phase 2: Building the Area tree
Initiating the layout process
In the PageSequence.endOfNode() method, the
AreaTreeHandler object
foEventHandler's method
endPageSequence is called. This method constructs a
PageSequenceLayoutManager for the
PageSequence FO node, which manages all page-related
layout.
org.apache.fop.fo.pagination.PageSequence.endOfNode():
this.getFOEventHandler().getFOEventHandler().endPageSequence(this):
-> foTreeBuilder.getFOEventHandler().endPageSequence(this)
-> foEventHandler.endPageSequence(this) (type AreaTreeHandler):
This method creates a new
PageSequenceLayoutManager for the
PageSequence FO node. The pages in this page sequence
are completely layed out by the
PageSequenceLayoutManager, in its
activateLayout method. The first step in the layout
process is getting the page setup from the page masters. Then the FO tree
is processed.
[1] org.apache.fop.layoutmgr.PageSequenceLayoutManager.activateLayout (PageLayoutManager.java:211)
[2] org.apache.fop.fo.area.AreaTreeHandler.endPageSequence (AreaTreeHandler.java:242)
[3] org.apache.fop.fo.pagination.PageSequence.endOfNode (PageSequence.java:202)
[4] org.apache.fop.fo.FOTreeBuilder.endElement (FOTreeBuilder.java:292)
... parser stuff
[13] org.apache.xerces.parsers.AbstractSAXParser.parse (null)
[14] org.apache.xalan.transformer.TransformerIdentityImpl.transform (null)
[15] org.apache.fop.apps.InputHandler.render (InputHandler.java:120)
[16] org.apache.fop.apps.Fop.main (Fop.java:102)
main[1] dump pageSLM
pageSLM = {
areaTreeHandler= org.apache.fop.area.AreaTreeHandler (id=79)
areaTreeModel= org.apache.fop.area.RenderPagesModel (id=81)
bFinished= false
bFirstPage= false
bInited= false
childLMiter= org.apache.fop.layoutmgr.LMiter (id=85)
childLMs= java.util.ArrayList (id=89)
curBody= null
curChildLM= null
curFlow= null
curPage= null
currentSimplePageMaster= null
curSpan= null
curSpanColumns= 0
flowBPD= 0
flowIPD= 0
fobj= org.apache.fop.fo.pagination.PageSequence (id=12)
fobjIter= java.util.AbstractList$ListItr (id=90)
isFirstPage= true
markers= null
pageCount= 1
pageNumberGenerator= null
pageNumberString= null
parentLM= null
staticContentLMs= java.util.HashMap (id=93)
}
The above calling sequence contains one configuration
point. FOP's area tree building process can be modified by
registering a different LayoutManagerMaker with the Area tree
handler. The LayoutManagerMaker controls the creation of Layout
Managers.
TO BE EXPANDED
Creating the page and body areas
Overview
Create the layout (activateLayout)
First create a new Page Viewport
(makeNewPage).
First finish the current page
(finishPage).
Then create the new page viewport
(createPage).
First get the page master
(getSimplePageMasterToUse,
pageSequence.getPageSequenceMaster or
pageSequence.getSimplePageMaster).
Then get the body
(currentSimplePageMaster.getRegion, from
currentSimplePageMaster's
regions map).
Then create the page viewport
(createPageAreas(currentSimplePageMaster)).
From the properties of the page
master create the page reference rectangle, a new page, a new
FODimension object, and a CTM object.
For each region in the page master
(in our example we only have a body):
make a region viewport
(makeRegionViewport), which involves calculating
the position of the region on the page, using the FODimension and CTM
objects.
make the reference area
(makeRegionBodyReferenceArea,
makeRegionReferenceArea).
At this point the page viewport and its region viewports
have been laid out.
Then create the body's main reference area
(createBodyMainReferenceArea).
Then create a Span
(createSpan).
And get the flowIPD
(curFlow.getIPD()).
At this point the body has a single span area with a
single flow area without children.
Detailed view
The call stack when creating the region viewports:
[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.activateLayout (PageLayoutManager.java:220)
At the end of createPageAreas the following
properties of the page have been established:
The page reference rectangle:
pageRefRect = {
x: 56692
y: 56692
width: 481891
height: 728505
serialVersionUID: -4345857070255674764
}
The page reference area:
page = {
regionBefore: null
regionStart: null
regionBody: instance of org.apache.fop.area.RegionViewport(id=1279)
regionEnd: null
regionAfter: null
unresolved: null
}
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
}
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
}
page.regionBody.viewArea = {
x: 56692
y: 56692
width: 481891
height: 728505
serialVersionUID: -4345857070255674764
}
The PageViewport is returned:
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
}
When makeNewPage returns, the Page
LayoutManager has a Page Viewport and a Body Region object. The layout
dimensions have been calculated:
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
}
The method createBodyMainReferenceArea() adds
a MainReferenceArea to the body region:
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
}
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
}
curBody.mainReference.spanAreas = "[]"
After createSpan(1):
curBody.mainReference.spanAreas = "[org.apache.fop.area.Span@1581e80]"
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
}