Source Code Cross Referenced for PageBreaker.java in  » Graphic-Library » fop » org » apache » fop » layoutmgr » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » fop » org.apache.fop.layoutmgr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        /* $Id: PageBreaker.java 554094 2007-07-07 00:04:25Z adelmelle $ */
019:
020:        package org.apache.fop.layoutmgr;
021:
022:        import java.util.LinkedList;
023:        import java.util.List;
024:        import java.util.ListIterator;
025:
026:        import org.apache.fop.area.Block;
027:        import org.apache.fop.area.Footnote;
028:        import org.apache.fop.area.PageViewport;
029:        import org.apache.fop.fo.Constants;
030:        import org.apache.fop.fo.FONode;
031:        import org.apache.fop.fo.FObj;
032:        import org.apache.fop.fo.pagination.PageSequence;
033:        import org.apache.fop.fo.pagination.Region;
034:        import org.apache.fop.fo.pagination.RegionBody;
035:        import org.apache.fop.fo.pagination.StaticContent;
036:        import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
037:        import org.apache.fop.traits.MinOptMax;
038:
039:        /**
040:         * Handles the breaking of pages in an fo:flow
041:         */
042:        public class PageBreaker extends AbstractBreaker {
043:
044:            private PageSequenceLayoutManager pslm;
045:            private boolean firstPart = true;
046:            private boolean pageBreakHandled;
047:            private boolean needColumnBalancing;
048:            private PageProvider pageProvider;
049:            private Block separatorArea;
050:
051:            /**
052:             * The FlowLayoutManager object, which processes
053:             * the single fo:flow of the fo:page-sequence
054:             */
055:            private FlowLayoutManager childFLM = null;
056:
057:            private StaticContentLayoutManager footnoteSeparatorLM = null;
058:
059:            public PageBreaker(PageSequenceLayoutManager pslm) {
060:                this .pslm = pslm;
061:                this .pageProvider = pslm.getPageProvider();
062:                this .childFLM = pslm.getLayoutManagerMaker()
063:                        .makeFlowLayoutManager(pslm,
064:                                pslm.getPageSequence().getMainFlow());
065:            }
066:
067:            /** @see org.apache.fop.layoutmgr.AbstractBreaker */
068:            protected void updateLayoutContext(LayoutContext context) {
069:                int flowIPD = pslm.getCurrentPV().getCurrentSpan()
070:                        .getColumnWidth();
071:                context.setRefIPD(flowIPD);
072:            }
073:
074:            /** @see org.apache.fop.layoutmgr.AbstractBreaker#getTopLevelLM() */
075:            protected LayoutManager getTopLevelLM() {
076:                return pslm;
077:            }
078:
079:            /** @see org.apache.fop.layoutmgr.AbstractBreaker#getPageProvider() */
080:            protected PageProvider getPageProvider() {
081:                return pslm.getPageProvider();
082:            }
083:
084:            /**
085:             * @see org.apache.fop.layoutmgr.AbstractBreaker#getLayoutListener()
086:             */
087:            protected PageBreakingLayoutListener getLayoutListener() {
088:                return new PageBreakingLayoutListener() {
089:
090:                    public void notifyOverflow(int part, FObj obj) {
091:                        Page p = pageProvider.getPage(false, part,
092:                                PageProvider.RELTO_CURRENT_ELEMENT_LIST);
093:                        RegionBody body = (RegionBody) p.getSimplePageMaster()
094:                                .getRegion(Region.FO_REGION_BODY);
095:                        String err = FONode
096:                                .decorateWithContextInfo(
097:                                        "Content of the region-body on page "
098:                                                + p.getPageViewport()
099:                                                        .getPageNumberString()
100:                                                + " overflows the available area in block-progression dimension.",
101:                                        obj);
102:                        if (body.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW) {
103:                            throw new RuntimeException(err);
104:                        } else {
105:                            log.warn(err);
106:                        }
107:                    }
108:
109:                };
110:            }
111:
112:            /** @see org.apache.fop.layoutmgr.AbstractBreaker */
113:            protected int handleSpanChange(LayoutContext childLC,
114:                    int nextSequenceStartsOn) {
115:                needColumnBalancing = false;
116:                if (childLC.getNextSpan() != Constants.NOT_SET) {
117:                    //Next block list will have a different span.
118:                    nextSequenceStartsOn = childLC.getNextSpan();
119:                    needColumnBalancing = (childLC.getNextSpan() == Constants.EN_ALL);
120:                }
121:                if (needColumnBalancing) {
122:                    AbstractBreaker.log
123:                            .debug("Column balancing necessary for the next element list!!!");
124:                }
125:                return nextSequenceStartsOn;
126:            }
127:
128:            /** @see org.apache.fop.layoutmgr.AbstractBreaker */
129:            protected int getNextBlockList(LayoutContext childLC,
130:                    int nextSequenceStartsOn) {
131:                if (!firstPart) {
132:                    // if this is the first page that will be created by
133:                    // the current BlockSequence, it could have a break
134:                    // condition that must be satisfied;
135:                    // otherwise, we may simply need a new page
136:                    handleBreakTrait(nextSequenceStartsOn);
137:                }
138:                firstPart = false;
139:                pageBreakHandled = true;
140:                pageProvider.setStartOfNextElementList(
141:                        pslm.getCurrentPageNum(), pslm.getCurrentPV()
142:                                .getCurrentSpan().getCurrentFlowIndex());
143:                return super .getNextBlockList(childLC, nextSequenceStartsOn);
144:            }
145:
146:            /** @see org.apache.fop.layoutmgr.AbstractBreaker */
147:            protected LinkedList getNextKnuthElements(LayoutContext context,
148:                    int alignment) {
149:                LinkedList contentList = null;
150:
151:                while (!childFLM.isFinished() && contentList == null) {
152:                    contentList = childFLM.getNextKnuthElements(context,
153:                            alignment);
154:                }
155:
156:                // scan contentList, searching for footnotes
157:                boolean bFootnotesPresent = false;
158:                if (contentList != null) {
159:                    ListIterator contentListIterator = contentList
160:                            .listIterator();
161:                    while (contentListIterator.hasNext()) {
162:                        ListElement element = (ListElement) contentListIterator
163:                                .next();
164:                        if (element instanceof  KnuthBlockBox
165:                                && ((KnuthBlockBox) element).hasAnchors()) {
166:                            // element represents a line with footnote citations
167:                            bFootnotesPresent = true;
168:                            LayoutContext footnoteContext = new LayoutContext(
169:                                    context);
170:                            footnoteContext.setStackLimit(context
171:                                    .getStackLimit());
172:                            footnoteContext.setRefIPD(pslm.getCurrentPV()
173:                                    .getRegionReference(
174:                                            Constants.FO_REGION_BODY).getIPD());
175:                            LinkedList footnoteBodyLMs = ((KnuthBlockBox) element)
176:                                    .getFootnoteBodyLMs();
177:                            ListIterator footnoteBodyIterator = footnoteBodyLMs
178:                                    .listIterator();
179:                            // store the lists of elements representing the footnote bodies
180:                            // in the box representing the line containing their references
181:                            while (footnoteBodyIterator.hasNext()) {
182:                                FootnoteBodyLayoutManager fblm = (FootnoteBodyLayoutManager) footnoteBodyIterator
183:                                        .next();
184:                                fblm.setParent(childFLM);
185:                                fblm.initialize();
186:                                ((KnuthBlockBox) element).addElementList(fblm
187:                                        .getNextKnuthElements(footnoteContext,
188:                                                alignment));
189:                            }
190:                        }
191:                    }
192:                }
193:
194:                if (bFootnotesPresent) {
195:                    // handle the footnote separator
196:                    StaticContent footnoteSeparator;
197:                    footnoteSeparator = pslm.getPageSequence()
198:                            .getStaticContent("xsl-footnote-separator");
199:                    if (footnoteSeparator != null) {
200:                        // the footnote separator can contain page-dependent content such as
201:                        // page numbers or retrieve markers, so its areas cannot simply be 
202:                        // obtained now and repeated in each page;
203:                        // we need to know in advance the separator bpd: the actual separator
204:                        // could be different from page to page, but its bpd would likely be
205:                        // always the same
206:
207:                        // create a Block area that will contain the separator areas
208:                        separatorArea = new Block();
209:                        separatorArea.setIPD(pslm.getCurrentPV()
210:                                .getRegionReference(Constants.FO_REGION_BODY)
211:                                .getIPD());
212:                        // create a StaticContentLM for the footnote separator
213:                        footnoteSeparatorLM = (StaticContentLayoutManager) pslm
214:                                .getLayoutManagerMaker()
215:                                .makeStaticContentLayoutManager(pslm,
216:                                        footnoteSeparator, separatorArea);
217:                        footnoteSeparatorLM.doLayout();
218:
219:                        footnoteSeparatorLength = new MinOptMax(separatorArea
220:                                .getBPD());
221:                    }
222:                }
223:                return contentList;
224:            }
225:
226:            /**
227:             * @return current display alignment
228:             */
229:            protected int getCurrentDisplayAlign() {
230:                return pslm.getCurrentPage().getSimplePageMaster().getRegion(
231:                        Constants.FO_REGION_BODY).getDisplayAlign();
232:            }
233:
234:            /**
235:             * @return whether or not this flow has more page break opportunities
236:             */
237:            protected boolean hasMoreContent() {
238:                return !childFLM.isFinished();
239:            }
240:
241:            /**
242:             * Adds an area to the flow layout manager
243:             * @param posIter the position iterator
244:             * @param context the layout context
245:             */
246:            protected void addAreas(PositionIterator posIter,
247:                    LayoutContext context) {
248:                if (footnoteSeparatorLM != null) {
249:                    StaticContent footnoteSeparator = pslm.getPageSequence()
250:                            .getStaticContent("xsl-footnote-separator");
251:                    // create a Block area that will contain the separator areas
252:                    separatorArea = new Block();
253:                    separatorArea.setIPD(pslm.getCurrentPV()
254:                            .getRegionReference(Constants.FO_REGION_BODY)
255:                            .getIPD());
256:                    // create a StaticContentLM for the footnote separator
257:                    footnoteSeparatorLM = (StaticContentLayoutManager) pslm
258:                            .getLayoutManagerMaker()
259:                            .makeStaticContentLayoutManager(pslm,
260:                                    footnoteSeparator, separatorArea);
261:                    footnoteSeparatorLM.doLayout();
262:                }
263:
264:                childFLM.addAreas(posIter, context);
265:            }
266:
267:            /**
268:             * Performs phase 3 operation
269:             * 
270:             * @param alg page breaking algorithm
271:             * @param partCount part count
272:             * @param originalList the block sequence original list
273:             * @param effectiveList the block sequence effective list
274:             */
275:            protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
276:                    BlockSequence originalList, BlockSequence effectiveList) {
277:                if (needColumnBalancing) {
278:                    doPhase3WithColumnBalancing(alg, partCount, originalList,
279:                            effectiveList);
280:                } else {
281:                    if (!hasMoreContent()
282:                            && pslm.getPageSequence().hasPagePositionLast()) {
283:                        //last part is reached and we have a "last page" condition
284:                        doPhase3WithLastPage(alg, partCount, originalList,
285:                                effectiveList);
286:                    } else {
287:                        //Directly add areas after finding the breaks
288:                        addAreas(alg, partCount, originalList, effectiveList);
289:                    }
290:                }
291:            }
292:
293:            private void doPhase3WithLastPage(PageBreakingAlgorithm alg,
294:                    int partCount, BlockSequence originalList,
295:                    BlockSequence effectiveList) {
296:                int newStartPos;
297:                int restartPoint = pageProvider
298:                        .getStartingPartIndexForLastPage(partCount);
299:                if (restartPoint > 0) {
300:                    //Add definitive areas before last page
301:                    addAreas(alg, restartPoint, originalList, effectiveList);
302:                    //Get page break from which we restart
303:                    PageBreakPosition pbp = (PageBreakPosition) alg
304:                            .getPageBreaks().get(restartPoint - 1);
305:                    newStartPos = pbp.getLeafPos();
306:                    //Handle page break right here to avoid any side-effects
307:                    if (newStartPos > 0) {
308:                        handleBreakTrait(Constants.EN_PAGE);
309:                    }
310:                } else {
311:                    newStartPos = 0;
312:                }
313:                AbstractBreaker.log.debug("Last page handling now!!!");
314:                AbstractBreaker.log
315:                        .debug("===================================================");
316:                AbstractBreaker.log.debug("Restarting at " + restartPoint
317:                        + ", new start position: " + newStartPos);
318:
319:                pageBreakHandled = true;
320:                //Update so the available BPD is reported correctly
321:                int currentPageNum = pslm.getCurrentPageNum();
322:                pageProvider.setStartOfNextElementList(currentPageNum, pslm
323:                        .getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
324:                pageProvider.setLastPageIndex(currentPageNum);
325:
326:                //Restart last page
327:                PageBreakingAlgorithm algRestart = new PageBreakingAlgorithm(
328:                        getTopLevelLM(), getPageProvider(),
329:                        getLayoutListener(), alg.getAlignment(), alg
330:                                .getAlignmentLast(), footnoteSeparatorLength,
331:                        isPartOverflowRecoveryActivated(), false, false);
332:                //alg.setConstantLineWidth(flowBPD);
333:                int iOptPageCount = algRestart.findBreakingPoints(
334:                        effectiveList, newStartPos, 1, true,
335:                        BreakingAlgorithm.ALL_BREAKS);
336:                AbstractBreaker.log.debug("restart: iOptPageCount= "
337:                        + iOptPageCount + " pageBreaks.size()= "
338:                        + algRestart.getPageBreaks().size());
339:                boolean replaceLastPage = iOptPageCount <= pslm.getCurrentPV()
340:                        .getBodyRegion().getColumnCount();
341:                if (replaceLastPage) {
342:                    //Replace last page
343:                    pslm.setCurrentPage(pageProvider.getPage(false,
344:                            currentPageNum));
345:                    //Make sure we only add the areas we haven't added already
346:                    effectiveList.ignoreAtStart = newStartPos;
347:                    addAreas(algRestart, iOptPageCount, originalList,
348:                            effectiveList);
349:                } else {
350:                    effectiveList.ignoreAtStart = newStartPos;
351:                    addAreas(alg, restartPoint, partCount - restartPoint,
352:                            originalList, effectiveList);
353:                    //Add blank last page
354:                    pageProvider.setLastPageIndex(currentPageNum + 1);
355:                    pslm.setCurrentPage(pslm.makeNewPage(true, true));
356:                }
357:                AbstractBreaker.log
358:                        .debug("===================================================");
359:            }
360:
361:            private void doPhase3WithColumnBalancing(PageBreakingAlgorithm alg,
362:                    int partCount, BlockSequence originalList,
363:                    BlockSequence effectiveList) {
364:                AbstractBreaker.log.debug("Column balancing now!!!");
365:                AbstractBreaker.log
366:                        .debug("===================================================");
367:                int newStartPos;
368:                int restartPoint = pageProvider
369:                        .getStartingPartIndexForLastPage(partCount);
370:                if (restartPoint > 0) {
371:                    //Add definitive areas
372:                    addAreas(alg, restartPoint, originalList, effectiveList);
373:                    //Get page break from which we restart
374:                    PageBreakPosition pbp = (PageBreakPosition) alg
375:                            .getPageBreaks().get(restartPoint - 1);
376:                    newStartPos = pbp.getLeafPos();
377:                    //Handle page break right here to avoid any side-effects
378:                    if (newStartPos > 0) {
379:                        handleBreakTrait(Constants.EN_PAGE);
380:                    }
381:                } else {
382:                    newStartPos = 0;
383:                }
384:                AbstractBreaker.log.debug("Restarting at " + restartPoint
385:                        + ", new start position: " + newStartPos);
386:
387:                pageBreakHandled = true;
388:                //Update so the available BPD is reported correctly
389:                pageProvider.setStartOfNextElementList(
390:                        pslm.getCurrentPageNum(), pslm.getCurrentPV()
391:                                .getCurrentSpan().getCurrentFlowIndex());
392:
393:                //Restart last page
394:                PageBreakingAlgorithm algRestart = new BalancingColumnBreakingAlgorithm(
395:                        getTopLevelLM(), getPageProvider(),
396:                        getLayoutListener(), alignment, Constants.EN_START,
397:                        footnoteSeparatorLength,
398:                        isPartOverflowRecoveryActivated(), pslm.getCurrentPV()
399:                                .getBodyRegion().getColumnCount());
400:                //alg.setConstantLineWidth(flowBPD);
401:                int iOptPageCount = algRestart.findBreakingPoints(
402:                        effectiveList, newStartPos, 1, true,
403:                        BreakingAlgorithm.ALL_BREAKS);
404:                AbstractBreaker.log.debug("restart: iOptPageCount= "
405:                        + iOptPageCount + " pageBreaks.size()= "
406:                        + algRestart.getPageBreaks().size());
407:                if (iOptPageCount > pslm.getCurrentPV().getBodyRegion()
408:                        .getColumnCount()) {
409:                    AbstractBreaker.log
410:                            .warn("Breaking algorithm produced more columns than are available.");
411:                    /* reenable when everything works
412:                    throw new IllegalStateException(
413:                            "Breaking algorithm must not produce more columns than available.");
414:                     */
415:                }
416:                //Make sure we only add the areas we haven't added already
417:                effectiveList.ignoreAtStart = newStartPos;
418:                addAreas(algRestart, iOptPageCount, originalList, effectiveList);
419:                AbstractBreaker.log
420:                        .debug("===================================================");
421:            }
422:
423:            protected void startPart(BlockSequence list, int breakClass) {
424:                AbstractBreaker.log.debug("startPart() breakClass="
425:                        + breakClass);
426:                if (pslm.getCurrentPage() == null) {
427:                    throw new IllegalStateException("curPage must not be null");
428:                }
429:                if (!pageBreakHandled) {
430:
431:                    //firstPart is necessary because we need the first page before we start the 
432:                    //algorithm so we have a BPD and IPD. This may subject to change later when we
433:                    //start handling more complex cases.
434:                    if (!firstPart) {
435:                        // if this is the first page that will be created by
436:                        // the current BlockSequence, it could have a break
437:                        // condition that must be satisfied;
438:                        // otherwise, we may simply need a new page
439:                        handleBreakTrait(breakClass);
440:                    }
441:                    pageProvider.setStartOfNextElementList(pslm
442:                            .getCurrentPageNum(), pslm.getCurrentPV()
443:                            .getCurrentSpan().getCurrentFlowIndex());
444:                }
445:                pageBreakHandled = false;
446:                // add static areas and resolve any new id areas
447:                // finish page and add to area tree
448:                firstPart = false;
449:            }
450:
451:            /** @see org.apache.fop.layoutmgr.AbstractBreaker#handleEmptyContent() */
452:            protected void handleEmptyContent() {
453:                pslm.getCurrentPV().getPage().fakeNonEmpty();
454:            }
455:
456:            protected void finishPart(PageBreakingAlgorithm alg,
457:                    PageBreakPosition pbp) {
458:                // add footnote areas
459:                if (pbp.footnoteFirstListIndex < pbp.footnoteLastListIndex
460:                        || pbp.footnoteFirstElementIndex <= pbp.footnoteLastElementIndex) {
461:                    // call addAreas() for each FootnoteBodyLM
462:                    for (int i = pbp.footnoteFirstListIndex; i <= pbp.footnoteLastListIndex; i++) {
463:                        LinkedList elementList = alg.getFootnoteList(i);
464:                        int firstIndex = (i == pbp.footnoteFirstListIndex ? pbp.footnoteFirstElementIndex
465:                                : 0);
466:                        int lastIndex = (i == pbp.footnoteLastListIndex ? pbp.footnoteLastElementIndex
467:                                : elementList.size() - 1);
468:
469:                        SpaceResolver.performConditionalsNotification(
470:                                elementList, firstIndex, lastIndex, -1);
471:                        LayoutContext childLC = new LayoutContext(0);
472:                        AreaAdditionUtil.addAreas(null, new KnuthPossPosIter(
473:                                elementList, firstIndex, lastIndex + 1),
474:                                childLC);
475:                    }
476:                    // set the offset from the top margin
477:                    Footnote parentArea = (Footnote) pslm.getCurrentPV()
478:                            .getBodyRegion().getFootnote();
479:                    int topOffset = (int) pslm.getCurrentPV().getBodyRegion()
480:                            .getBPD()
481:                            - parentArea.getBPD();
482:                    if (separatorArea != null) {
483:                        topOffset -= separatorArea.getBPD();
484:                    }
485:                    parentArea.setTop(topOffset);
486:                    parentArea.setSeparator(separatorArea);
487:                }
488:                pslm.getCurrentPV().getCurrentSpan().notifyFlowsFinished();
489:            }
490:
491:            /**
492:             * @return the current child flow layout manager
493:             */
494:            protected LayoutManager getCurrentChildLM() {
495:                return childFLM;
496:            }
497:
498:            /** @see org.apache.fop.layoutmgr.AbstractBreaker#observeElementList(java.util.List) */
499:            protected void observeElementList(List elementList) {
500:                ElementListObserver.observe(elementList, "breaker",
501:                        ((PageSequence) pslm.getFObj()).getId());
502:            }
503:
504:            /**
505:             * Depending on the kind of break condition, move to next column
506:             * or page. May need to make an empty page if next page would
507:             * not have the desired "handedness".
508:             * @param breakVal - value of break-before or break-after trait.
509:             */
510:            private void handleBreakTrait(int breakVal) {
511:                Page curPage = pslm.getCurrentPage();
512:                if (breakVal == Constants.EN_ALL) {
513:                    //break due to span change in multi-column layout
514:                    curPage.getPageViewport().createSpan(true);
515:                    return;
516:                } else if (breakVal == Constants.EN_NONE) {
517:                    curPage.getPageViewport().createSpan(false);
518:                    return;
519:                } else if (breakVal == Constants.EN_COLUMN || breakVal <= 0) {
520:                    PageViewport pv = curPage.getPageViewport();
521:
522:                    //Check if previous page was spanned
523:                    boolean forceNewPageWithSpan = false;
524:                    RegionBody rb = (RegionBody) curPage.getSimplePageMaster()
525:                            .getRegion(Constants.FO_REGION_BODY);
526:                    if (breakVal < 0 && rb.getColumnCount() > 1
527:                            && pv.getCurrentSpan().getColumnCount() == 1) {
528:                        forceNewPageWithSpan = true;
529:                    }
530:
531:                    if (forceNewPageWithSpan) {
532:                        curPage = pslm.makeNewPage(false, false);
533:                        curPage.getPageViewport().createSpan(true);
534:                    } else if (pv.getCurrentSpan().hasMoreFlows()) {
535:                        pv.getCurrentSpan().moveToNextFlow();
536:                    } else {
537:                        curPage = pslm.makeNewPage(false, false);
538:                    }
539:                    return;
540:                }
541:                log.debug("handling break-before after page "
542:                        + pslm.getCurrentPageNum() + " breakVal=" + breakVal);
543:                if (needBlankPageBeforeNew(breakVal)) {
544:                    curPage = pslm.makeNewPage(true, false);
545:                }
546:                if (needNewPage(breakVal)) {
547:                    curPage = pslm.makeNewPage(false, false);
548:                }
549:            }
550:
551:            /**
552:             * Check if a blank page is needed to accomodate
553:             * desired even or odd page number.
554:             * @param breakVal - value of break-before or break-after trait.
555:             */
556:            private boolean needBlankPageBeforeNew(int breakVal) {
557:                if (breakVal == Constants.EN_PAGE
558:                        || (pslm.getCurrentPage().getPageViewport().getPage()
559:                                .isEmpty())) {
560:                    // any page is OK or we already have an empty page
561:                    return false;
562:                } else {
563:                    /* IF we are on the kind of page we need, we'll need a new page. */
564:                    if (pslm.getCurrentPageNum() % 2 == 0) { // even page
565:                        return (breakVal == Constants.EN_EVEN_PAGE);
566:                    } else { // odd page
567:                        return (breakVal == Constants.EN_ODD_PAGE);
568:                    }
569:                }
570:            }
571:
572:            /**
573:             * See if need to generate a new page
574:             * @param breakVal - value of break-before or break-after trait.
575:             */
576:            private boolean needNewPage(int breakVal) {
577:                if (pslm.getCurrentPage().getPageViewport().getPage().isEmpty()) {
578:                    if (breakVal == Constants.EN_PAGE) {
579:                        return false;
580:                    } else if (pslm.getCurrentPageNum() % 2 == 0) { // even page
581:                        return (breakVal == Constants.EN_ODD_PAGE);
582:                    } else { // odd page
583:                        return (breakVal == Constants.EN_EVEN_PAGE);
584:                    }
585:                } else {
586:                    return true;
587:                }
588:            }
589:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.