Source Code Cross Referenced for BlockContainerLayoutManager.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) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        /* $Id: BlockContainerLayoutManager.java 525253 2007-04-03 19:40:14Z spepping $ */
0019:
0020:        package org.apache.fop.layoutmgr;
0021:
0022:        import java.util.LinkedList;
0023:        import java.util.List;
0024:        import java.util.ListIterator;
0025:        import java.awt.Point;
0026:        import java.awt.geom.Rectangle2D;
0027:
0028:        import org.apache.commons.logging.Log;
0029:        import org.apache.commons.logging.LogFactory;
0030:        import org.apache.fop.area.Area;
0031:        import org.apache.fop.area.BlockViewport;
0032:        import org.apache.fop.area.Block;
0033:        import org.apache.fop.area.Trait;
0034:        import org.apache.fop.fo.FONode;
0035:        import org.apache.fop.fo.flow.BlockContainer;
0036:        import org.apache.fop.fo.properties.CommonAbsolutePosition;
0037:        import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
0038:        import org.apache.fop.area.CTM;
0039:        import org.apache.fop.datatypes.FODimension;
0040:        import org.apache.fop.datatypes.Length;
0041:        import org.apache.fop.traits.MinOptMax;
0042:        import org.apache.fop.traits.SpaceVal;
0043:
0044:        /**
0045:         * LayoutManager for a block-container FO.
0046:         */
0047:        public class BlockContainerLayoutManager extends
0048:                BlockStackingLayoutManager implements 
0049:                ConditionalElementListener {
0050:
0051:            /**
0052:             * logging instance
0053:             */
0054:            private static Log log = LogFactory
0055:                    .getLog(BlockContainerLayoutManager.class);
0056:
0057:            private BlockViewport viewportBlockArea;
0058:            private Block referenceArea;
0059:
0060:            private CommonAbsolutePosition abProps;
0061:            private FODimension relDims;
0062:            private CTM absoluteCTM;
0063:            private Length width;
0064:            private Length height;
0065:            //private int vpContentIPD;
0066:            private int vpContentBPD;
0067:
0068:            // When viewport should grow with the content.
0069:            private boolean autoHeight = true;
0070:
0071:            /* holds the (one-time use) fo:block space-before
0072:            and -after properties.  Large fo:blocks are split
0073:            into multiple Area.Blocks to accomodate the subsequent
0074:            regions (pages) they are placed on.  space-before
0075:            is applied at the beginning of the first
0076:            Block and space-after at the end of the last Block
0077:            used in rendering the fo:block.
0078:             */
0079:            //TODO space-before|after: handle space-resolution rules
0080:            private MinOptMax foBlockSpaceBefore;
0081:            private MinOptMax foBlockSpaceAfter;
0082:
0083:            private boolean discardBorderBefore;
0084:            private boolean discardBorderAfter;
0085:            private boolean discardPaddingBefore;
0086:            private boolean discardPaddingAfter;
0087:            private MinOptMax effSpaceBefore;
0088:            private MinOptMax effSpaceAfter;
0089:
0090:            /**
0091:             * Create a new block container layout manager.
0092:             * @param node block-container node to create the layout manager for.
0093:             */
0094:            public BlockContainerLayoutManager(BlockContainer node) {
0095:                super (node);
0096:            }
0097:
0098:            /** @see org.apache.fop.layoutmgr.LayoutManager#initialize() */
0099:            public void initialize() {
0100:                abProps = getBlockContainerFO().getCommonAbsolutePosition();
0101:                foBlockSpaceBefore = new SpaceVal(getBlockContainerFO()
0102:                        .getCommonMarginBlock().spaceBefore, this ).getSpace();
0103:                foBlockSpaceAfter = new SpaceVal(getBlockContainerFO()
0104:                        .getCommonMarginBlock().spaceAfter, this ).getSpace();
0105:                startIndent = getBlockContainerFO().getCommonMarginBlock().startIndent
0106:                        .getValue(this );
0107:                endIndent = getBlockContainerFO().getCommonMarginBlock().endIndent
0108:                        .getValue(this );
0109:
0110:                boolean rotated = (getBlockContainerFO()
0111:                        .getReferenceOrientation() % 180 != 0);
0112:                if (rotated) {
0113:                    height = getBlockContainerFO()
0114:                            .getInlineProgressionDimension().getOptimum(this )
0115:                            .getLength();
0116:                    width = getBlockContainerFO()
0117:                            .getBlockProgressionDimension().getOptimum(this )
0118:                            .getLength();
0119:                } else {
0120:                    height = getBlockContainerFO()
0121:                            .getBlockProgressionDimension().getOptimum(this )
0122:                            .getLength();
0123:                    width = getBlockContainerFO()
0124:                            .getInlineProgressionDimension().getOptimum(this )
0125:                            .getLength();
0126:                }
0127:
0128:                bpUnit = 0; //layoutProps.blockProgressionUnit;
0129:                if (bpUnit == 0) {
0130:                    // use optimum space values
0131:                    adjustedSpaceBefore = getBlockContainerFO()
0132:                            .getCommonMarginBlock().spaceBefore.getSpace()
0133:                            .getOptimum(this ).getLength().getValue(this );
0134:                    adjustedSpaceAfter = getBlockContainerFO()
0135:                            .getCommonMarginBlock().spaceAfter.getSpace()
0136:                            .getOptimum(this ).getLength().getValue(this );
0137:                } else {
0138:                    // use minimum space values
0139:                    adjustedSpaceBefore = getBlockContainerFO()
0140:                            .getCommonMarginBlock().spaceBefore.getSpace()
0141:                            .getMinimum(this ).getLength().getValue(this );
0142:                    adjustedSpaceAfter = getBlockContainerFO()
0143:                            .getCommonMarginBlock().spaceAfter.getSpace()
0144:                            .getMinimum(this ).getLength().getValue(this );
0145:                }
0146:            }
0147:
0148:            private void resetSpaces() {
0149:                this .discardBorderBefore = false;
0150:                this .discardBorderAfter = false;
0151:                this .discardPaddingBefore = false;
0152:                this .discardPaddingAfter = false;
0153:                this .effSpaceBefore = null;
0154:                this .effSpaceAfter = null;
0155:            }
0156:
0157:            /** @return the content IPD */
0158:            protected int getRotatedIPD() {
0159:                return getBlockContainerFO().getInlineProgressionDimension()
0160:                        .getOptimum(this ).getLength().getValue(this );
0161:            }
0162:
0163:            private boolean needClip() {
0164:                int overflow = getBlockContainerFO().getOverflow();
0165:                return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW);
0166:            }
0167:
0168:            private int getSpaceBefore() {
0169:                return foBlockSpaceBefore.opt;
0170:            }
0171:
0172:            private int getBPIndents() {
0173:                int indents = 0;
0174:                /* TODO This is wrong isn't it?
0175:                indents += getBlockContainerFO().getCommonMarginBlock()
0176:                            .spaceBefore.getOptimum(this).getLength().getValue(this);
0177:                indents += getBlockContainerFO().getCommonMarginBlock()
0178:                            .spaceAfter.getOptimum(this).getLength().getValue(this);
0179:                 */
0180:                indents += getBlockContainerFO()
0181:                        .getCommonBorderPaddingBackground()
0182:                        .getBPPaddingAndBorder(false, this );
0183:                return indents;
0184:            }
0185:
0186:            private boolean isAbsoluteOrFixed() {
0187:                return (abProps.absolutePosition == EN_ABSOLUTE)
0188:                        || (abProps.absolutePosition == EN_FIXED);
0189:            }
0190:
0191:            private boolean isFixed() {
0192:                return (abProps.absolutePosition == EN_FIXED);
0193:            }
0194:
0195:            /** @see org.apache.fop.layoutmgr.LayoutManager#getContentAreaBPD() */
0196:            public int getContentAreaBPD() {
0197:                if (autoHeight) {
0198:                    return -1;
0199:                } else {
0200:                    return this .vpContentBPD;
0201:                }
0202:            }
0203:
0204:            /** @see org.apache.fop.layoutmgr.LayoutManager */
0205:            public LinkedList getNextKnuthElements(LayoutContext context,
0206:                    int alignment) {
0207:                resetSpaces();
0208:                if (isAbsoluteOrFixed()) {
0209:                    return getNextKnuthElementsAbsolute(context, alignment);
0210:                }
0211:
0212:                autoHeight = false;
0213:                //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
0214:                int maxbpd = context.getStackLimit().opt;
0215:                int allocBPD;
0216:                if (height.getEnum() == EN_AUTO
0217:                        || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
0218:                    //auto height when height="auto" or "if that dimension is not specified explicitly 
0219:                    //(i.e., it depends on content's blockprogression-dimension)" (XSL 1.0, 7.14.1)
0220:                    allocBPD = maxbpd;
0221:                    autoHeight = true;
0222:                } else {
0223:                    allocBPD = height.getValue(this ); //this is the content-height
0224:                    allocBPD += getBPIndents();
0225:                }
0226:                vpContentBPD = allocBPD - getBPIndents();
0227:
0228:                referenceIPD = context.getRefIPD();
0229:                if (width.getEnum() == EN_AUTO) {
0230:                    updateContentAreaIPDwithOverconstrainedAdjust();
0231:                } else {
0232:                    int contentWidth = width.getValue(this );
0233:                    updateContentAreaIPDwithOverconstrainedAdjust(contentWidth);
0234:                }
0235:
0236:                double contentRectOffsetX = 0;
0237:                contentRectOffsetX += getBlockContainerFO()
0238:                        .getCommonMarginBlock().startIndent.getValue(this );
0239:                double contentRectOffsetY = 0;
0240:                contentRectOffsetY += getBlockContainerFO()
0241:                        .getCommonBorderPaddingBackground()
0242:                        .getBorderBeforeWidth(false);
0243:                contentRectOffsetY += getBlockContainerFO()
0244:                        .getCommonBorderPaddingBackground().getPaddingBefore(
0245:                                false, this );
0246:
0247:                Rectangle2D rect = new Rectangle2D.Double(contentRectOffsetX,
0248:                        contentRectOffsetY, getContentAreaIPD(),
0249:                        getContentAreaBPD());
0250:                relDims = new FODimension(0, 0);
0251:                absoluteCTM = CTM.getCTMandRelDims(getBlockContainerFO()
0252:                        .getReferenceOrientation(), getBlockContainerFO()
0253:                        .getWritingMode(), rect, relDims);
0254:
0255:                int availableIPD = referenceIPD - getIPIndents();
0256:                if (rect.getWidth() > availableIPD) {
0257:                    log.warn(FONode.decorateWithContextInfo(
0258:                            "The extent in inline-progression-direction (width) of a block-container is"
0259:                                    + " bigger than the available space ("
0260:                                    + rect.getWidth() + "mpt > "
0261:                                    + context.getRefIPD() + "mpt)",
0262:                            getBlockContainerFO()));
0263:                }
0264:
0265:                MinOptMax stackLimit = new MinOptMax(relDims.bpd);
0266:
0267:                LinkedList returnedList = null;
0268:                LinkedList contentList = new LinkedList();
0269:                LinkedList returnList = new LinkedList();
0270:
0271:                if (!breakBeforeServed) {
0272:                    try {
0273:                        if (addKnuthElementsForBreakBefore(returnList, context)) {
0274:                            return returnList;
0275:                        }
0276:                    } finally {
0277:                        breakBeforeServed = true;
0278:                    }
0279:                }
0280:
0281:                if (!firstVisibleMarkServed) {
0282:                    addKnuthElementsForSpaceBefore(returnList, alignment);
0283:                }
0284:
0285:                addKnuthElementsForBorderPaddingBefore(returnList,
0286:                        !firstVisibleMarkServed);
0287:                firstVisibleMarkServed = true;
0288:
0289:                if (autoHeight) {
0290:                    //Spaces, border and padding to be repeated at each break
0291:                    addPendingMarks(context);
0292:
0293:                    BlockLevelLayoutManager curLM; // currently active LM
0294:                    BlockLevelLayoutManager prevLM = null; // previously active LM
0295:                    while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
0296:                        LayoutContext childLC = new LayoutContext(0);
0297:                        childLC.copyPendingMarksFrom(context);
0298:                        // curLM is a ?
0299:                        childLC.setStackLimit(MinOptMax.subtract(context
0300:                                .getStackLimit(), stackLimit));
0301:                        childLC.setRefIPD(relDims.ipd);
0302:                        childLC.setWritingMode(getBlockContainerFO()
0303:                                .getWritingMode());
0304:
0305:                        // get elements from curLM
0306:                        returnedList = curLM.getNextKnuthElements(childLC,
0307:                                alignment);
0308:                        if (returnedList.size() == 1
0309:                                && ((ListElement) returnedList.getFirst())
0310:                                        .isForcedBreak()) {
0311:                            // a descendant of this block has break-before
0312:                            /*
0313:                            if (returnList.size() == 0) {
0314:                                // the first child (or its first child ...) has
0315:                                // break-before;
0316:                                // all this block, including space before, will be put in
0317:                                // the
0318:                                // following page
0319:                                bSpaceBeforeServed = false;
0320:                            }*/
0321:                            contentList.addAll(returnedList);
0322:
0323:                            // "wrap" the Position inside each element
0324:                            // moving the elements from contentList to returnList
0325:                            returnedList = new LinkedList();
0326:                            wrapPositionElements(contentList, returnList);
0327:
0328:                            return returnList;
0329:                        } else {
0330:                            if (prevLM != null) {
0331:                                // there is a block handled by prevLM
0332:                                // before the one handled by curLM
0333:                                if (mustKeepTogether()
0334:                                        || prevLM.mustKeepWithNext()
0335:                                        || curLM.mustKeepWithPrevious()) {
0336:                                    // add an infinite penalty to forbid a break between
0337:                                    // blocks
0338:                                    contentList.add(new BreakElement(
0339:                                            new Position(this ),
0340:                                            KnuthElement.INFINITE, context));
0341:                                } else if (!((ListElement) contentList
0342:                                        .getLast()).isGlue()) {
0343:                                    // add a null penalty to allow a break between blocks
0344:                                    contentList.add(new BreakElement(
0345:                                            new Position(this ), 0, context));
0346:                                } else {
0347:                                    // the last element in contentList is a glue;
0348:                                    // it is a feasible breakpoint, there is no need to add
0349:                                    // a penalty
0350:                                }
0351:                            }
0352:                            contentList.addAll(returnedList);
0353:                            if (returnedList.size() == 0) {
0354:                                //Avoid NoSuchElementException below (happens with empty blocks)
0355:                                continue;
0356:                            }
0357:                            if (((ListElement) returnedList.getLast())
0358:                                    .isForcedBreak()) {
0359:                                // a descendant of this block has break-after
0360:                                if (curLM.isFinished()) {
0361:                                    // there is no other content in this block;
0362:                                    // it's useless to add space after before a page break
0363:                                    setFinished(true);
0364:                                }
0365:
0366:                                returnedList = new LinkedList();
0367:                                wrapPositionElements(contentList, returnList);
0368:
0369:                                return returnList;
0370:                            }
0371:                        }
0372:                        prevLM = curLM;
0373:                    }
0374:
0375:                    returnedList = new LinkedList();
0376:                    wrapPositionElements(contentList, returnList);
0377:
0378:                } else {
0379:                    MinOptMax range = new MinOptMax(relDims.ipd);
0380:                    BlockContainerBreaker breaker = new BlockContainerBreaker(
0381:                            this , range);
0382:                    breaker.doLayout(relDims.bpd, autoHeight);
0383:                    boolean contentOverflows = false;
0384:                    if (!breaker.isEmpty()) {
0385:                        contentOverflows = (breaker.deferredAlg.getPageBreaks()
0386:                                .size() > 1);
0387:                    }
0388:
0389:                    Position bcPosition = new BlockContainerPosition(this ,
0390:                            breaker);
0391:                    returnList.add(new KnuthBox(vpContentBPD,
0392:                            notifyPos(bcPosition), false));
0393:                    //TODO Handle min/opt/max for block-progression-dimension
0394:                    /* These two elements will be used to add stretchability to the above box
0395:                    returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, 
0396:                                           false, returnPosition, false));
0397:                    returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0,
0398:                                           LINE_NUMBER_ADJUSTMENT, returnPosition, false));
0399:                     */
0400:
0401:                    if (contentOverflows) {
0402:                        log
0403:                                .warn("Contents overflow block-container viewport: clipping");
0404:                        if (getBlockContainerFO().getOverflow() == EN_ERROR_IF_OVERFLOW) {
0405:                            //TODO Throw layout exception
0406:                        }
0407:                    }
0408:                }
0409:                addKnuthElementsForBorderPaddingAfter(returnList, true);
0410:                addKnuthElementsForSpaceAfter(returnList, alignment);
0411:                addKnuthElementsForBreakAfter(returnList, context);
0412:
0413:                setFinished(true);
0414:                return returnList;
0415:            }
0416:
0417:            private LinkedList getNextKnuthElementsAbsolute(
0418:                    LayoutContext context, int alignment) {
0419:                autoHeight = false;
0420:
0421:                Point offset = getAbsOffset();
0422:                int allocBPD, allocIPD;
0423:                if (height.getEnum() == EN_AUTO
0424:                        || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
0425:                    //auto height when height="auto" or "if that dimension is not specified explicitly 
0426:                    //(i.e., it depends on content's blockprogression-dimension)" (XSL 1.0, 7.14.1)
0427:                    allocBPD = 0;
0428:                    if (abProps.bottom.getEnum() != EN_AUTO) {
0429:                        int availHeight;
0430:                        if (isFixed()) {
0431:                            availHeight = (int) getCurrentPV().getViewArea()
0432:                                    .getHeight();
0433:                        } else {
0434:                            availHeight = context.getStackLimit().opt;
0435:                        }
0436:                        allocBPD = availHeight;
0437:                        allocBPD -= offset.y;
0438:                        if (abProps.bottom.getEnum() != EN_AUTO) {
0439:                            allocBPD -= abProps.bottom.getValue(this );
0440:                            if (allocBPD < 0) {
0441:                                //TODO Fix absolute b-c layout, layout may need to be defferred until
0442:                                //after page breaking when the size of the containing box is known.
0443:                                /* Warning disabled due to a interpretation mistake.
0444:                                 * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
0445:                                log.error("The current combination of top and bottom properties results"
0446:                                        + " in a negative extent for the block-container. 'bottom' may be"
0447:                                        + " at most " + (allocBPD + abProps.bottom.getValue(this)) + " mpt,"
0448:                                        + " but was actually " + abProps.bottom.getValue(this) + " mpt."
0449:                                        + " The nominal available height is " + availHeight + " mpt.");
0450:                                 */
0451:                                allocBPD = 0;
0452:                            }
0453:                        } else {
0454:                            if (allocBPD < 0) {
0455:                                /* Warning disabled due to a interpretation mistake.
0456:                                 * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
0457:                                log.error("The current combination of top and bottom properties results"
0458:                                        + " in a negative extent for the block-container. 'top' may be"
0459:                                        + " at most " + availHeight + " mpt,"
0460:                                        + " but was actually " + offset.y + " mpt."
0461:                                        + " The nominal available height is " + availHeight + " mpt.");
0462:                                 */
0463:                                allocBPD = 0;
0464:                            }
0465:                        }
0466:                    } else {
0467:                        int maxbpd = context.getStackLimit().opt;
0468:                        allocBPD = maxbpd;
0469:                        autoHeight = true;
0470:                    }
0471:                } else {
0472:                    allocBPD = height.getValue(this ); //this is the content-height
0473:                    allocBPD += getBPIndents();
0474:                }
0475:                if (width.getEnum() == EN_AUTO) {
0476:                    int availWidth;
0477:                    if (isFixed()) {
0478:                        availWidth = (int) getCurrentPV().getViewArea()
0479:                                .getWidth();
0480:                    } else {
0481:                        availWidth = context.getRefIPD();
0482:                    }
0483:                    allocIPD = availWidth;
0484:                    if (abProps.left.getEnum() != EN_AUTO) {
0485:                        allocIPD -= abProps.left.getValue(this );
0486:                    }
0487:                    if (abProps.right.getEnum() != EN_AUTO) {
0488:                        allocIPD -= abProps.right.getValue(this );
0489:                        if (allocIPD < 0) {
0490:                            /* Warning disabled due to a interpretation mistake.
0491:                             * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
0492:                            log.error("The current combination of left and right properties results"
0493:                                    + " in a negative extent for the block-container. 'right' may be"
0494:                                    + " at most " + (allocIPD + abProps.right.getValue(this)) + " mpt,"
0495:                                    + " but was actually " + abProps.right.getValue(this) + " mpt."
0496:                                    + " The nominal available width is " + availWidth + " mpt.");
0497:                             */
0498:                            allocIPD = 0;
0499:                        }
0500:                    } else {
0501:                        if (allocIPD < 0) {
0502:                            /* Warning disabled due to a interpretation mistake.
0503:                             * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
0504:                            log.error("The current combination of left and right properties results"
0505:                                    + " in a negative extent for the block-container. 'left' may be"
0506:                                    + " at most " + allocIPD + " mpt,"
0507:                                    + " but was actually " + abProps.left.getValue(this) + " mpt."
0508:                                    + " The nominal available width is " + availWidth + " mpt.");
0509:                             */
0510:                            allocIPD = 0;
0511:                        }
0512:                    }
0513:                } else {
0514:                    allocIPD = width.getValue(this ); //this is the content-width
0515:                    allocIPD += getIPIndents();
0516:                }
0517:
0518:                vpContentBPD = allocBPD - getBPIndents();
0519:                setContentAreaIPD(allocIPD - getIPIndents());
0520:
0521:                double contentRectOffsetX = offset.getX();
0522:                contentRectOffsetX += getBlockContainerFO()
0523:                        .getCommonMarginBlock().startIndent.getValue(this );
0524:                double contentRectOffsetY = offset.getY();
0525:                contentRectOffsetY += getSpaceBefore(); //TODO Uhm, is that necessary?
0526:                contentRectOffsetY += getBlockContainerFO()
0527:                        .getCommonBorderPaddingBackground()
0528:                        .getBorderBeforeWidth(false);
0529:                contentRectOffsetY += getBlockContainerFO()
0530:                        .getCommonBorderPaddingBackground().getPaddingBefore(
0531:                                false, this );
0532:
0533:                Rectangle2D rect = new Rectangle2D.Double(contentRectOffsetX,
0534:                        contentRectOffsetY, getContentAreaIPD(), vpContentBPD);
0535:                relDims = new FODimension(0, 0);
0536:                absoluteCTM = CTM.getCTMandRelDims(getBlockContainerFO()
0537:                        .getReferenceOrientation(), getBlockContainerFO()
0538:                        .getWritingMode(), rect, relDims);
0539:
0540:                MinOptMax range = new MinOptMax(relDims.ipd);
0541:                BlockContainerBreaker breaker = new BlockContainerBreaker(this ,
0542:                        range);
0543:                breaker.doLayout((autoHeight ? 0 : relDims.bpd), autoHeight);
0544:                boolean contentOverflows = breaker.isOverflow();
0545:                LinkedList returnList = new LinkedList();
0546:                if (!breaker.isEmpty()) {
0547:                    Position bcPosition = new BlockContainerPosition(this ,
0548:                            breaker);
0549:                    returnList
0550:                            .add(new KnuthBox(0, notifyPos(bcPosition), false));
0551:
0552:                    //TODO Maybe check for page overflow when autoHeight=true
0553:                    if (!autoHeight
0554:                            & (contentOverflows/*usedBPD > relDims.bpd*/)) {
0555:                        log
0556:                                .warn("Contents overflow block-container viewport: clipping");
0557:                        if (getBlockContainerFO().getOverflow() == EN_ERROR_IF_OVERFLOW) {
0558:                            //TODO Throw layout exception
0559:                        }
0560:                    }
0561:                }
0562:
0563:                setFinished(true);
0564:                return returnList;
0565:            }
0566:
0567:            private class BlockContainerPosition extends NonLeafPosition {
0568:
0569:                private BlockContainerBreaker breaker;
0570:
0571:                public BlockContainerPosition(LayoutManager lm,
0572:                        BlockContainerBreaker breaker) {
0573:                    super (lm, null);
0574:                    this .breaker = breaker;
0575:                }
0576:
0577:                public BlockContainerBreaker getBreaker() {
0578:                    return this .breaker;
0579:                }
0580:
0581:            }
0582:
0583:            private class BlockContainerBreaker extends AbstractBreaker {
0584:
0585:                private BlockContainerLayoutManager bclm;
0586:                private MinOptMax ipd;
0587:
0588:                //Info for deferred adding of areas
0589:                private PageBreakingAlgorithm deferredAlg;
0590:                private BlockSequence deferredOriginalList;
0591:                private BlockSequence deferredEffectiveList;
0592:
0593:                public BlockContainerBreaker(BlockContainerLayoutManager bclm,
0594:                        MinOptMax ipd) {
0595:                    this .bclm = bclm;
0596:                    this .ipd = ipd;
0597:                }
0598:
0599:                /** @see org.apache.fop.layoutmgr.AbstractBreaker#observeElementList(java.util.List) */
0600:                protected void observeElementList(List elementList) {
0601:                    ElementListObserver.observe(elementList, "block-container",
0602:                            bclm.getBlockContainerFO().getId());
0603:                }
0604:
0605:                /** @see org.apache.fop.layoutmgr.AbstractBreaker#isPartOverflowRecoveryActivated() */
0606:                protected boolean isPartOverflowRecoveryActivated() {
0607:                    //For block-containers, this must be disabled because of wanted overflow.
0608:                    return false;
0609:                }
0610:
0611:                /** @see org.apache.fop.layoutmgr.AbstractBreaker#isSinglePartFavored() */
0612:                protected boolean isSinglePartFavored() {
0613:                    return true;
0614:                }
0615:
0616:                public int getDifferenceOfFirstPart() {
0617:                    PageBreakPosition pbp = (PageBreakPosition) this .deferredAlg
0618:                            .getPageBreaks().getFirst();
0619:                    return pbp.difference;
0620:                }
0621:
0622:                public boolean isOverflow() {
0623:                    if (isEmpty()) {
0624:                        return false;
0625:                    } else {
0626:                        return (deferredAlg.getPageBreaks().size() > 1);
0627:                    }
0628:                }
0629:
0630:                protected LayoutManager getTopLevelLM() {
0631:                    return bclm;
0632:                }
0633:
0634:                protected LayoutContext createLayoutContext() {
0635:                    LayoutContext lc = super .createLayoutContext();
0636:                    lc.setRefIPD(ipd.opt);
0637:                    lc.setWritingMode(getBlockContainerFO().getWritingMode());
0638:                    return lc;
0639:                }
0640:
0641:                protected LinkedList getNextKnuthElements(
0642:                        LayoutContext context, int alignment) {
0643:                    LayoutManager curLM; // currently active LM
0644:                    LinkedList returnList = new LinkedList();
0645:
0646:                    while ((curLM = getChildLM()) != null) {
0647:                        LayoutContext childLC = new LayoutContext(0);
0648:                        childLC.setStackLimit(context.getStackLimit());
0649:                        childLC.setRefIPD(context.getRefIPD());
0650:                        childLC.setWritingMode(getBlockContainerFO()
0651:                                .getWritingMode());
0652:
0653:                        LinkedList returnedList = null;
0654:                        if (!curLM.isFinished()) {
0655:                            returnedList = curLM.getNextKnuthElements(childLC,
0656:                                    alignment);
0657:                        }
0658:                        if (returnedList != null) {
0659:                            bclm.wrapPositionElements(returnedList, returnList);
0660:                        }
0661:                    }
0662:                    SpaceResolver.resolveElementList(returnList);
0663:                    setFinished(true);
0664:                    return returnList;
0665:                }
0666:
0667:                protected int getCurrentDisplayAlign() {
0668:                    return getBlockContainerFO().getDisplayAlign();
0669:                }
0670:
0671:                protected boolean hasMoreContent() {
0672:                    return !isFinished();
0673:                }
0674:
0675:                protected void addAreas(PositionIterator posIter,
0676:                        LayoutContext context) {
0677:                    AreaAdditionUtil.addAreas(bclm, posIter, context);
0678:                }
0679:
0680:                protected void doPhase3(PageBreakingAlgorithm alg,
0681:                        int partCount, BlockSequence originalList,
0682:                        BlockSequence effectiveList) {
0683:                    //Defer adding of areas until addAreas is called by the parent LM
0684:                    this .deferredAlg = alg;
0685:                    this .deferredOriginalList = originalList;
0686:                    this .deferredEffectiveList = effectiveList;
0687:                }
0688:
0689:                protected void finishPart(PageBreakingAlgorithm alg,
0690:                        PageBreakPosition pbp) {
0691:                    //nop for bclm
0692:                }
0693:
0694:                protected LayoutManager getCurrentChildLM() {
0695:                    return curChildLM;
0696:                }
0697:
0698:                public void addContainedAreas() {
0699:                    if (isEmpty()) {
0700:                        return;
0701:                    }
0702:                    //Rendering all parts (not just the first) at once for the case where the parts that 
0703:                    //overflow should be visible.
0704:                    //TODO Check if this has any unwanted side-effects. Feels a bit like a hack.
0705:                    this .addAreas(this .deferredAlg,
0706:                    /*1*/this .deferredAlg.getPageBreaks().size(),
0707:                            this .deferredOriginalList,
0708:                            this .deferredEffectiveList);
0709:                }
0710:
0711:            }
0712:
0713:            private Point getAbsOffset() {
0714:                int x = 0;
0715:                int y = 0;
0716:                if (abProps.left.getEnum() != EN_AUTO) {
0717:                    x = abProps.left.getValue(this );
0718:                }
0719:                if (abProps.top.getEnum() != EN_AUTO) {
0720:                    y = abProps.top.getValue(this );
0721:                }
0722:                return new Point(x, y);
0723:            }
0724:
0725:            /** @see org.apache.fop.layoutmgr.LayoutManager */
0726:            public void addAreas(PositionIterator parentIter,
0727:                    LayoutContext layoutContext) {
0728:                getParentArea(null);
0729:
0730:                // if this will create the first block area in a page
0731:                // and display-align is bottom or center, add space before
0732:                if (layoutContext.getSpaceBefore() > 0) {
0733:                    addBlockSpacing(0.0, new MinOptMax(layoutContext
0734:                            .getSpaceBefore()));
0735:                }
0736:
0737:                LayoutManager childLM = null;
0738:                LayoutManager lastLM = null;
0739:                LayoutContext lc = new LayoutContext(0);
0740:                lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
0741:                // set space after in the LayoutContext for children
0742:                if (layoutContext.getSpaceAfter() > 0) {
0743:                    lc.setSpaceAfter(layoutContext.getSpaceAfter());
0744:                }
0745:                BlockContainerPosition bcpos = null;
0746:                PositionIterator childPosIter;
0747:
0748:                // "unwrap" the NonLeafPositions stored in parentIter
0749:                // and put them in a new list;
0750:                LinkedList positionList = new LinkedList();
0751:                Position pos;
0752:                boolean bSpaceBefore = false;
0753:                boolean bSpaceAfter = false;
0754:                Position firstPos = null;
0755:                Position lastPos = null;
0756:                while (parentIter.hasNext()) {
0757:                    pos = (Position) parentIter.next();
0758:                    if (pos.getIndex() >= 0) {
0759:                        if (firstPos == null) {
0760:                            firstPos = pos;
0761:                        }
0762:                        lastPos = pos;
0763:                    }
0764:                    Position innerPosition = pos;
0765:                    if (pos instanceof  NonLeafPosition) {
0766:                        innerPosition = ((NonLeafPosition) pos).getPosition();
0767:                    }
0768:                    if (pos instanceof  BlockContainerPosition) {
0769:                        if (bcpos != null) {
0770:                            throw new IllegalStateException(
0771:                                    "Only one BlockContainerPosition allowed");
0772:                        }
0773:                        bcpos = (BlockContainerPosition) pos;
0774:                        //Add child areas inside the reference area
0775:                        //bcpos.getBreaker().addContainedAreas();
0776:                    } else if (innerPosition == null) {
0777:                        if (pos instanceof  NonLeafPosition) {
0778:                            // pos was created by this BCLM and was inside an element
0779:                            // representing space before or after
0780:                            // this means the space was not discarded
0781:                            if (positionList.size() == 0 && bcpos == null) {
0782:                                // pos was in the element representing space-before
0783:                                bSpaceBefore = true;
0784:                            } else {
0785:                                // pos was in the element representing space-after
0786:                                bSpaceAfter = true;
0787:                            }
0788:                        } else {
0789:                            //ignore (probably a Position for a simple penalty between blocks)
0790:                        }
0791:                    } else if (innerPosition.getLM() == this 
0792:                            && !(innerPosition instanceof  MappingPosition)) {
0793:                        // pos was created by this BlockLM and was inside a penalty
0794:                        // allowing or forbidding a page break
0795:                        // nothing to do
0796:                    } else {
0797:                        // innerPosition was created by another LM
0798:                        positionList.add(innerPosition);
0799:                        lastLM = innerPosition.getLM();
0800:                    }
0801:                }
0802:
0803:                getPSLM().addIDToPage(getBlockContainerFO().getId());
0804:                if (markers != null) {
0805:                    getCurrentPV().addMarkers(markers, true, isFirst(firstPos),
0806:                            isLast(lastPos));
0807:                }
0808:
0809:                if (bcpos == null) {
0810:                    if (bpUnit == 0) {
0811:                        // the Positions in positionList were inside the elements
0812:                        // created by the LineLM
0813:                        childPosIter = new StackingIter(positionList
0814:                                .listIterator());
0815:                    } else {
0816:                        // the Positions in positionList were inside the elements
0817:                        // created by the BCLM in the createUnitElements() method
0818:                        //if (((Position) positionList.getLast()) instanceof
0819:                        // LeafPosition) {
0820:                        //    // the last item inside positionList is a LeafPosition
0821:                        //    // (a LineBreakPosition, more precisely); this means that
0822:                        //    // the whole paragraph is on the same page
0823:                        //    childPosIter = new KnuthPossPosIter(storedList, 0,
0824:                        // storedList.size());
0825:                        //} else {
0826:                        //    // the last item inside positionList is a Position;
0827:                        //    // this means that the paragraph has been split
0828:                        //    // between consecutive pages
0829:                        LinkedList splitList = new LinkedList();
0830:                        int splitLength = 0;
0831:                        int iFirst = ((MappingPosition) positionList.getFirst())
0832:                                .getFirstIndex();
0833:                        int iLast = ((MappingPosition) positionList.getLast())
0834:                                .getLastIndex();
0835:                        // copy from storedList to splitList all the elements from
0836:                        // iFirst to iLast
0837:                        ListIterator storedListIterator = storedList
0838:                                .listIterator(iFirst);
0839:                        while (storedListIterator.nextIndex() <= iLast) {
0840:                            KnuthElement element = (KnuthElement) storedListIterator
0841:                                    .next();
0842:                            // some elements in storedList (i.e. penalty items) were created
0843:                            // by this BlockLM, and must be ignored
0844:                            if (element.getLayoutManager() != this ) {
0845:                                splitList.add(element);
0846:                                splitLength += element.getW();
0847:                                lastLM = element.getLayoutManager();
0848:                            }
0849:                        }
0850:                        //log.debug("Adding areas from " + iFirst + " to " + iLast);
0851:                        //log.debug("splitLength= " + splitLength
0852:                        //                   + " (" + neededUnits(splitLength) + " units') "
0853:                        //                   + (neededUnits(splitLength) * bpUnit - splitLength) 
0854:                        //                   + " spacing");
0855:                        // add space before and / or after the paragraph
0856:                        // to reach a multiple of bpUnit
0857:                        if (bSpaceBefore && bSpaceAfter) {
0858:                            foBlockSpaceBefore = new SpaceVal(
0859:                                    getBlockContainerFO()
0860:                                            .getCommonMarginBlock().spaceBefore,
0861:                                    this ).getSpace();
0862:                            foBlockSpaceAfter = new SpaceVal(
0863:                                    getBlockContainerFO()
0864:                                            .getCommonMarginBlock().spaceAfter,
0865:                                    this ).getSpace();
0866:                            adjustedSpaceBefore = (neededUnits(splitLength
0867:                                    + foBlockSpaceBefore.min
0868:                                    + foBlockSpaceAfter.min)
0869:                                    * bpUnit - splitLength) / 2;
0870:                            adjustedSpaceAfter = neededUnits(splitLength
0871:                                    + foBlockSpaceBefore.min
0872:                                    + foBlockSpaceAfter.min)
0873:                                    * bpUnit
0874:                                    - splitLength
0875:                                    - adjustedSpaceBefore;
0876:                        } else if (bSpaceBefore) {
0877:                            adjustedSpaceBefore = neededUnits(splitLength
0878:                                    + foBlockSpaceBefore.min)
0879:                                    * bpUnit - splitLength;
0880:                        } else {
0881:                            adjustedSpaceAfter = neededUnits(splitLength
0882:                                    + foBlockSpaceAfter.min)
0883:                                    * bpUnit - splitLength;
0884:                        }
0885:                        //log.debug("space before = " + adjustedSpaceBefore
0886:                        // + " space after = " + adjustedSpaceAfter + " total = " +
0887:                        // (adjustedSpaceBefore + adjustedSpaceAfter + splitLength));
0888:                        childPosIter = new KnuthPossPosIter(splitList, 0,
0889:                                splitList.size());
0890:                        //}
0891:                    }
0892:
0893:                    while ((childLM = childPosIter.getNextChildLM()) != null) {
0894:                        // set last area flag
0895:                        lc.setFlags(LayoutContext.LAST_AREA, (layoutContext
0896:                                .isLastArea() && childLM == lastLM));
0897:                        /*LF*/lc.setStackLimit(layoutContext.getStackLimit());
0898:                        // Add the line areas to Area
0899:                        childLM.addAreas(childPosIter, lc);
0900:                    }
0901:                } else {
0902:                    //Add child areas inside the reference area
0903:                    bcpos.getBreaker().addContainedAreas();
0904:                }
0905:
0906:                if (markers != null) {
0907:                    getCurrentPV().addMarkers(markers, false,
0908:                            isFirst(firstPos), isLast(lastPos));
0909:                }
0910:
0911:                TraitSetter.addSpaceBeforeAfter(viewportBlockArea,
0912:                        layoutContext.getSpaceAdjust(), effSpaceBefore,
0913:                        effSpaceAfter);
0914:                flush();
0915:
0916:                viewportBlockArea = null;
0917:                referenceArea = null;
0918:                resetSpaces();
0919:
0920:                getPSLM().notifyEndOfLayout(
0921:                        ((BlockContainer) getFObj()).getId());
0922:            }
0923:
0924:            /**
0925:             * Get the parent area for children of this block container.
0926:             * This returns the current block container area
0927:             * and creates it if required.
0928:             *
0929:             * @see org.apache.fop.layoutmgr.LayoutManager#getParentArea(Area)
0930:             */
0931:            public Area getParentArea(Area childArea) {
0932:                if (referenceArea == null) {
0933:                    viewportBlockArea = new BlockViewport();
0934:                    viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA,
0935:                            Boolean.TRUE);
0936:                    viewportBlockArea.setIPD(getContentAreaIPD());
0937:                    if (autoHeight) {
0938:                        viewportBlockArea.setBPD(0);
0939:                    } else {
0940:                        viewportBlockArea.setBPD(getContentAreaBPD());
0941:                    }
0942:
0943:                    TraitSetter.setProducerID(viewportBlockArea,
0944:                            getBlockContainerFO().getId());
0945:                    TraitSetter.addBorders(viewportBlockArea,
0946:                            getBlockContainerFO()
0947:                                    .getCommonBorderPaddingBackground(),
0948:                            discardBorderBefore, discardBorderAfter, false,
0949:                            false, this );
0950:                    TraitSetter.addPadding(viewportBlockArea,
0951:                            getBlockContainerFO()
0952:                                    .getCommonBorderPaddingBackground(),
0953:                            discardPaddingBefore, discardPaddingAfter, false,
0954:                            false, this );
0955:                    // TraitSetter.addBackground(viewportBlockArea, 
0956:                    //        getBlockContainerFO().getCommonBorderPaddingBackground(),
0957:                    //        this);
0958:                    TraitSetter.addMargins(viewportBlockArea,
0959:                            getBlockContainerFO()
0960:                                    .getCommonBorderPaddingBackground(),
0961:                            startIndent, endIndent, this );
0962:
0963:                    viewportBlockArea.setCTM(absoluteCTM);
0964:                    viewportBlockArea.setClip(needClip());
0965:                    /*
0966:                    if (getSpaceBefore() != 0) {
0967:                        viewportBlockArea.addTrait(Trait.SPACE_BEFORE, new Integer(getSpaceBefore()));
0968:                    }
0969:                    if (foBlockSpaceAfter.opt != 0) {
0970:                        viewportBlockArea.addTrait(Trait.SPACE_AFTER, new Integer(foBlockSpaceAfter.opt));
0971:                    }*/
0972:
0973:                    if (abProps.absolutePosition == EN_ABSOLUTE
0974:                            || abProps.absolutePosition == EN_FIXED) {
0975:                        Point offset = getAbsOffset();
0976:                        viewportBlockArea.setXOffset(offset.x);
0977:                        viewportBlockArea.setYOffset(offset.y);
0978:                    } else {
0979:                        //nop
0980:                    }
0981:
0982:                    referenceArea = new Block();
0983:                    referenceArea.addTrait(Trait.IS_REFERENCE_AREA,
0984:                            Boolean.TRUE);
0985:                    TraitSetter.setProducerID(referenceArea,
0986:                            getBlockContainerFO().getId());
0987:
0988:                    if (abProps.absolutePosition == EN_ABSOLUTE) {
0989:                        viewportBlockArea.setPositioning(Block.ABSOLUTE);
0990:                    } else if (abProps.absolutePosition == EN_FIXED) {
0991:                        viewportBlockArea.setPositioning(Block.FIXED);
0992:                    }
0993:
0994:                    // Set up dimensions
0995:                    // Must get dimensions from parent area
0996:                    /*Area parentArea =*/parentLM.getParentArea(referenceArea);
0997:                    //int referenceIPD = parentArea.getIPD();
0998:                    referenceArea.setIPD(relDims.ipd);
0999:                    // Get reference IPD from parentArea
1000:                    setCurrentArea(viewportBlockArea); // ??? for generic operations
1001:                }
1002:                return referenceArea;
1003:            }
1004:
1005:            /**
1006:             * Add the child to the block container.
1007:             *
1008:             * @see org.apache.fop.layoutmgr.LayoutManager#addChildArea(Area)
1009:             */
1010:            public void addChildArea(Area childArea) {
1011:                if (referenceArea != null) {
1012:                    referenceArea.addBlock((Block) childArea);
1013:                }
1014:            }
1015:
1016:            /**
1017:             * @see org.apache.fop.layoutmgr.LayoutManager#resetPosition(org.apache.fop.layoutmgr.Position)
1018:             */
1019:            public void resetPosition(Position resetPos) {
1020:                if (resetPos == null) {
1021:                    reset(null);
1022:                }
1023:            }
1024:
1025:            /** 
1026:             * Force current area to be added to parent area.
1027:             * @see org.apache.fop.layoutmgr.BlockStackingLayoutManager#flush()
1028:             */
1029:            protected void flush() {
1030:                viewportBlockArea.addBlock(referenceArea, autoHeight);
1031:
1032:                TraitSetter.addBackground(viewportBlockArea,
1033:                        getBlockContainerFO()
1034:                                .getCommonBorderPaddingBackground(), this );
1035:
1036:                // Fake a 0 height for absolute positioned blocks.
1037:                int saveBPD = viewportBlockArea.getBPD();
1038:                if (viewportBlockArea.getPositioning() == Block.ABSOLUTE) {
1039:                    viewportBlockArea.setBPD(0);
1040:                }
1041:                super .flush();
1042:                // Restore the right height.
1043:                if (viewportBlockArea.getPositioning() == Block.ABSOLUTE) {
1044:                    viewportBlockArea.setBPD(saveBPD);
1045:                }
1046:            }
1047:
1048:            /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager */
1049:            public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
1050:                // TODO Auto-generated method stub
1051:                return 0;
1052:            }
1053:
1054:            /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager */
1055:            public void discardSpace(KnuthGlue spaceGlue) {
1056:                // TODO Auto-generated method stub
1057:
1058:            }
1059:
1060:            /**
1061:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
1062:             */
1063:            public boolean mustKeepTogether() {
1064:                //TODO Keeps will have to be more sophisticated sooner or later
1065:                return (!getBlockContainerFO().getKeepTogether()
1066:                        .getWithinPage().isAuto()
1067:                        || !getBlockContainerFO().getKeepTogether()
1068:                                .getWithinColumn().isAuto()
1069:                        || (getParent() instanceof  BlockLevelLayoutManager && ((BlockLevelLayoutManager) getParent())
1070:                                .mustKeepTogether()) || (getParent() instanceof  InlineLayoutManager && ((InlineLayoutManager) getParent())
1071:                        .mustKeepTogether()));
1072:            }
1073:
1074:            /**
1075:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
1076:             */
1077:            public boolean mustKeepWithPrevious() {
1078:                return !getBlockContainerFO().getKeepWithPrevious()
1079:                        .getWithinPage().isAuto()
1080:                        || !getBlockContainerFO().getKeepWithPrevious()
1081:                                .getWithinColumn().isAuto();
1082:            }
1083:
1084:            /**
1085:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
1086:             */
1087:            public boolean mustKeepWithNext() {
1088:                return !getBlockContainerFO().getKeepWithNext().getWithinPage()
1089:                        .isAuto()
1090:                        || !getBlockContainerFO().getKeepWithNext()
1091:                                .getWithinColumn().isAuto();
1092:            }
1093:
1094:            /**
1095:             * @return the BlockContainer node
1096:             */
1097:            protected BlockContainer getBlockContainerFO() {
1098:                return (BlockContainer) fobj;
1099:            }
1100:
1101:            // --------- Property Resolution related functions --------- //
1102:
1103:            /**
1104:             * @see org.apache.fop.layoutmgr.LayoutManager#getGeneratesReferenceArea
1105:             */
1106:            public boolean getGeneratesReferenceArea() {
1107:                return true;
1108:            }
1109:
1110:            /**
1111:             * @see org.apache.fop.layoutmgr.LayoutManager#getGeneratesBlockArea
1112:             */
1113:            public boolean getGeneratesBlockArea() {
1114:                return true;
1115:            }
1116:
1117:            /** @see org.apache.fop.layoutmgr.ConditionalElementListener */
1118:            public void notifySpace(RelSide side, MinOptMax effectiveLength) {
1119:                if (RelSide.BEFORE == side) {
1120:                    if (log.isDebugEnabled()) {
1121:                        log
1122:                                .debug(this  + ": Space " + side + ", "
1123:                                        + this .effSpaceBefore + "-> "
1124:                                        + effectiveLength);
1125:                    }
1126:                    this .effSpaceBefore = effectiveLength;
1127:                } else {
1128:                    if (log.isDebugEnabled()) {
1129:                        log.debug(this  + ": Space " + side + ", "
1130:                                + this .effSpaceAfter + "-> " + effectiveLength);
1131:                    }
1132:                    this .effSpaceAfter = effectiveLength;
1133:                }
1134:            }
1135:
1136:            /** @see org.apache.fop.layoutmgr.ConditionalElementListener */
1137:            public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
1138:                if (effectiveLength == null) {
1139:                    if (RelSide.BEFORE == side) {
1140:                        this .discardBorderBefore = true;
1141:                    } else {
1142:                        this .discardBorderAfter = true;
1143:                    }
1144:                }
1145:                if (log.isDebugEnabled()) {
1146:                    log.debug(this  + ": Border " + side + " -> "
1147:                            + effectiveLength);
1148:                }
1149:            }
1150:
1151:            /** @see org.apache.fop.layoutmgr.ConditionalElementListener */
1152:            public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
1153:                if (effectiveLength == null) {
1154:                    if (RelSide.BEFORE == side) {
1155:                        this .discardPaddingBefore = true;
1156:                    } else {
1157:                        this .discardPaddingAfter = true;
1158:                    }
1159:                }
1160:                if (log.isDebugEnabled()) {
1161:                    log.debug(this  + ": Padding " + side + " -> "
1162:                            + effectiveLength);
1163:                }
1164:            }
1165:
1166:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.