123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 |
- /*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.fo;
-
- // Java
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.HashSet;
- import java.util.Iterator;
-
- // SAX
- import org.xml.sax.SAXException;
-
- // FOP
- import org.apache.fop.apps.FOUserAgent;
- import org.apache.fop.apps.FOPException;
- import org.apache.fop.area.AreaTree;
- import org.apache.fop.area.Title;
- import org.apache.fop.fo.extensions.Bookmarks;
- import org.apache.fop.fo.flow.BasicLink;
- import org.apache.fop.fo.flow.Block;
- import org.apache.fop.fo.flow.ExternalGraphic;
- import org.apache.fop.fo.flow.Footnote;
- import org.apache.fop.fo.flow.FootnoteBody;
- import org.apache.fop.fo.flow.InstreamForeignObject;
- import org.apache.fop.fo.flow.Inline;
- import org.apache.fop.fo.flow.Leader;
- import org.apache.fop.fo.flow.ListBlock;
- import org.apache.fop.fo.flow.ListItem;
- import org.apache.fop.fo.flow.PageNumber;
- import org.apache.fop.fo.flow.Table;
- import org.apache.fop.fo.flow.TableColumn;
- import org.apache.fop.fo.flow.TableBody;
- import org.apache.fop.fo.flow.TableCell;
- import org.apache.fop.fo.flow.TableRow;
- import org.apache.fop.fo.pagination.Flow;
- import org.apache.fop.fo.pagination.PageSequence;
- import org.apache.fop.layoutmgr.AddLMVisitor;
- import org.apache.fop.layoutmgr.ContentLayoutManager;
- import org.apache.fop.layoutmgr.InlineStackingLayoutManager;
- import org.apache.fop.layoutmgr.LMiter;
- import org.apache.fop.layoutmgr.PageLayoutManager;
- import org.apache.fop.render.Renderer;
-
-
- /**
- * Defines how SAX events specific to XSL-FO input should be handled when
- * an FO Tree needs to be built.
- * This initiates layout processes and corresponding
- * rendering processes such as start/end.
- * @see FOInputHandler
- */
- public class FOTreeHandler extends FOInputHandler {
-
- // TODO: Collecting of statistics should be configurable
- private final boolean collectStatistics = true;
- private static final boolean MEM_PROFILE_WITH_GC = false;
- private boolean pageSequenceFound = false;
-
- /**
- * Somewhere to get our stats from.
- */
- private Runtime runtime;
-
- /** The current AreaTree for the FOTreeHandler. */
- public AreaTree areaTree;
-
- /**
- * Keep track of the number of pages rendered.
- */
- private int pageCount;
-
- /**
- * Keep track of heap memory allocated,
- * for statistical purposes.
- */
- private long initialMemory;
-
- /**
- * Keep track of time used by renderer.
- */
- private long startTime;
-
- /** Useful only for allowing subclasses of AddLMVisitor to be set by those
- extending FOP **/
- private AddLMVisitor addLMVisitor = null;
-
- /**
- * the renderer to use to output the area tree
- */
- private Renderer renderer;
-
- /**
- * Main constructor
- * @param userAgent the apps.userAgent implementation that governs
- * this FO Tree
- * @param OutputStream stream to use to output results of renderer
- *
- * @param store if true then use the store pages model and keep the
- * area tree in memory
- */
- public FOTreeHandler(FOUserAgent userAgent, int renderType,
- OutputStream stream, boolean store) throws FOPException {
- super(userAgent);
-
- if (foUserAgent.getRendererOverride() != null) {
- renderer = foUserAgent.getRendererOverride();
- } else {
- renderer = createRenderer(renderType);
- renderer.setUserAgent(foUserAgent);
- }
-
- areaTree = new AreaTree(renderer);
-
- try {
- renderer.setupFontInfo(fontInfo);
- // check that the "any,normal,400" font exists
- if (!fontInfo.isSetupValid()) {
- throw new FOPException(
- "No default font defined by OutputConverter");
- }
- renderer.startRenderer(stream);
- } catch (IOException e) {
- throw new FOPException(e);
- }
-
- if (collectStatistics) {
- runtime = Runtime.getRuntime();
- }
- }
-
- /**
- * Creates a Renderer object based on render-type desired
- * @param renderType the type of renderer to use
- * @return Renderer the new Renderer instance
- * @throws IllegalArgumentException if an unsupported renderer type was requested
- */
- private Renderer createRenderer(int renderType) throws IllegalArgumentException {
-
- switch (renderType) {
- case Constants.RENDER_PDF:
- return new org.apache.fop.render.pdf.PDFRenderer();
- case Constants.RENDER_AWT:
- return new org.apache.fop.render.awt.AWTRenderer();
- case Constants.RENDER_PRINT:
- return new org.apache.fop.render.awt.AWTPrintRenderer();
- case Constants.RENDER_PCL:
- return new org.apache.fop.render.pcl.PCLRenderer();
- case Constants.RENDER_PS:
- return new org.apache.fop.render.ps.PSRenderer();
- case Constants.RENDER_TXT:
- return new org.apache.fop.render.txt.TXTRenderer();
- case Constants.RENDER_XML:
- return new org.apache.fop.render.xml.XMLRenderer();
- case Constants.RENDER_SVG:
- return new org.apache.fop.render.svg.SVGRenderer();
- default:
- throw new IllegalArgumentException("Invalid renderer type "
- + renderType);
- }
- }
-
- /**
- * Start the document.
- * This starts the document in the renderer.
- *
- * @throws SAXException if there is an error
- */
- public void startDocument() throws SAXException {
- //Initialize statistics
- if (collectStatistics) {
- pageCount = 0;
- if (MEM_PROFILE_WITH_GC) {
- System.gc(); // This takes time but gives better results
- }
-
- initialMemory = runtime.totalMemory() - runtime.freeMemory();
- startTime = System.currentTimeMillis();
- }
- }
-
- /**
- * End the document.
- *
- * @throws SAXException if there is some error
- */
- public void endDocument() throws SAXException {
- try {
- if (pageSequenceFound == false) {
- throw new SAXException("Error: No fo:page-sequence child " +
- "found within fo:root element.");
- }
- areaTree.endDocument();
- renderer.stopRenderer();
- } catch (IOException ex) {
- throw new SAXException(ex);
- }
-
- if (collectStatistics) {
- if (MEM_PROFILE_WITH_GC) {
- // This takes time but gives better results
- System.gc();
- }
- long memoryNow = runtime.totalMemory() - runtime.freeMemory();
- long memoryUsed = (memoryNow - initialMemory) / 1024L;
- long timeUsed = System.currentTimeMillis() - startTime;
- if (logger != null && logger.isDebugEnabled()) {
- logger.debug("Initial heap size: " + (initialMemory / 1024L) + "Kb");
- logger.debug("Current heap size: " + (memoryNow / 1024L) + "Kb");
- logger.debug("Total memory used: " + memoryUsed + "Kb");
- if (!MEM_PROFILE_WITH_GC) {
- logger.debug(" Memory use is indicative; no GC was performed");
- logger.debug(" These figures should not be used comparatively");
- }
- logger.debug("Total time used: " + timeUsed + "ms");
- logger.debug("Pages rendered: " + pageCount);
- if (pageCount > 0) {
- logger.debug("Avg render time: " + (timeUsed / pageCount) + "ms/page");
- }
- }
- }
- }
-
- /**
- * Start a page sequence.
- * At the start of a page sequence it can start the page sequence
- * on the area tree with the page sequence title.
- *
- * @param pageSeq the page sequence starting
- */
- public void startPageSequence(PageSequence pageSeq) {
- pageSequenceFound = true;
- }
-
- /**
- * End the PageSequence.
- * The PageSequence formats Pages and adds them to the AreaTree.
- * The area tree then handles what happens with the pages.
- *
- * @param pageSequence the page sequence ending
- * @throws FOPException if there is an error formatting the pages
- */
- public void endPageSequence(PageSequence pageSequence)
- throws FOPException {
- //areaTree.setFontInfo(fontInfo);
-
- if (collectStatistics) {
- if (MEM_PROFILE_WITH_GC) {
- // This takes time but gives better results
- System.gc();
- }
- long memoryNow = runtime.totalMemory() - runtime.freeMemory();
- if (logger != null) {
- logger.debug("Current heap size: " + (memoryNow / 1024L) + "Kb");
- }
- }
-
- areaTree.addBookmarksToAreaTree(pageSequence.getRoot().getBookmarks());
- formatPageSequence(pageSequence, areaTree);
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startFlow(Flow)
- */
- public void startFlow(Flow fl) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endFlow(Flow)
- */
- public void endFlow(Flow fl) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startBlock(Block)
- */
- public void startBlock(Block bl) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endBlock(Block)
- */
- public void endBlock(Block bl) {
- }
-
- /**
- *
- * @param inl Inline that is starting.
- */
- public void startInline(Inline inl){
- }
-
- /**
- *
- * @param inl Inline that is ending.
- */
- public void endInline(Inline inl){
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startTable(Table)
- */
- public void startTable(Table tbl) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endTable(Table)
- */
- public void endTable(Table tbl) {
- }
-
- /**
- *
- * @param tc TableColumn that is starting;
- */
- public void startColumn(TableColumn tc) {
- }
-
- /**
- *
- * @param tc TableColumn that is ending;
- */
- public void endColumn(TableColumn tc) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startHeader(TableBody)
- */
- public void startHeader(TableBody th) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endHeader(TableBody)
- */
- public void endHeader(TableBody th) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startFooter(TableBody)
- */
- public void startFooter(TableBody tf) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endFooter(TableBody)
- */
- public void endFooter(TableBody tf) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startBody(TableBody)
- */
- public void startBody(TableBody tb) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endBody(TableBody)
- */
- public void endBody(TableBody tb) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startRow(TableRow)
- */
- public void startRow(TableRow tr) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endRow(TableRow)
- */
- public void endRow(TableRow tr) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startCell(TableCell)
- */
- public void startCell(TableCell tc) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endCell(TableCell)
- */
- public void endCell(TableCell tc) {
- }
-
- // Lists
- /**
- * @see org.apache.fop.fo.FOInputHandler#startList(ListBlock)
- */
- public void startList(ListBlock lb) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endList(ListBlock)
- */
- public void endList(ListBlock lb) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startListItem(ListItem)
- */
- public void startListItem(ListItem li) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endListItem(ListItem)
- */
- public void endListItem(ListItem li) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startListLabel()
- */
- public void startListLabel() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endListLabel()
- */
- public void endListLabel() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startListBody()
- */
- public void startListBody() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endListBody()
- */
- public void endListBody() {
- }
-
- // Static Regions
- /**
- * @see org.apache.fop.fo.FOInputHandler#startStatic()
- */
- public void startStatic() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endStatic()
- */
- public void endStatic() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startMarkup()
- */
- public void startMarkup() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endMarkup()
- */
- public void endMarkup() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startLink(BasicLink basicLink)
- */
- public void startLink(BasicLink basicLink) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endLink()
- */
- public void endLink() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#image(ExternalGraphic)
- */
- public void image(ExternalGraphic eg) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#pageRef()
- */
- public void pageRef() {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#foreignObject(InstreamForeignObject)
- */
- public void foreignObject(InstreamForeignObject ifo) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startFootnote(Footnote)
- */
- public void startFootnote(Footnote footnote) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endFootnote(Footnote)
- */
- public void endFootnote(Footnote footnote) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#startFootnoteBody(FootnoteBody)
- */
- public void startFootnoteBody(FootnoteBody body) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#endFootnoteBody(FootnoteBody)
- */
- public void endFootnoteBody(FootnoteBody body) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#leader(Leader)
- */
- public void leader(Leader l) {
- }
-
- /**
- * @see org.apache.fop.fo.FOInputHandler#characters(char[], int, int)
- */
- public void characters(char[] data, int start, int length) {
- }
-
- /**
- * Runs the formatting of this page sequence into the given area tree
- *
- * @param pageSeq the PageSequence to be formatted
- * @param areaTree the area tree to format this page sequence into
- * @throws FOPException if there is an error formatting the contents
- */
- private void formatPageSequence(PageSequence pageSeq, AreaTree areaTree)
- throws FOPException {
- Title title = null;
- if (pageSeq.getTitleFO() != null) {
- title = getTitleArea(pageSeq.getTitleFO());
- }
- areaTree.startPageSequence(title);
- // Make a new PageLayoutManager and a FlowLayoutManager
- // Run the PLM in a thread
- // Wait for them to finish.
-
- // If no main flow, nothing to layout!
- if (pageSeq.getMainFlow() == null) {
- return;
- }
-
- // Initialize if already used?
- // this.layoutMasterSet.resetPageMasters();
- if (pageSeq.getPageSequenceMaster() != null) {
- pageSeq.getPageSequenceMaster().reset();
- }
-
- pageSeq.initPageNumber();
-
- // This will layout pages and add them to the area tree
- PageLayoutManager pageLM = new PageLayoutManager(areaTree, pageSeq,
- this);
- pageLM.setPageCounting(pageSeq.getCurrentPageNumber(),
- pageSeq.getPageNumberGenerator());
-
- // For now, skip the threading and just call run directly.
- pageLM.run();
-
- // Thread layoutThread = new Thread(pageLM);
- // layoutThread.start();
- // log.debug("Layout thread started");
-
- // // wait on both managers
- // try {
- // layoutThread.join();
- // log.debug("Layout thread done");
- // } catch (InterruptedException ie) {
- // log.error("PageSequence.format() interrupted waiting on layout");
- // }
-
- pageSeq.setCurrentPageNumber(pageLM.getPageCount());
- // Tell the root the last page number we created.
- pageSeq.getRoot().setRunningPageNumberCounter(pageSeq.getCurrentPageNumber());
- }
-
- /**
- * @return the Title area
- */
- private org.apache.fop.area.Title getTitleArea(org.apache.fop.fo.pagination.Title foTitle) {
- // use special layout manager to add the inline areas
- // to the Title.
- InlineStackingLayoutManager lm;
- lm = new InlineStackingLayoutManager(foTitle);
- lm.setLMiter(new LMiter(lm, foTitle.children.listIterator()));
- lm.initialize();
-
- // get breaks then add areas to title
- org.apache.fop.area.Title title =
- new org.apache.fop.area.Title();
-
- ContentLayoutManager clm = new ContentLayoutManager(title);
- clm.setUserAgent(foTitle.getUserAgent());
- lm.setParent(clm);
-
- clm.fillArea(lm);
-
- return title;
- }
-
- /**
- * Public accessor to set the AddLMVisitor object that should be used.
- * This allows subclasses of AddLMVisitor to be used, which can be useful
- * for extensions to the FO Tree.
- * @param addLMVisitor the AddLMVisitor object that should be used.
- */
- public void setAddLMVisitor(AddLMVisitor addLMVisitor) {
- this.addLMVisitor = addLMVisitor;
- }
-
- /**
- * Public accessor to get the AddLMVisitor object that should be used.
- * @return the AddLMVisitor object that should be used.
- */
- public AddLMVisitor getAddLMVisitor() {
- if (this.addLMVisitor == null) {
- this.addLMVisitor = new AddLMVisitor();
- }
- return this.addLMVisitor;
- }
-
- /**
- *
- * @param pagenum PageNumber that is starting.
- */
- public void startPageNumber(PageNumber pagenum) {
- }
-
- /**
- *
- * @param pagenum PageNumber that is ending.
- */
- public void endPageNumber(PageNumber pagenum) {
- }
-
- }
|