Source Code Cross Referenced for BlockStackingLayoutManager.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: BlockStackingLayoutManager.java 478928 2006-11-24 17:32:48Z vhennebert $ */
0019:
0020:        package org.apache.fop.layoutmgr;
0021:
0022:        import java.util.Iterator;
0023:        import java.util.LinkedList;
0024:        import java.util.List;
0025:        import java.util.ListIterator;
0026:
0027:        import org.apache.commons.logging.Log;
0028:        import org.apache.commons.logging.LogFactory;
0029:        import org.apache.fop.area.Area;
0030:        import org.apache.fop.area.BlockParent;
0031:        import org.apache.fop.area.Block;
0032:        import org.apache.fop.fo.FObj;
0033:        import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
0034:        import org.apache.fop.fo.properties.SpaceProperty;
0035:        import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
0036:        import org.apache.fop.layoutmgr.inline.LineLayoutManager;
0037:        import org.apache.fop.traits.MinOptMax;
0038:
0039:        /**
0040:         * Base LayoutManager class for all areas which stack their child
0041:         * areas in the block-progression direction, such as Flow, Block, ListBlock.
0042:         */
0043:        public abstract class BlockStackingLayoutManager extends
0044:                AbstractLayoutManager implements  BlockLevelLayoutManager {
0045:
0046:            /**
0047:             * logging instance
0048:             */
0049:            private static Log log = LogFactory
0050:                    .getLog(BlockStackingLayoutManager.class);
0051:
0052:            /**
0053:             * Reference to FO whose areas it's managing or to the traits
0054:             * of the FO.
0055:             */
0056:            //protected LayoutManager curChildLM = null; AbstractLayoutManager also defines this!
0057:            protected BlockParent parentArea = null;
0058:
0059:            /** Value of the block-progression-unit (non-standard property) */
0060:            protected int bpUnit = 0;
0061:            /** space-before value adjusted for block-progression-unit handling */
0062:            protected int adjustedSpaceBefore = 0;
0063:            /** space-after value adjusted for block-progression-unit handling */
0064:            protected int adjustedSpaceAfter = 0;
0065:            /** Only used to store the original list when createUnitElements is called */
0066:            protected LinkedList storedList = null;
0067:            /** Indicates whether break before has been served or not */
0068:            protected boolean breakBeforeServed = false;
0069:            /** Indicates whether the first visible mark has been returned by this LM, yet */
0070:            protected boolean firstVisibleMarkServed = false;
0071:            /** Reference IPD available */
0072:            protected int referenceIPD = 0;
0073:            /** the effective start-indent value */
0074:            protected int startIndent = 0;
0075:            /** the effective end-indent value */
0076:            protected int endIndent = 0;
0077:            /**
0078:             * Holds the (one-time use) fo:block space-before
0079:             * and -after properties.  Large fo:blocks are split
0080:             * into multiple Area. Blocks to accomodate the subsequent
0081:             * regions (pages) they are placed on.  space-before
0082:             * is applied at the beginning of the first
0083:             * Block and space-after at the end of the last Block
0084:             * used in rendering the fo:block.
0085:             */
0086:            protected MinOptMax foSpaceBefore = null;
0087:            /** see foSpaceBefore */
0088:            protected MinOptMax foSpaceAfter = null;
0089:
0090:            private Position auxiliaryPosition;
0091:
0092:            private int contentAreaIPD = 0;
0093:
0094:            /**
0095:             * @param node the fo this LM deals with
0096:             */
0097:            public BlockStackingLayoutManager(FObj node) {
0098:                super (node);
0099:                setGeneratesBlockArea(true);
0100:            }
0101:
0102:            /** 
0103:             * @return current area being filled
0104:             */
0105:            protected BlockParent getCurrentArea() {
0106:                return this .parentArea;
0107:            }
0108:
0109:            /**
0110:             * Set the current area being filled.
0111:             * @param parentArea the current area to be filled
0112:             */
0113:            protected void setCurrentArea(BlockParent parentArea) {
0114:                this .parentArea = parentArea;
0115:            }
0116:
0117:            /**
0118:             * Add a block spacer for space before and space after a block.
0119:             * This adds an empty Block area that acts as a block space.
0120:             *
0121:             * @param adjust the adjustment value
0122:             * @param minoptmax the min/opt/max value of the spacing
0123:             */
0124:            public void addBlockSpacing(double adjust, MinOptMax minoptmax) {
0125:                int sp = TraitSetter.getEffectiveSpace(adjust, minoptmax);
0126:                if (sp != 0) {
0127:                    Block spacer = new Block();
0128:                    spacer.setBPD(sp);
0129:                    parentLM.addChildArea(spacer);
0130:                }
0131:            }
0132:
0133:            /**
0134:             * Add the childArea to the passed area.
0135:             * Called by child LayoutManager when it has filled one of its areas.
0136:             * The LM should already have an Area in which to put the child.
0137:             * See if the area will fit in the current area.
0138:             * If so, add it. Otherwise initiate breaking.
0139:             * @param childArea the area to add: will be some block-stacked Area.
0140:             * @param parentArea the area in which to add the childArea
0141:             */
0142:            protected void addChildToArea(Area childArea, BlockParent parentArea) {
0143:                // This should be a block-level Area (Block in the generic sense)
0144:                if (!(childArea instanceof  Block)) {
0145:                    //log.error("Child not a Block in BlockStackingLM!");
0146:                }
0147:
0148:                parentArea.addBlock((Block) childArea);
0149:                flush(); // hand off current area to parent
0150:            }
0151:
0152:            /**
0153:             * Add the childArea to the current area.
0154:             * Called by child LayoutManager when it has filled one of its areas.
0155:             * The LM should already have an Area in which to put the child.
0156:             * See if the area will fit in the current area.
0157:             * If so, add it. Otherwise initiate breaking.
0158:             * @param childArea the area to add: will be some block-stacked Area.
0159:             */
0160:            public void addChildArea(Area childArea) {
0161:                addChildToArea(childArea, getCurrentArea());
0162:            }
0163:
0164:            /**
0165:             * Force current area to be added to parent area.
0166:             */
0167:            protected void flush() {
0168:                if (getCurrentArea() != null) {
0169:                    parentLM.addChildArea(getCurrentArea());
0170:                }
0171:            }
0172:
0173:            /** @return a cached auxiliary Position instance used for things like spaces. */
0174:            protected Position getAuxiliaryPosition() {
0175:                if (this .auxiliaryPosition == null) {
0176:                    this .auxiliaryPosition = new NonLeafPosition(this , null);
0177:                }
0178:                return this .auxiliaryPosition;
0179:            }
0180:
0181:            /**
0182:             * @param len length in millipoints to span with bp units
0183:             * @return the minimum integer n such that n * bpUnit >= len
0184:             */
0185:            protected int neededUnits(int len) {
0186:                return (int) Math.ceil((float) len / bpUnit);
0187:            }
0188:
0189:            /**
0190:             * Determines and sets the content area IPD based on available reference area IPD, start- and
0191:             * end-indent properties.
0192:             * end-indent is adjusted based on overconstrained geometry rules, if necessary.
0193:             * @return the resulting content area IPD
0194:             */
0195:            protected int updateContentAreaIPDwithOverconstrainedAdjust() {
0196:                int ipd = referenceIPD - (startIndent + endIndent);
0197:                if (ipd < 0) {
0198:                    //5.3.4, XSL 1.0, Overconstrained Geometry
0199:                    log
0200:                            .debug("Adjusting end-indent based on overconstrained geometry rules for "
0201:                                    + fobj);
0202:                    endIndent += ipd;
0203:                    ipd = 0;
0204:                    //TODO Should we skip layout for a block that has ipd=0?
0205:                }
0206:                setContentAreaIPD(ipd);
0207:                return ipd;
0208:            }
0209:
0210:            /**
0211:             * Sets the content area IPD by directly supplying the value. 
0212:             * end-indent is adjusted based on overconstrained geometry rules, if necessary.
0213:             * @return the resulting content area IPD
0214:             */
0215:            protected int updateContentAreaIPDwithOverconstrainedAdjust(
0216:                    int contentIPD) {
0217:                int ipd = referenceIPD
0218:                        - (contentIPD + (startIndent + endIndent));
0219:                if (ipd < 0) {
0220:                    //5.3.4, XSL 1.0, Overconstrained Geometry
0221:                    log
0222:                            .debug("Adjusting end-indent based on overconstrained geometry rules for "
0223:                                    + fobj);
0224:                    endIndent += ipd;
0225:                }
0226:                setContentAreaIPD(contentIPD);
0227:                return contentIPD;
0228:            }
0229:
0230:            /**
0231:             * @see LayoutManager#getNextKnuthElements(LayoutContext, int)
0232:             */
0233:            public LinkedList getNextKnuthElements(LayoutContext context,
0234:                    int alignment) {
0235:                //log.debug("BLM.getNextKnuthElements> keep-together = "
0236:                // + layoutProps.keepTogether.getType());
0237:                //log.debug(" keep-with-previous = " +
0238:                // layoutProps.keepWithPrevious.getType());
0239:                //log.debug(" keep-with-next = " +
0240:                // layoutProps.keepWithNext.getType());
0241:                BlockLevelLayoutManager curLM; // currently active LM
0242:                BlockLevelLayoutManager prevLM = null; // previously active LM
0243:
0244:                referenceIPD = context.getRefIPD();
0245:
0246:                updateContentAreaIPDwithOverconstrainedAdjust();
0247:
0248:                LinkedList returnedList = null;
0249:                LinkedList contentList = new LinkedList();
0250:                LinkedList returnList = new LinkedList();
0251:
0252:                if (!breakBeforeServed) {
0253:                    try {
0254:                        if (addKnuthElementsForBreakBefore(returnList, context)) {
0255:                            return returnList;
0256:                        }
0257:                    } finally {
0258:                        breakBeforeServed = true;
0259:                    }
0260:                }
0261:
0262:                if (!firstVisibleMarkServed) {
0263:                    addKnuthElementsForSpaceBefore(returnList, alignment);
0264:                }
0265:
0266:                addKnuthElementsForBorderPaddingBefore(returnList,
0267:                        !firstVisibleMarkServed);
0268:                firstVisibleMarkServed = true;
0269:
0270:                //Spaces, border and padding to be repeated at each break
0271:                addPendingMarks(context);
0272:
0273:                while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
0274:                    LayoutContext childLC = new LayoutContext(0);
0275:                    childLC.copyPendingMarksFrom(context);
0276:                    if (curLM instanceof  LineLayoutManager) {
0277:                        // curLM is a LineLayoutManager
0278:                        // set stackLimit for lines (stack limit is now i-p-direction, not b-p-direction!)
0279:                        childLC
0280:                                .setStackLimit(new MinOptMax(
0281:                                        getContentAreaIPD()));
0282:                        childLC.setRefIPD(getContentAreaIPD());
0283:                    } else {
0284:                        // curLM is a ?
0285:                        //childLC.setStackLimit(MinOptMax.subtract(context
0286:                        //        .getStackLimit(), stackSize));
0287:                        childLC.setStackLimit(context.getStackLimit());
0288:                        childLC.setRefIPD(referenceIPD);
0289:                    }
0290:
0291:                    // get elements from curLM
0292:                    returnedList = curLM.getNextKnuthElements(childLC,
0293:                            alignment);
0294:                    if (contentList.size() == 0
0295:                            && childLC.isKeepWithPreviousPending()) {
0296:                        context
0297:                                .setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
0298:                        childLC
0299:                                .setFlags(
0300:                                        LayoutContext.KEEP_WITH_PREVIOUS_PENDING,
0301:                                        false);
0302:                    }
0303:                    if (returnedList != null
0304:                            && returnedList.size() == 1
0305:                            && ((ListElement) returnedList.getFirst())
0306:                                    .isForcedBreak()) {
0307:                        // a descendant of this block has break-before
0308:                        /*
0309:                        if (returnList.size() == 0) {
0310:                            // the first child (or its first child ...) has
0311:                            // break-before;
0312:                            // all this block, including space before, will be put in
0313:                            // the
0314:                            // following page
0315:                            bSpaceBeforeServed = false;
0316:                        }*/
0317:                        contentList.addAll(returnedList);
0318:
0319:                        /* extension: conversione di tutta la sequenza fin'ora ottenuta */
0320:                        if (bpUnit > 0) {
0321:                            storedList = contentList;
0322:                            contentList = createUnitElements(contentList);
0323:                        }
0324:                        /* end of extension */
0325:
0326:                        // "wrap" the Position inside each element
0327:                        // moving the elements from contentList to returnList
0328:                        returnedList = new LinkedList();
0329:                        wrapPositionElements(contentList, returnList);
0330:
0331:                        return returnList;
0332:                    } else {
0333:                        if (prevLM != null) {
0334:                            // there is a block handled by prevLM
0335:                            // before the one handled by curLM
0336:                            if (mustKeepTogether()
0337:                                    || context.isKeepWithNextPending()
0338:                                    || childLC.isKeepWithPreviousPending()) {
0339:                                // Clear keep pending flag
0340:                                context.setFlags(
0341:                                        LayoutContext.KEEP_WITH_NEXT_PENDING,
0342:                                        false);
0343:                                // add an infinite penalty to forbid a break between
0344:                                // blocks
0345:                                contentList.add(new BreakElement(new Position(
0346:                                        this ), KnuthElement.INFINITE, context));
0347:                            } else if (!((ListElement) contentList.getLast())
0348:                                    .isGlue()) {
0349:                                // add a null penalty to allow a break between blocks
0350:                                contentList.add(new BreakElement(new Position(
0351:                                        this ), 0, context));
0352:                            } else {
0353:                                // the last element in contentList is a glue;
0354:                                // it is a feasible breakpoint, there is no need to add
0355:                                // a penalty
0356:                                log
0357:                                        .warn("glue-type break possibility not handled properly, yet");
0358:                                //TODO Does this happen? If yes, need to deal with border and padding
0359:                                //at the break possibility
0360:                            }
0361:                        }
0362:                        if (returnedList == null || returnedList.size() == 0) {
0363:                            //Avoid NoSuchElementException below (happens with empty blocks)
0364:                            continue;
0365:                        }
0366:                        contentList.addAll(returnedList);
0367:                        if (((ListElement) returnedList.getLast())
0368:                                .isForcedBreak()) {
0369:                            // a descendant of this block has break-after
0370:
0371:                            /* extension: conversione di tutta la sequenza fin'ora ottenuta */
0372:                            if (bpUnit > 0) {
0373:                                storedList = contentList;
0374:                                contentList = createUnitElements(contentList);
0375:                            }
0376:                            /* end of extension */
0377:
0378:                            returnedList = new LinkedList();
0379:                            wrapPositionElements(contentList, returnList);
0380:
0381:                            return returnList;
0382:                        }
0383:                    }
0384:                    // propagate and clear
0385:                    context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING,
0386:                            childLC.isKeepWithNextPending());
0387:                    childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING,
0388:                            false);
0389:                    childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING,
0390:                            false);
0391:                    prevLM = curLM;
0392:                }
0393:
0394:                /* Extension: conversione di tutta la sequenza fin'ora ottenuta */
0395:                if (bpUnit > 0) {
0396:                    storedList = contentList;
0397:                    contentList = createUnitElements(contentList);
0398:                }
0399:                /* end of extension */
0400:
0401:                returnedList = new LinkedList();
0402:                if (contentList.size() > 0) {
0403:                    wrapPositionElements(contentList, returnList);
0404:                } else {
0405:                    //Empty fo:block, zero-length box makes sure the IDs are registered.
0406:                    returnList.add(new KnuthBox(0,
0407:                            notifyPos(new Position(this )), true));
0408:                }
0409:
0410:                addKnuthElementsForBorderPaddingAfter(returnList, true);
0411:                addKnuthElementsForSpaceAfter(returnList, alignment);
0412:                addKnuthElementsForBreakAfter(returnList, context);
0413:
0414:                if (mustKeepWithNext()) {
0415:                    context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
0416:                }
0417:                if (mustKeepWithPrevious()) {
0418:                    context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
0419:                }
0420:
0421:                setFinished(true);
0422:
0423:                return returnList;
0424:            }
0425:
0426:            /**
0427:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
0428:             */
0429:            public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
0430:                /*LF*///log.debug("  BLM.negotiateBPDAdjustment> " + adj);
0431:                /*LF*///log.debug("  lastElement e' " + (lastElement.isPenalty() 
0432:                //      ? "penalty" : (lastElement.isGlue() ? "glue" : "box" )));
0433:                /*LF*///log.debug("  position e' " + lastElement.getPosition().getClass().getName());
0434:                /*LF*///log.debug("  " + (bpUnit > 0 ? "unit" : ""));
0435:                Position innerPosition = ((NonLeafPosition) lastElement
0436:                        .getPosition()).getPosition();
0437:
0438:                if (innerPosition == null && lastElement.isGlue()) {
0439:                    // this adjustment applies to space-before or space-after of this block
0440:                    if (((KnuthGlue) lastElement).getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) {
0441:                        // this adjustment applies to space-before
0442:                        adjustedSpaceBefore += adj;
0443:                        /*LF*///log.debug("  BLM.negotiateBPDAdjustment> spazio prima: " + adj);
0444:                    } else {
0445:                        // this adjustment applies to space-after
0446:                        adjustedSpaceAfter += adj;
0447:                        /*LF*///log.debug("  BLM.negotiateBPDAdjustment> spazio dopo: " + adj);
0448:                    }
0449:                    return adj;
0450:                } else if (innerPosition instanceof  MappingPosition) {
0451:                    // this block has block-progression-unit > 0: the adjustment can concern
0452:                    // - the space-before or space-after of this block, 
0453:                    // - the line number of a descendant of this block
0454:                    MappingPosition mappingPos = (MappingPosition) innerPosition;
0455:                    if (lastElement.isGlue()) {
0456:                        // lastElement is a glue
0457:                        /*LF*///log.debug("  BLM.negotiateBPDAdjustment> bpunit con glue");
0458:                        ListIterator storedListIterator = storedList
0459:                                .listIterator(mappingPos.getFirstIndex());
0460:                        int newAdjustment = 0;
0461:                        while (storedListIterator.nextIndex() <= mappingPos
0462:                                .getLastIndex()) {
0463:                            KnuthElement storedElement = (KnuthElement) storedListIterator
0464:                                    .next();
0465:                            if (storedElement.isGlue()) {
0466:                                newAdjustment += ((BlockLevelLayoutManager) storedElement
0467:                                        .getLayoutManager())
0468:                                        .negotiateBPDAdjustment(adj
0469:                                                - newAdjustment, storedElement);
0470:                                /*LF*///log.debug("  BLM.negotiateBPDAdjustment> (progressivo) righe: " 
0471:                                //  + newAdjustment);
0472:                            }
0473:                        }
0474:                        newAdjustment = (newAdjustment > 0 ? bpUnit
0475:                                * neededUnits(newAdjustment) : -bpUnit
0476:                                * neededUnits(-newAdjustment));
0477:                        return newAdjustment;
0478:                    } else {
0479:                        // lastElement is a penalty: this means that the paragraph
0480:                        // has been split between consecutive pages:
0481:                        // this may involve a change in the number of lines
0482:                        /*LF*///log.debug("  BLM.negotiateBPDAdjustment> bpunit con penalty");
0483:                        KnuthPenalty storedPenalty = (KnuthPenalty) storedList
0484:                                .get(mappingPos.getLastIndex());
0485:                        if (storedPenalty.getW() > 0) {
0486:                            // the original penalty has width > 0
0487:                            /*LF*///log.debug("  BLM.negotiateBPDAdjustment> chiamata passata");
0488:                            return ((BlockLevelLayoutManager) storedPenalty
0489:                                    .getLayoutManager())
0490:                                    .negotiateBPDAdjustment(storedPenalty
0491:                                            .getW(),
0492:                                            (KnuthElement) storedPenalty);
0493:                        } else {
0494:                            // the original penalty has width = 0
0495:                            // the adjustment involves only the spaces before and after
0496:                            /*LF*///log.debug("  BLM.negotiateBPDAdjustment> chiamata gestita");
0497:                            return adj;
0498:                        }
0499:                    }
0500:                } else if (innerPosition.getLM() != this ) {
0501:                    // this adjustment concerns another LM
0502:                    NonLeafPosition savedPos = (NonLeafPosition) lastElement
0503:                            .getPosition();
0504:                    lastElement.setPosition(innerPosition);
0505:                    int returnValue = ((BlockLevelLayoutManager) lastElement
0506:                            .getLayoutManager()).negotiateBPDAdjustment(adj,
0507:                            lastElement);
0508:                    lastElement.setPosition(savedPos);
0509:                    /*LF*///log.debug("  BLM.negotiateBPDAdjustment> righe: " + returnValue);
0510:                    return returnValue;
0511:                } else {
0512:                    // this should never happen
0513:                    log
0514:                            .error("BlockLayoutManager.negotiateBPDAdjustment(): unexpected Position");
0515:                    return 0;
0516:                }
0517:            }
0518:
0519:            /**
0520:             * @see BlockLevelLayoutManager#discardSpace(KnuthGlue)
0521:             */
0522:            public void discardSpace(KnuthGlue spaceGlue) {
0523:                //log.debug("  BLM.discardSpace> " + spaceGlue.getPosition().getClass().getName());
0524:                Position innerPosition = ((NonLeafPosition) spaceGlue
0525:                        .getPosition()).getPosition();
0526:
0527:                if (innerPosition == null || innerPosition.getLM() == this ) {
0528:                    // if this block has block-progression-unit > 0, innerPosition can be
0529:                    // a MappingPosition
0530:                    // spaceGlue represents space before or space after of this block
0531:                    if (spaceGlue.getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) {
0532:                        // space-before must be discarded
0533:                        adjustedSpaceBefore = 0;
0534:                        foSpaceBefore = new MinOptMax(0);
0535:                    } else {
0536:                        // space-after must be discarded
0537:                        adjustedSpaceAfter = 0;
0538:                        foSpaceAfter = new MinOptMax(0);
0539:                        //TODO Why are both cases handled in the same way?
0540:                    }
0541:                } else {
0542:                    // this element was not created by this BlockLM
0543:                    NonLeafPosition savedPos = (NonLeafPosition) spaceGlue
0544:                            .getPosition();
0545:                    spaceGlue.setPosition(innerPosition);
0546:                    ((BlockLevelLayoutManager) spaceGlue.getLayoutManager())
0547:                            .discardSpace(spaceGlue);
0548:                    spaceGlue.setPosition(savedPos);
0549:                }
0550:            }
0551:
0552:            /**
0553:             * @see LayoutManager#getChangedKnuthElements(List, int)
0554:             */
0555:            public LinkedList getChangedKnuthElements(List oldList,
0556:                    int alignment) {
0557:                /*LF*///log.debug("");
0558:                /*LF*///log.debug("  BLM.getChangedKnuthElements> inizio: oldList.size() = " 
0559:                //  + oldList.size());
0560:                ListIterator oldListIterator = oldList.listIterator();
0561:                KnuthElement returnedElement;
0562:                KnuthElement currElement = null;
0563:                KnuthElement prevElement = null;
0564:                LinkedList returnedList = new LinkedList();
0565:                LinkedList returnList = new LinkedList();
0566:                int fromIndex = 0;
0567:
0568:                // "unwrap" the Positions stored in the elements
0569:                KnuthElement oldElement = null;
0570:                while (oldListIterator.hasNext()) {
0571:                    oldElement = (KnuthElement) oldListIterator.next();
0572:                    Position innerPosition = ((NonLeafPosition) oldElement
0573:                            .getPosition()).getPosition();
0574:                    //log.debug(" BLM> unwrapping: " 
0575:                    //  + (oldElement.isBox() ? "box    " : (oldElement.isGlue() ? "glue   " : "penalty")) 
0576:                    //  + " creato da " + oldElement.getLayoutManager().getClass().getName());
0577:                    //log.debug(" BLM> unwrapping:         " 
0578:                    //  + oldElement.getPosition().getClass().getName());
0579:                    if (innerPosition != null) {
0580:                        // oldElement was created by a descendant of this BlockLM
0581:                        oldElement.setPosition(innerPosition);
0582:                    } else {
0583:                        // thisElement was created by this BlockLM
0584:                        // modify its position in order to recognize it was not created
0585:                        // by a child
0586:                        oldElement.setPosition(new Position(this ));
0587:                    }
0588:                }
0589:
0590:                // create the iterator
0591:                List workList;
0592:                if (bpUnit == 0) {
0593:                    workList = oldList;
0594:                } else {
0595:                    // the storedList must be used instead of oldList;
0596:                    // find the index of the first element of returnedList
0597:                    // corresponding to the first element of oldList
0598:                    oldListIterator = oldList.listIterator();
0599:                    KnuthElement el = (KnuthElement) oldListIterator.next();
0600:                    while (!(el.getPosition() instanceof  MappingPosition)) {
0601:                        el = (KnuthElement) oldListIterator.next();
0602:                    }
0603:                    int iFirst = ((MappingPosition) el.getPosition())
0604:                            .getFirstIndex();
0605:
0606:                    // find the index of the last element of returnedList
0607:                    // corresponding to the last element of oldList
0608:                    oldListIterator = oldList.listIterator(oldList.size());
0609:                    el = (KnuthElement) oldListIterator.previous();
0610:                    while (!(el.getPosition() instanceof  MappingPosition)) {
0611:                        el = (KnuthElement) oldListIterator.previous();
0612:                    }
0613:                    int iLast = ((MappingPosition) el.getPosition())
0614:                            .getLastIndex();
0615:
0616:                    //log-debug("  si usa storedList da " + iFirst + " a " + iLast 
0617:                    //  + " compresi su " + storedList.size() + " elementi totali");
0618:                    workList = storedList.subList(iFirst, iLast + 1);
0619:                }
0620:                ListIterator workListIterator = workList.listIterator();
0621:
0622:                //log.debug("  BLM.getChangedKnuthElements> workList.size() = " 
0623:                //  + workList.size() + " da 0 a " + (workList.size() - 1));
0624:
0625:                while (workListIterator.hasNext()) {
0626:                    currElement = (KnuthElement) workListIterator.next();
0627:                    //log.debug("elemento n. " + workListIterator.previousIndex() 
0628:                    //  + " nella workList");
0629:                    if (prevElement != null
0630:                            && prevElement.getLayoutManager() != currElement
0631:                                    .getLayoutManager()) {
0632:                        // prevElement is the last element generated by the same LM
0633:                        BlockLevelLayoutManager prevLM = (BlockLevelLayoutManager) prevElement
0634:                                .getLayoutManager();
0635:                        BlockLevelLayoutManager currLM = (BlockLevelLayoutManager) currElement
0636:                                .getLayoutManager();
0637:                        boolean bSomethingAdded = false;
0638:                        if (prevLM != this ) {
0639:                            //log.debug(" BLM.getChangedKnuthElements> chiamata da " 
0640:                            //    + fromIndex + " a " + workListIterator.previousIndex() + " su " 
0641:                            //    + prevLM.getClass().getName());
0642:                            returnedList.addAll(prevLM.getChangedKnuthElements(
0643:                                    workList.subList(fromIndex,
0644:                                            workListIterator.previousIndex()),
0645:                                    alignment));
0646:                            bSomethingAdded = true;
0647:                        } else {
0648:                            // prevLM == this
0649:                            // do nothing
0650:                            //log.debug(" BLM.getChangedKnuthElements> elementi propri, "
0651:                            //  + "ignorati, da " + fromIndex + " a " + workListIterator.previousIndex() 
0652:                            //  + " su " + prevLM.getClass().getName());
0653:                        }
0654:                        fromIndex = workListIterator.previousIndex();
0655:
0656:                        /*
0657:                         * TODO: why are KnuthPenalties added here,
0658:                         *       while in getNextKE they were changed to BreakElements?
0659:                         */
0660:                        // there is another block after this one
0661:                        if (bSomethingAdded
0662:                                && (this .mustKeepTogether()
0663:                                        || prevLM.mustKeepWithNext() || currLM
0664:                                        .mustKeepWithPrevious())) {
0665:                            // add an infinite penalty to forbid a break between blocks
0666:                            returnedList.add(new KnuthPenalty(0,
0667:                                    KnuthElement.INFINITE, false, new Position(
0668:                                            this ), false));
0669:                        } else if (bSomethingAdded
0670:                                && !((KnuthElement) returnedList.getLast())
0671:                                        .isGlue()) {
0672:                            // add a null penalty to allow a break between blocks
0673:                            returnedList.add(new KnuthPenalty(0, 0, false,
0674:                                    new Position(this ), false));
0675:                        }
0676:                    }
0677:                    prevElement = currElement;
0678:                }
0679:                if (currElement != null) {
0680:                    BlockLevelLayoutManager currLM = (BlockLevelLayoutManager) currElement
0681:                            .getLayoutManager();
0682:                    if (currLM != this ) {
0683:                        //log.debug(" BLM.getChangedKnuthElements> chiamata da " + fromIndex 
0684:                        //  + " a " + oldList.size() + " su " + currLM.getClass().getName());
0685:                        returnedList.addAll(currLM.getChangedKnuthElements(
0686:                                workList.subList(fromIndex, workList.size()),
0687:                                alignment));
0688:                    } else {
0689:                        // currLM == this
0690:                        // there are no more elements to add
0691:                        // remove the last penalty added to returnedList
0692:                        if (returnedList.size() > 0) {
0693:                            returnedList.removeLast();
0694:                        }
0695:                        //log.debug(" BLM.getChangedKnuthElements> elementi propri, ignorati, da " 
0696:                        //  + fromIndex + " a " + workList.size());
0697:                    }
0698:                }
0699:
0700:                // append elements representing space-before
0701:                boolean spaceBeforeIsConditional = true;
0702:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
0703:                    spaceBeforeIsConditional = ((org.apache.fop.fo.flow.Block) fobj)
0704:                            .getCommonMarginBlock().spaceBefore.getSpace()
0705:                            .isDiscard();
0706:                }
0707:                if (bpUnit > 0 || adjustedSpaceBefore != 0) {
0708:                    if (!spaceBeforeIsConditional) {
0709:                        // add elements to prevent the glue to be discarded
0710:                        returnList.add(new KnuthBox(0, new NonLeafPosition(
0711:                                this , null), false));
0712:                        returnList.add(new KnuthPenalty(0,
0713:                                KnuthElement.INFINITE, false,
0714:                                new NonLeafPosition(this , null), false));
0715:                    }
0716:                    if (bpUnit > 0) {
0717:                        returnList.add(new KnuthGlue(0, 0, 0,
0718:                                SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(
0719:                                        this , null), true));
0720:                    } else {
0721:                        returnList.add(new KnuthGlue(adjustedSpaceBefore, 0, 0,
0722:                                SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(
0723:                                        this , null), true));
0724:                    }
0725:                }
0726:
0727:                //log.debug("  BLM.getChangedKnuthElements> intermedio: returnedList.size() = " 
0728:                //    + returnedList.size());
0729:
0730:                /* estensione: conversione complessiva */
0731:                /*LF*/if (bpUnit > 0) {
0732:                    /*LF*/storedList = returnedList;
0733:                    /*LF*/returnedList = createUnitElements(returnedList);
0734:                    /*LF*/}
0735:                /* estensione */
0736:
0737:                // "wrap" the Position stored in each element of returnedList
0738:                // and add elements to returnList
0739:                ListIterator listIter = returnedList.listIterator();
0740:                while (listIter.hasNext()) {
0741:                    returnedElement = (KnuthElement) listIter.next();
0742:                    returnedElement.setPosition(new NonLeafPosition(this ,
0743:                            returnedElement.getPosition()));
0744:                    returnList.add(returnedElement);
0745:                }
0746:
0747:                // append elements representing space-after
0748:                boolean spaceAfterIsConditional = true;
0749:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
0750:                    spaceAfterIsConditional = ((org.apache.fop.fo.flow.Block) fobj)
0751:                            .getCommonMarginBlock().spaceAfter.getSpace()
0752:                            .isDiscard();
0753:                }
0754:                if (bpUnit > 0 || adjustedSpaceAfter != 0) {
0755:                    if (!spaceAfterIsConditional) {
0756:                        returnList.add(new KnuthPenalty(0,
0757:                                KnuthElement.INFINITE, false,
0758:                                new NonLeafPosition(this , null), false));
0759:                    }
0760:                    if (bpUnit > 0) {
0761:                        returnList.add(new KnuthGlue(0, 0, 0,
0762:                                SPACE_AFTER_ADJUSTMENT, new NonLeafPosition(
0763:                                        this , null),
0764:                                (!spaceAfterIsConditional) ? false : true));
0765:                    } else {
0766:                        returnList.add(new KnuthGlue(adjustedSpaceAfter, 0, 0,
0767:                                SPACE_AFTER_ADJUSTMENT, new NonLeafPosition(
0768:                                        this , null),
0769:                                (!spaceAfterIsConditional) ? false : true));
0770:                    }
0771:                    if (!spaceAfterIsConditional) {
0772:                        returnList.add(new KnuthBox(0, new NonLeafPosition(
0773:                                this , null), true));
0774:                    }
0775:                }
0776:
0777:                //log.debug("  BLM.getChangedKnuthElements> finished: returnList.size() = " 
0778:                //  + returnList.size());
0779:                return returnList;
0780:            }
0781:
0782:            /**
0783:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
0784:             */
0785:            // default action: ask parentLM
0786:            public boolean mustKeepTogether() {
0787:                return ((getParent() instanceof  BlockLevelLayoutManager && ((BlockLevelLayoutManager) getParent())
0788:                        .mustKeepTogether()) || (getParent() instanceof  InlineLayoutManager && ((InlineLayoutManager) getParent())
0789:                        .mustKeepTogether()));
0790:            }
0791:
0792:            /**
0793:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
0794:             */
0795:            public boolean mustKeepWithPrevious() {
0796:                return false;
0797:            }
0798:
0799:            /**
0800:             * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
0801:             */
0802:            public boolean mustKeepWithNext() {
0803:                return false;
0804:            }
0805:
0806:            /**
0807:             * Adds the unresolved elements for border and padding to a layout context so break
0808:             * possibilities can be properly constructed.
0809:             * @param context the layout context
0810:             */
0811:            protected void addPendingMarks(LayoutContext context) {
0812:                CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
0813:                if (borderAndPadding != null) {
0814:                    if (borderAndPadding.getBorderBeforeWidth(false) > 0) {
0815:                        context.addPendingBeforeMark(new BorderElement(
0816:                                getAuxiliaryPosition(),
0817:                                borderAndPadding.getBorderInfo(
0818:                                        CommonBorderPaddingBackground.BEFORE)
0819:                                        .getWidth(), RelSide.BEFORE, false,
0820:                                false, this ));
0821:                    }
0822:                    if (borderAndPadding.getPaddingBefore(false, this ) > 0) {
0823:                        context
0824:                                .addPendingBeforeMark(new PaddingElement(
0825:                                        getAuxiliaryPosition(),
0826:                                        borderAndPadding
0827:                                                .getPaddingLengthProperty(CommonBorderPaddingBackground.BEFORE),
0828:                                        RelSide.BEFORE, false, false, this ));
0829:                    }
0830:                    if (borderAndPadding.getBorderAfterWidth(false) > 0) {
0831:                        context.addPendingAfterMark(new BorderElement(
0832:                                getAuxiliaryPosition(),
0833:                                borderAndPadding.getBorderInfo(
0834:                                        CommonBorderPaddingBackground.AFTER)
0835:                                        .getWidth(), RelSide.AFTER, false,
0836:                                false, this ));
0837:                    }
0838:                    if (borderAndPadding.getPaddingAfter(false, this ) > 0) {
0839:                        context
0840:                                .addPendingAfterMark(new PaddingElement(
0841:                                        getAuxiliaryPosition(),
0842:                                        borderAndPadding
0843:                                                .getPaddingLengthProperty(CommonBorderPaddingBackground.AFTER),
0844:                                        RelSide.AFTER, false, false, this ));
0845:                    }
0846:                }
0847:            }
0848:
0849:            /** @return the border, padding and background info structure */
0850:            private CommonBorderPaddingBackground getBorderPaddingBackground() {
0851:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
0852:                    return ((org.apache.fop.fo.flow.Block) fobj)
0853:                            .getCommonBorderPaddingBackground();
0854:                } else if (fobj instanceof  org.apache.fop.fo.flow.BlockContainer) {
0855:                    return ((org.apache.fop.fo.flow.BlockContainer) fobj)
0856:                            .getCommonBorderPaddingBackground();
0857:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListBlock) {
0858:                    return ((org.apache.fop.fo.flow.ListBlock) fobj)
0859:                            .getCommonBorderPaddingBackground();
0860:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListItem) {
0861:                    return ((org.apache.fop.fo.flow.ListItem) fobj)
0862:                            .getCommonBorderPaddingBackground();
0863:                } else if (fobj instanceof  org.apache.fop.fo.flow.Table) {
0864:                    return ((org.apache.fop.fo.flow.Table) fobj)
0865:                            .getCommonBorderPaddingBackground();
0866:                } else {
0867:                    return null;
0868:                }
0869:            }
0870:
0871:            /** @return the space-before property */
0872:            private SpaceProperty getSpaceBeforeProperty() {
0873:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
0874:                    return ((org.apache.fop.fo.flow.Block) fobj)
0875:                            .getCommonMarginBlock().spaceBefore;
0876:                } else if (fobj instanceof  org.apache.fop.fo.flow.BlockContainer) {
0877:                    return ((org.apache.fop.fo.flow.BlockContainer) fobj)
0878:                            .getCommonMarginBlock().spaceBefore;
0879:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListBlock) {
0880:                    return ((org.apache.fop.fo.flow.ListBlock) fobj)
0881:                            .getCommonMarginBlock().spaceBefore;
0882:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListItem) {
0883:                    return ((org.apache.fop.fo.flow.ListItem) fobj)
0884:                            .getCommonMarginBlock().spaceBefore;
0885:                } else if (fobj instanceof  org.apache.fop.fo.flow.Table) {
0886:                    return ((org.apache.fop.fo.flow.Table) fobj)
0887:                            .getCommonMarginBlock().spaceBefore;
0888:                } else {
0889:                    return null;
0890:                }
0891:            }
0892:
0893:            /** @return the space-after property */
0894:            private SpaceProperty getSpaceAfterProperty() {
0895:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
0896:                    return ((org.apache.fop.fo.flow.Block) fobj)
0897:                            .getCommonMarginBlock().spaceAfter;
0898:                } else if (fobj instanceof  org.apache.fop.fo.flow.BlockContainer) {
0899:                    return ((org.apache.fop.fo.flow.BlockContainer) fobj)
0900:                            .getCommonMarginBlock().spaceAfter;
0901:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListBlock) {
0902:                    return ((org.apache.fop.fo.flow.ListBlock) fobj)
0903:                            .getCommonMarginBlock().spaceAfter;
0904:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListItem) {
0905:                    return ((org.apache.fop.fo.flow.ListItem) fobj)
0906:                            .getCommonMarginBlock().spaceAfter;
0907:                } else if (fobj instanceof  org.apache.fop.fo.flow.Table) {
0908:                    return ((org.apache.fop.fo.flow.Table) fobj)
0909:                            .getCommonMarginBlock().spaceAfter;
0910:                } else {
0911:                    return null;
0912:                }
0913:            }
0914:
0915:            /**
0916:             * Creates Knuth elements for before border padding and adds them to the return list.
0917:             * @param returnList return list to add the additional elements to
0918:             * @param isFirst true if this is the first time a layout manager instance needs to generate 
0919:             *                border and padding
0920:             */
0921:            protected void addKnuthElementsForBorderPaddingBefore(
0922:                    LinkedList returnList, boolean isFirst) {
0923:                //Border and Padding (before)
0924:                CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
0925:                if (borderAndPadding != null) {
0926:                    if (borderAndPadding.getBorderBeforeWidth(false) > 0) {
0927:                        returnList.add(new BorderElement(
0928:                                getAuxiliaryPosition(),
0929:                                borderAndPadding.getBorderInfo(
0930:                                        CommonBorderPaddingBackground.BEFORE)
0931:                                        .getWidth(), RelSide.BEFORE, isFirst,
0932:                                false, this ));
0933:                    }
0934:                    if (borderAndPadding.getPaddingBefore(false, this ) > 0) {
0935:                        returnList
0936:                                .add(new PaddingElement(
0937:                                        getAuxiliaryPosition(),
0938:                                        borderAndPadding
0939:                                                .getPaddingLengthProperty(CommonBorderPaddingBackground.BEFORE),
0940:                                        RelSide.BEFORE, isFirst, false, this ));
0941:                    }
0942:                }
0943:            }
0944:
0945:            /**
0946:             * Creates Knuth elements for after border padding and adds them to the return list.
0947:             * @param returnList return list to add the additional elements to
0948:             * @param isLast true if this is the last time a layout manager instance needs to generate 
0949:             *               border and padding
0950:             */
0951:            protected void addKnuthElementsForBorderPaddingAfter(
0952:                    LinkedList returnList, boolean isLast) {
0953:                //Border and Padding (after)
0954:                CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
0955:                if (borderAndPadding != null) {
0956:                    if (borderAndPadding.getPaddingAfter(false, this ) > 0) {
0957:                        returnList
0958:                                .add(new PaddingElement(
0959:                                        getAuxiliaryPosition(),
0960:                                        borderAndPadding
0961:                                                .getPaddingLengthProperty(CommonBorderPaddingBackground.AFTER),
0962:                                        RelSide.AFTER, false, isLast, this ));
0963:                    }
0964:                    if (borderAndPadding.getBorderAfterWidth(false) > 0) {
0965:                        returnList.add(new BorderElement(
0966:                                getAuxiliaryPosition(),
0967:                                borderAndPadding.getBorderInfo(
0968:                                        CommonBorderPaddingBackground.AFTER)
0969:                                        .getWidth(), RelSide.AFTER, false,
0970:                                isLast, this ));
0971:                    }
0972:                }
0973:            }
0974:
0975:            /**
0976:             * Creates Knuth elements for break-before and adds them to the return list.
0977:             * @param returnList return list to add the additional elements to
0978:             * @param context the layout context
0979:             * @return true if an element has been added due to a break-before.
0980:             */
0981:            protected boolean addKnuthElementsForBreakBefore(
0982:                    LinkedList returnList, LayoutContext context) {
0983:                int breakBefore = -1;
0984:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
0985:                    breakBefore = ((org.apache.fop.fo.flow.Block) fobj)
0986:                            .getBreakBefore();
0987:                } else if (fobj instanceof  org.apache.fop.fo.flow.BlockContainer) {
0988:                    breakBefore = ((org.apache.fop.fo.flow.BlockContainer) fobj)
0989:                            .getBreakBefore();
0990:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListBlock) {
0991:                    breakBefore = ((org.apache.fop.fo.flow.ListBlock) fobj)
0992:                            .getBreakBefore();
0993:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListItem) {
0994:                    breakBefore = ((org.apache.fop.fo.flow.ListItem) fobj)
0995:                            .getBreakBefore();
0996:                } else if (fobj instanceof  org.apache.fop.fo.flow.Table) {
0997:                    breakBefore = ((org.apache.fop.fo.flow.Table) fobj)
0998:                            .getBreakBefore();
0999:                }
1000:                if (breakBefore == EN_PAGE || breakBefore == EN_COLUMN
1001:                        || breakBefore == EN_EVEN_PAGE
1002:                        || breakBefore == EN_ODD_PAGE) {
1003:                    // return a penalty element, representing a forced page break
1004:                    returnList.add(new BreakElement(getAuxiliaryPosition(), 0,
1005:                            -KnuthElement.INFINITE, breakBefore, context));
1006:                    return true;
1007:                } else {
1008:                    return false;
1009:                }
1010:            }
1011:
1012:            /**
1013:             * Creates Knuth elements for break-after and adds them to the return list.
1014:             * @param returnList return list to add the additional elements to
1015:             * @param context the layout context
1016:             * @return true if an element has been added due to a break-after.
1017:             */
1018:            protected boolean addKnuthElementsForBreakAfter(
1019:                    LinkedList returnList, LayoutContext context) {
1020:                int breakAfter = -1;
1021:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
1022:                    breakAfter = ((org.apache.fop.fo.flow.Block) fobj)
1023:                            .getBreakAfter();
1024:                } else if (fobj instanceof  org.apache.fop.fo.flow.BlockContainer) {
1025:                    breakAfter = ((org.apache.fop.fo.flow.BlockContainer) fobj)
1026:                            .getBreakAfter();
1027:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListBlock) {
1028:                    breakAfter = ((org.apache.fop.fo.flow.ListBlock) fobj)
1029:                            .getBreakAfter();
1030:                } else if (fobj instanceof  org.apache.fop.fo.flow.ListItem) {
1031:                    breakAfter = ((org.apache.fop.fo.flow.ListItem) fobj)
1032:                            .getBreakAfter();
1033:                } else if (fobj instanceof  org.apache.fop.fo.flow.Table) {
1034:                    breakAfter = ((org.apache.fop.fo.flow.Table) fobj)
1035:                            .getBreakAfter();
1036:                }
1037:                if (breakAfter == EN_PAGE || breakAfter == EN_COLUMN
1038:                        || breakAfter == EN_EVEN_PAGE
1039:                        || breakAfter == EN_ODD_PAGE) {
1040:                    // add a penalty element, representing a forced page break
1041:                    returnList.add(new BreakElement(getAuxiliaryPosition(), 0,
1042:                            -KnuthElement.INFINITE, breakAfter, context));
1043:                    return true;
1044:                } else {
1045:                    return false;
1046:                }
1047:            }
1048:
1049:            /**
1050:             * Creates Knuth elements for space-before and adds them to the return list.
1051:             * @param returnList return list to add the additional elements to
1052:             * @param alignment vertical alignment
1053:             */
1054:            protected void addKnuthElementsForSpaceBefore(LinkedList returnList/*, 
1055:                        Position returnPosition*/, int alignment) {
1056:                SpaceProperty spaceBefore = getSpaceBeforeProperty();
1057:                // append elements representing space-before
1058:                if (spaceBefore != null
1059:                        && !(spaceBefore.getMinimum(this ).getLength().getValue(
1060:                                this ) == 0 && spaceBefore.getMaximum(this )
1061:                                .getLength().getValue(this ) == 0)) {
1062:                    returnList.add(new SpaceElement(getAuxiliaryPosition(),
1063:                            spaceBefore, RelSide.BEFORE, true, false, this ));
1064:                }
1065:                /*
1066:                if (bpUnit > 0
1067:                        || spaceBefore != null
1068:                           && !(spaceBefore.getMinimum(this).getLength().getValue(this) == 0 
1069:                                && spaceBefore.getMaximum(this).getLength().getValue(this) == 0)) {
1070:                    if (spaceBefore != null && !spaceBefore.getSpace().isDiscard()) {
1071:                        // add elements to prevent the glue to be discarded
1072:                        returnList.add(new KnuthBox(0, getAuxiliaryPosition(), false));
1073:                        returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
1074:                                false, getAuxiliaryPosition(), false));
1075:                    }
1076:                    if (bpUnit > 0) {
1077:                        returnList.add(new KnuthGlue(0, 0, 0,
1078:                                BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, 
1079:                                getAuxiliaryPosition(), true));
1080:                    } else { //if (alignment == EN_JUSTIFY) {
1081:                        returnList.add(new KnuthGlue(
1082:                                spaceBefore.getOptimum(this).getLength().getValue(this),
1083:                                spaceBefore.getMaximum(this).getLength().getValue(this)
1084:                                        - spaceBefore.getOptimum(this).getLength().getValue(this),
1085:                                spaceBefore.getOptimum(this).getLength().getValue(this)
1086:                                        - spaceBefore.getMinimum(this).getLength().getValue(this),
1087:                                BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, 
1088:                                getAuxiliaryPosition(), true));
1089:                //            } else {
1090:                //                returnList.add(new KnuthGlue(
1091:                //                        spaceBefore.getOptimum().getLength().getValue(this), 
1092:                //                        0, 0, BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT,
1093:                //                        returnPosition, true));
1094:                    }
1095:                }*/
1096:            }
1097:
1098:            /**
1099:             * Creates Knuth elements for space-after and adds them to the return list.
1100:             * @param returnList return list to add the additional elements to
1101:             * @param alignment vertical alignment
1102:             */
1103:            protected void addKnuthElementsForSpaceAfter(
1104:                    LinkedList returnList/*, Position returnPosition*/,
1105:                    int alignment) {
1106:                SpaceProperty spaceAfter = getSpaceAfterProperty();
1107:                // append elements representing space-after
1108:                if (spaceAfter != null
1109:                        && !(spaceAfter.getMinimum(this ).getLength().getValue(
1110:                                this ) == 0 && spaceAfter.getMaximum(this )
1111:                                .getLength().getValue(this ) == 0)) {
1112:                    returnList.add(new SpaceElement(getAuxiliaryPosition(),
1113:                            spaceAfter, RelSide.AFTER, false, true, this ));
1114:                }
1115:                /*
1116:                if (bpUnit > 0
1117:                        || spaceAfter != null
1118:                           && !(spaceAfter.getMinimum(this).getLength().getValue(this) == 0 
1119:                                && spaceAfter.getMaximum(this).getLength().getValue(this) == 0)) {
1120:                    if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
1121:                        returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
1122:                                false, getAuxiliaryPosition(), false));
1123:                    }
1124:                    if (bpUnit > 0) {
1125:                        returnList.add(new KnuthGlue(0, 0, 0, 
1126:                                BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT,
1127:                                getAuxiliaryPosition(), true));
1128:                    } else { //if (alignment == EN_JUSTIFY) {
1129:                        returnList.add(new KnuthGlue(
1130:                                spaceAfter.getOptimum(this).getLength().getValue(this),
1131:                                spaceAfter.getMaximum(this).getLength().getValue(this)
1132:                                        - spaceAfter.getOptimum(this).getLength().getValue(this),
1133:                                spaceAfter.getOptimum(this).getLength().getValue(this)
1134:                                        - spaceAfter.getMinimum(this).getLength().getValue(this),
1135:                                BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, getAuxiliaryPosition(),
1136:                                (!spaceAfter.getSpace().isDiscard()) ? false : true));
1137:                //            } else {
1138:                //                returnList.add(new KnuthGlue(
1139:                //                        spaceAfter.getOptimum().getLength().getValue(this), 0, 0,
1140:                //                        BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, returnPosition,
1141:                //                        (!spaceAfter.getSpace().isDiscard()) ? false : true));
1142:                    }
1143:                    if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
1144:                        returnList.add(new KnuthBox(0, getAuxiliaryPosition(), true));
1145:                    }
1146:                }*/
1147:            }
1148:
1149:            protected LinkedList createUnitElements(LinkedList oldList) {
1150:                //log.debug("Start conversion: " + oldList.size() 
1151:                //  + " elements, space-before.min=" + layoutProps.spaceBefore.getSpace().min
1152:                //  + " space-after.min=" + layoutProps.spaceAfter.getSpace().min);
1153:                // add elements at the beginning and at the end of oldList
1154:                // representing minimum spaces
1155:                LayoutManager lm = ((KnuthElement) oldList.getFirst())
1156:                        .getLayoutManager();
1157:                boolean bAddedBoxBefore = false;
1158:                boolean bAddedBoxAfter = false;
1159:                if (adjustedSpaceBefore > 0) {
1160:                    oldList.addFirst(new KnuthBox(adjustedSpaceBefore,
1161:                            new Position(lm), true));
1162:                    bAddedBoxBefore = true;
1163:                }
1164:                if (adjustedSpaceAfter > 0) {
1165:                    oldList.addLast(new KnuthBox(adjustedSpaceAfter,
1166:                            new Position(lm), true));
1167:                    bAddedBoxAfter = true;
1168:                }
1169:
1170:                MinOptMax totalLength = new MinOptMax(0);
1171:                MinOptMax totalUnits = new MinOptMax(0);
1172:                LinkedList newList = new LinkedList();
1173:
1174:                //log.debug(" Prima scansione");
1175:                // scan the list once to compute total min, opt and max length
1176:                ListIterator oldListIterator = oldList.listIterator();
1177:                while (oldListIterator.hasNext()) {
1178:                    KnuthElement element = (KnuthElement) oldListIterator
1179:                            .next();
1180:                    if (element.isBox()) {
1181:                        totalLength.add(new MinOptMax(element.getW()));
1182:                        //log.debug("box " + element.getW());               
1183:                    } else if (element.isGlue()) {
1184:                        totalLength.min -= ((KnuthGlue) element).getZ();
1185:                        totalLength.max += ((KnuthGlue) element).getY();
1186:                        //leafValue = ((LeafPosition) element.getPosition()).getLeafPos();
1187:                        //log.debug("glue " + element.getW() + " + " 
1188:                        //    + ((KnuthGlue) element).getY() + " - " + ((KnuthGlue) element).getZ());
1189:                    } else {
1190:                        //log.debug((((KnuthPenalty)element).getP() == KnuthElement.INFINITE 
1191:                        //    ? "PENALTY " : "penalty ") + element.getW());
1192:                    }
1193:                }
1194:                // compute the total amount of "units"
1195:                totalUnits = new MinOptMax(neededUnits(totalLength.min),
1196:                        neededUnits(totalLength.opt),
1197:                        neededUnits(totalLength.max));
1198:                //log.debug(" totalLength= " + totalLength);
1199:                //log.debug(" unita'= " + totalUnits);
1200:
1201:                //log.debug(" Seconda scansione");
1202:                // scan the list once more, stopping at every breaking point
1203:                // in order to compute partial min, opt and max length
1204:                // and create the new elements
1205:                oldListIterator = oldList.listIterator();
1206:                boolean bPrevIsBox = false;
1207:                MinOptMax lengthBeforeBreak = new MinOptMax(0);
1208:                MinOptMax lengthAfterBreak = (MinOptMax) totalLength.clone();
1209:                MinOptMax unitsBeforeBreak;
1210:                MinOptMax unitsAfterBreak;
1211:                MinOptMax unsuppressibleUnits = new MinOptMax(0);
1212:                int firstIndex = 0;
1213:                int lastIndex = -1;
1214:                while (oldListIterator.hasNext()) {
1215:                    KnuthElement element = (KnuthElement) oldListIterator
1216:                            .next();
1217:                    lastIndex++;
1218:                    if (element.isBox()) {
1219:                        lengthBeforeBreak.add(new MinOptMax(element.getW()));
1220:                        lengthAfterBreak
1221:                                .subtract(new MinOptMax(element.getW()));
1222:                        bPrevIsBox = true;
1223:                    } else if (element.isGlue()) {
1224:                        lengthBeforeBreak.min -= ((KnuthGlue) element).getZ();
1225:                        lengthAfterBreak.min += ((KnuthGlue) element).getZ();
1226:                        lengthBeforeBreak.max += ((KnuthGlue) element).getY();
1227:                        lengthAfterBreak.max -= ((KnuthGlue) element).getY();
1228:                        bPrevIsBox = false;
1229:                    } else {
1230:                        lengthBeforeBreak.add(new MinOptMax(element.getW()));
1231:                        bPrevIsBox = false;
1232:                    }
1233:
1234:                    // create the new elements
1235:                    if (element.isPenalty()
1236:                            && ((KnuthPenalty) element).getP() < KnuthElement.INFINITE
1237:                            || element.isGlue() && bPrevIsBox
1238:                            || !oldListIterator.hasNext()) {
1239:                        // suppress elements after the breaking point
1240:                        int iStepsForward = 0;
1241:                        while (oldListIterator.hasNext()) {
1242:                            KnuthElement el = (KnuthElement) oldListIterator
1243:                                    .next();
1244:                            iStepsForward++;
1245:                            if (el.isGlue()) {
1246:                                // suppressed glue
1247:                                lengthAfterBreak.min += ((KnuthGlue) el).getZ();
1248:                                lengthAfterBreak.max -= ((KnuthGlue) el).getY();
1249:                            } else if (el.isPenalty()) {
1250:                                // suppressed penalty, do nothing
1251:                            } else {
1252:                                // box, end of suppressions
1253:                                break;
1254:                            }
1255:                        }
1256:                        // compute the partial amount of "units" before and after the break
1257:                        unitsBeforeBreak = new MinOptMax(
1258:                                neededUnits(lengthBeforeBreak.min),
1259:                                neededUnits(lengthBeforeBreak.opt),
1260:                                neededUnits(lengthBeforeBreak.max));
1261:                        unitsAfterBreak = new MinOptMax(
1262:                                neededUnits(lengthAfterBreak.min),
1263:                                neededUnits(lengthAfterBreak.opt),
1264:                                neededUnits(lengthAfterBreak.max));
1265:
1266:                        // rewind the iterator and lengthAfterBreak
1267:                        for (int i = 0; i < iStepsForward; i++) {
1268:                            KnuthElement el = (KnuthElement) oldListIterator
1269:                                    .previous();
1270:                            if (el.isGlue()) {
1271:                                lengthAfterBreak.min -= ((KnuthGlue) el).getZ();
1272:                                lengthAfterBreak.max += ((KnuthGlue) el).getY();
1273:                            }
1274:                        }
1275:
1276:                        // compute changes in length, stretch and shrink
1277:                        int uLengthChange = unitsBeforeBreak.opt
1278:                                + unitsAfterBreak.opt - totalUnits.opt;
1279:                        int uStretchChange = (unitsBeforeBreak.max
1280:                                + unitsAfterBreak.max - totalUnits.max)
1281:                                - (unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt);
1282:                        int uShrinkChange = (unitsBeforeBreak.opt
1283:                                + unitsAfterBreak.opt - totalUnits.opt)
1284:                                - (unitsBeforeBreak.min + unitsAfterBreak.min - totalUnits.min);
1285:
1286:                        // compute the number of normal, stretch and shrink unit
1287:                        // that must be added to the new sequence
1288:                        int uNewNormal = unitsBeforeBreak.opt
1289:                                - unsuppressibleUnits.opt;
1290:                        int uNewStretch = (unitsBeforeBreak.max - unitsBeforeBreak.opt)
1291:                                - (unsuppressibleUnits.max - unsuppressibleUnits.opt);
1292:                        int uNewShrink = (unitsBeforeBreak.opt - unitsBeforeBreak.min)
1293:                                - (unsuppressibleUnits.opt - unsuppressibleUnits.min);
1294:
1295:                        //log.debug("(" 
1296:                        //    + unsuppressibleUnits.min + "-" + unsuppressibleUnits.opt + "-" 
1297:                        //         + unsuppressibleUnits.max + ") "
1298:                        //    + " -> " + unitsBeforeBreak.min + "-" + unitsBeforeBreak.opt + "-" 
1299:                        //         + unitsBeforeBreak.max
1300:                        //    + " + " + unitsAfterBreak.min + "-" + unitsAfterBreak.opt + "-" 
1301:                        //         + unitsAfterBreak.max
1302:                        //    + (uLengthChange != 0 ? " [length " + uLengthChange + "] " : "")
1303:                        //    + (uStretchChange != 0 ? " [stretch " + uStretchChange + "] " : "")
1304:                        //    + (uShrinkChange != 0 ? " [shrink " + uShrinkChange + "]" : ""));
1305:
1306:                        // create the MappingPosition which will be stored in the new elements
1307:                        // correct firstIndex and lastIndex
1308:                        int firstIndexCorrection = 0;
1309:                        int lastIndexCorrection = 0;
1310:                        if (bAddedBoxBefore) {
1311:                            if (firstIndex != 0) {
1312:                                firstIndexCorrection++;
1313:                            }
1314:                            lastIndexCorrection++;
1315:                        }
1316:                        if (bAddedBoxAfter && lastIndex == (oldList.size() - 1)) {
1317:                            lastIndexCorrection++;
1318:                        }
1319:                        MappingPosition mappingPos = new MappingPosition(this ,
1320:                                firstIndex - firstIndexCorrection, lastIndex
1321:                                        - lastIndexCorrection);
1322:
1323:                        // new box
1324:                        newList.add(new KnuthBox((uNewNormal - uLengthChange)
1325:                                * bpUnit, mappingPos, false));
1326:                        unsuppressibleUnits.add(new MinOptMax(uNewNormal
1327:                                - uLengthChange));
1328:                        //log.debug("        box " + (uNewNormal - uLengthChange));
1329:
1330:                        // new infinite penalty, glue and box, if necessary
1331:                        if (uNewStretch - uStretchChange > 0
1332:                                || uNewShrink - uShrinkChange > 0) {
1333:                            int iStretchUnits = (uNewStretch - uStretchChange > 0 ? (uNewStretch - uStretchChange)
1334:                                    : 0);
1335:                            int iShrinkUnits = (uNewShrink - uShrinkChange > 0 ? (uNewShrink - uShrinkChange)
1336:                                    : 0);
1337:                            newList.add(new KnuthPenalty(0,
1338:                                    KnuthElement.INFINITE, false, mappingPos,
1339:                                    false));
1340:                            newList.add(new KnuthGlue(0,
1341:                                    iStretchUnits * bpUnit, iShrinkUnits
1342:                                            * bpUnit, LINE_NUMBER_ADJUSTMENT,
1343:                                    mappingPos, false));
1344:                            //log.debug("        PENALTY");
1345:                            //log.debug("        glue 0 " + iStretchUnits + " " + iShrinkUnits);
1346:                            unsuppressibleUnits.max += iStretchUnits;
1347:                            unsuppressibleUnits.min -= iShrinkUnits;
1348:                            if (!oldListIterator.hasNext()) {
1349:                                newList.add(new KnuthBox(0, mappingPos, false));
1350:                                //log.debug("        box 0");
1351:                            }
1352:                        }
1353:
1354:                        // new breaking sequence
1355:                        if (uStretchChange != 0 || uShrinkChange != 0) {
1356:                            // new infinite penalty, glue, penalty and glue
1357:                            newList.add(new KnuthPenalty(0,
1358:                                    KnuthElement.INFINITE, false, mappingPos,
1359:                                    false));
1360:                            newList.add(new KnuthGlue(0, uStretchChange
1361:                                    * bpUnit, uShrinkChange * bpUnit,
1362:                                    LINE_NUMBER_ADJUSTMENT, mappingPos, false));
1363:                            newList.add(new KnuthPenalty(
1364:                                    uLengthChange * bpUnit, 0, false, element
1365:                                            .getPosition(), false));
1366:                            newList.add(new KnuthGlue(0, -uStretchChange
1367:                                    * bpUnit, -uShrinkChange * bpUnit,
1368:                                    LINE_NUMBER_ADJUSTMENT, mappingPos, false));
1369:                            //log.debug("        PENALTY");
1370:                            //log.debug("        glue 0 " + uStretchChange + " " + uShrinkChange);
1371:                            //log.debug("        penalty " + uLengthChange + " * unit");
1372:                            //log.debug("        glue 0 " + (- uStretchChange) + " " 
1373:                            //      + (- uShrinkChange));
1374:                        } else if (oldListIterator.hasNext()) {
1375:                            // new penalty
1376:                            newList.add(new KnuthPenalty(
1377:                                    uLengthChange * bpUnit, 0, false,
1378:                                    mappingPos, false));
1379:                            //log.debug("        penalty " + uLengthChange + " * unit");
1380:                        }
1381:                        // update firstIndex
1382:                        firstIndex = lastIndex + 1;
1383:                    }
1384:
1385:                    if (element.isPenalty()) {
1386:                        lengthBeforeBreak.add(new MinOptMax(-element.getW()));
1387:                    }
1388:
1389:                }
1390:
1391:                // remove elements at the beginning and at the end of oldList
1392:                // representing minimum spaces
1393:                if (adjustedSpaceBefore > 0) {
1394:                    oldList.removeFirst();
1395:                }
1396:                if (adjustedSpaceAfter > 0) {
1397:                    oldList.removeLast();
1398:                }
1399:
1400:                // if space-before.conditionality is "discard", correct newList
1401:                boolean correctFirstElement = false;
1402:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
1403:                    correctFirstElement = ((org.apache.fop.fo.flow.Block) fobj)
1404:                            .getCommonMarginBlock().spaceBefore.getSpace()
1405:                            .isDiscard();
1406:                }
1407:                if (correctFirstElement) {
1408:                    // remove the wrong element
1409:                    KnuthBox wrongBox = (KnuthBox) newList.removeFirst();
1410:                    // if this paragraph is at the top of a page, the space before
1411:                    // must be ignored; compute the length change
1412:                    int decreasedLength = (neededUnits(totalLength.opt) - neededUnits(totalLength.opt
1413:                            - adjustedSpaceBefore))
1414:                            * bpUnit;
1415:                    // insert the correct elements
1416:                    newList.addFirst(new KnuthBox(wrongBox.getW()
1417:                            - decreasedLength, wrongBox.getPosition(), false));
1418:                    newList.addFirst(new KnuthGlue(decreasedLength, 0, 0,
1419:                            SPACE_BEFORE_ADJUSTMENT, wrongBox.getPosition(),
1420:                            false));
1421:                    //log.debug("        rimosso box " + neededUnits(wrongBox.getW()));
1422:                    //log.debug("        aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
1423:                    //log.debug("        aggiunto box " + neededUnits(
1424:                    //       wrongBox.getW() - decreasedLength));
1425:                }
1426:
1427:                // if space-after.conditionality is "discard", correct newList
1428:                boolean correctLastElement = false;
1429:                if (fobj instanceof  org.apache.fop.fo.flow.Block) {
1430:                    correctLastElement = ((org.apache.fop.fo.flow.Block) fobj)
1431:                            .getCommonMarginBlock().spaceAfter.getSpace()
1432:                            .isDiscard();
1433:                }
1434:                if (correctLastElement) {
1435:                    // remove the wrong element
1436:                    KnuthBox wrongBox = (KnuthBox) newList.removeLast();
1437:                    // if the old sequence is box(h) penalty(inf) glue(x,y,z) box(0)
1438:                    // (it cannot be parted and has some stretch or shrink)
1439:                    // the wrong box is the first one, not the last one
1440:                    LinkedList preserveList = new LinkedList();
1441:                    if (wrongBox.getW() == 0) {
1442:                        preserveList.add(wrongBox);
1443:                        preserveList.addFirst((KnuthGlue) newList.removeLast());
1444:                        preserveList.addFirst((KnuthPenalty) newList
1445:                                .removeLast());
1446:                        wrongBox = (KnuthBox) newList.removeLast();
1447:                    }
1448:
1449:                    // if this paragraph is at the bottom of a page, the space after
1450:                    // must be ignored; compute the length change
1451:                    int decreasedLength = (neededUnits(totalLength.opt) - neededUnits(totalLength.opt
1452:                            - adjustedSpaceAfter))
1453:                            * bpUnit;
1454:                    // insert the correct box
1455:                    newList.addLast(new KnuthBox(wrongBox.getW()
1456:                            - decreasedLength, wrongBox.getPosition(), false));
1457:                    // add preserved elements
1458:                    if (preserveList.size() > 0) {
1459:                        newList.addAll(preserveList);
1460:                    }
1461:                    // insert the correct glue
1462:                    newList.addLast(new KnuthGlue(decreasedLength, 0, 0,
1463:                            SPACE_AFTER_ADJUSTMENT, wrongBox.getPosition(),
1464:                            false));
1465:                    //log.debug("        rimosso box " + neededUnits(wrongBox.getW()));
1466:                    //log.debug("        aggiunto box " + neededUnits(
1467:                    //      wrongBox.getW() - decreasedLength));
1468:                    //log.debug("        aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
1469:                }
1470:
1471:                return newList;
1472:            }
1473:
1474:            protected static class StackingIter extends PositionIterator {
1475:                StackingIter(Iterator parentIter) {
1476:                    super (parentIter);
1477:                }
1478:
1479:                protected LayoutManager getLM(Object nextObj) {
1480:                    return ((Position) nextObj).getLM();
1481:                }
1482:
1483:                protected Position getPos(Object nextObj) {
1484:                    return ((Position) nextObj);
1485:                }
1486:            }
1487:
1488:            protected static class MappingPosition extends Position {
1489:                private int iFirstIndex;
1490:                private int iLastIndex;
1491:
1492:                public MappingPosition(LayoutManager lm, int first, int last) {
1493:                    super (lm);
1494:                    iFirstIndex = first;
1495:                    iLastIndex = last;
1496:                }
1497:
1498:                public int getFirstIndex() {
1499:                    return iFirstIndex;
1500:                }
1501:
1502:                public int getLastIndex() {
1503:                    return iLastIndex;
1504:                }
1505:            }
1506:
1507:            /**
1508:             * "wrap" the Position inside each element moving the elements from 
1509:             * SourceList to targetList
1510:             * @param sourceList source list
1511:             * @param targetList target list receiving the wrapped position elements
1512:             */
1513:            protected void wrapPositionElements(List sourceList, List targetList) {
1514:                wrapPositionElements(sourceList, targetList, false);
1515:            }
1516:
1517:            /**
1518:             * "wrap" the Position inside each element moving the elements from 
1519:             * SourceList to targetList
1520:             * @param sourceList source list
1521:             * @param targetList target list receiving the wrapped position elements
1522:             * @param force if true, every Position is wrapped regardless of its LM of origin
1523:             */
1524:            protected void wrapPositionElements(List sourceList,
1525:                    List targetList, boolean force) {
1526:
1527:                ListIterator listIter = sourceList.listIterator();
1528:                while (listIter.hasNext()) {
1529:                    ListElement tempElement;
1530:                    tempElement = (ListElement) listIter.next();
1531:                    if (force || tempElement.getLayoutManager() != this ) {
1532:                        tempElement.setPosition(notifyPos(new NonLeafPosition(
1533:                                this , tempElement.getPosition())));
1534:                    }
1535:                    targetList.add(tempElement);
1536:                }
1537:            }
1538:
1539:            /** @return the sum of start-indent and end-indent */
1540:            protected int getIPIndents() {
1541:                return startIndent + endIndent;
1542:            }
1543:
1544:            /**
1545:             * Returns the IPD of the content area
1546:             * @return the IPD of the content area
1547:             */
1548:            public int getContentAreaIPD() {
1549:                return contentAreaIPD;
1550:            }
1551:
1552:            /**
1553:             * Sets the IPD of the content area
1554:             * @param contentAreaIPD the IPD of the content area
1555:             */
1556:            protected void setContentAreaIPD(int contentAreaIPD) {
1557:                this .contentAreaIPD = contentAreaIPD;
1558:            }
1559:
1560:            /**
1561:             * Returns the BPD of the content area
1562:             * @return the BPD of the content area
1563:             */
1564:            public int getContentAreaBPD() {
1565:                return -1;
1566:            }
1567:
1568:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.