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 }