KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > layoutmgr > list > ListItemLayoutManager


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: ListItemLayoutManager.java 454338 2006-10-09 10:57:55Z spepping $ */
19
20 package org.apache.fop.layoutmgr.list;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.fop.fo.flow.ListItem;
25 import org.apache.fop.fo.flow.ListItemBody;
26 import org.apache.fop.fo.flow.ListItemLabel;
27 import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
28 import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
29 import org.apache.fop.layoutmgr.BreakElement;
30 import org.apache.fop.layoutmgr.ConditionalElementListener;
31 import org.apache.fop.layoutmgr.ElementListObserver;
32 import org.apache.fop.layoutmgr.ElementListUtils;
33 import org.apache.fop.layoutmgr.LayoutManager;
34 import org.apache.fop.layoutmgr.LayoutContext;
35 import org.apache.fop.layoutmgr.PositionIterator;
36 import org.apache.fop.layoutmgr.Position;
37 import org.apache.fop.layoutmgr.NonLeafPosition;
38 import org.apache.fop.layoutmgr.RelSide;
39 import org.apache.fop.layoutmgr.SpaceResolver;
40 import org.apache.fop.layoutmgr.TraitSetter;
41 import org.apache.fop.layoutmgr.KnuthElement;
42 import org.apache.fop.layoutmgr.KnuthBox;
43 import org.apache.fop.layoutmgr.KnuthPenalty;
44 import org.apache.fop.layoutmgr.KnuthPossPosIter;
45 import org.apache.fop.area.Area;
46 import org.apache.fop.area.Block;
47 import org.apache.fop.traits.MinOptMax;
48 import org.apache.fop.traits.SpaceVal;
49
50 import java.util.ArrayList JavaDoc;
51 import java.util.List JavaDoc;
52 import java.util.LinkedList JavaDoc;
53 import java.util.ListIterator JavaDoc;
54
55 /**
56  * LayoutManager for a list-item FO.
57  * The list item contains a list item label and a list item body.
58  */

59 public class ListItemLayoutManager extends BlockStackingLayoutManager
60                     implements ConditionalElementListener {
61
62     /**
63      * logging instance
64      */

65     private static Log log = LogFactory.getLog(ListItemLayoutManager.class);
66
67     private ListItemContentLayoutManager label;
68     private ListItemContentLayoutManager body;
69
70     private Block curBlockArea = null;
71
72     private LinkedList JavaDoc labelList = null;
73     private LinkedList JavaDoc bodyList = null;
74
75     private int listItemHeight;
76     
77     private boolean discardBorderBefore;
78     private boolean discardBorderAfter;
79     private boolean discardPaddingBefore;
80     private boolean discardPaddingAfter;
81     private MinOptMax effSpaceBefore;
82     private MinOptMax effSpaceAfter;
83     
84     private boolean keepWithNextPendingOnLabel;
85     private boolean keepWithNextPendingOnBody;
86   
87     private class ListItemPosition extends Position {
88         private int iLabelFirstIndex;
89         private int iLabelLastIndex;
90         private int iBodyFirstIndex;
91         private int iBodyLastIndex;
92
93         public ListItemPosition(LayoutManager lm, int labelFirst, int labelLast,
94                 int bodyFirst, int bodyLast) {
95             super(lm);
96             iLabelFirstIndex = labelFirst;
97             iLabelLastIndex = labelLast;
98             iBodyFirstIndex = bodyFirst;
99             iBodyLastIndex = bodyLast;
100         }
101         
102         public int getLabelFirstIndex() {
103             return iLabelFirstIndex;
104         }
105         
106         public int getLabelLastIndex() {
107             return iLabelLastIndex;
108         }
109
110         public int getBodyFirstIndex() {
111             return iBodyFirstIndex;
112         }
113         
114         public int getBodyLastIndex() {
115             return iBodyLastIndex;
116         }
117         
118         /** @see java.lang.Object#toString() */
119         public String JavaDoc toString() {
120             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("ListItemPosition:");
121             sb.append(getIndex()).append("(");
122             sb.append("label:").append(iLabelFirstIndex).append("-").append(iLabelLastIndex);
123             sb.append(" body:").append(iBodyFirstIndex).append("-").append(iBodyLastIndex);
124             sb.append(")");
125             return sb.toString();
126         }
127     }
128
129     /**
130      * Create a new list item layout manager.
131      * @param node list-item to create the layout manager for
132      */

133     public ListItemLayoutManager(ListItem node) {
134         super(node);
135         setLabel(node.getLabel());
136         setBody(node.getBody());
137     }
138
139     /**
140      * Convenience method.
141      * @return the ListBlock node
142      */

143     protected ListItem getListItemFO() {
144         return (ListItem)fobj;
145     }
146
147     /**
148      * Create a LM for the fo:list-item-label object
149      * @param node the fo:list-item-label FO
150      */

151     public void setLabel(ListItemLabel node) {
152         label = new ListItemContentLayoutManager(node);
153         label.setParent(this);
154     }
155
156     /**
157      * Create a LM for the fo:list-item-body object
158      * @param node the fo:list-item-body FO
159      */

160     public void setBody(ListItemBody node) {
161         body = new ListItemContentLayoutManager(node);
162         body.setParent(this);
163     }
164
165     /** @see org.apache.fop.layoutmgr.LayoutManager#initialize() */
166     public void initialize() {
167         foSpaceBefore = new SpaceVal(
168                 getListItemFO().getCommonMarginBlock().spaceBefore, this).getSpace();
169         foSpaceAfter = new SpaceVal(
170                 getListItemFO().getCommonMarginBlock().spaceAfter, this).getSpace();
171         startIndent = getListItemFO().getCommonMarginBlock().startIndent.getValue(this);
172         endIndent = getListItemFO().getCommonMarginBlock().endIndent.getValue(this);
173     }
174
175     private void resetSpaces() {
176         this.discardBorderBefore = false;
177         this.discardBorderAfter = false;
178         this.discardPaddingBefore = false;
179         this.discardPaddingAfter = false;
180         this.effSpaceBefore = null;
181         this.effSpaceAfter = null;
182     }
183     
184     /** @see org.apache.fop.layoutmgr.LayoutManager */
185     public LinkedList JavaDoc getNextKnuthElements(LayoutContext context, int alignment) {
186         referenceIPD = context.getRefIPD();
187         LayoutContext childLC;
188         
189         LinkedList JavaDoc returnList = new LinkedList JavaDoc();
190         
191         if (!breakBeforeServed) {
192             try {
193                 if (addKnuthElementsForBreakBefore(returnList, context)) {
194                     return returnList;
195                 }
196             } finally {
197                 breakBeforeServed = true;
198             }
199         }
200
201         addKnuthElementsForSpaceBefore(returnList, alignment);
202         
203         addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
204         firstVisibleMarkServed = true;
205
206         //Spaces, border and padding to be repeated at each break
207
addPendingMarks(context);
208
209         // label
210
childLC = new LayoutContext(0);
211         childLC.setRefIPD(context.getRefIPD());
212         label.initialize();
213         labelList = label.getNextKnuthElements(childLC, alignment);
214         
215         //Space resolution as if the contents were placed in a new reference area
216
//(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
217
SpaceResolver.resolveElementList(labelList);
218         ElementListObserver.observe(labelList, "list-item-label", label.getPartFO().getId());
219         
220         if (childLC.isKeepWithPreviousPending()) {
221             context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
222         }
223         this.keepWithNextPendingOnLabel = childLC.isKeepWithNextPending();
224
225         // body
226
childLC = new LayoutContext(0);
227         childLC.setRefIPD(context.getRefIPD());
228         body.initialize();
229         bodyList = body.getNextKnuthElements(childLC, alignment);
230
231         //Space resolution as if the contents were placed in a new reference area
232
//(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
233
SpaceResolver.resolveElementList(bodyList);
234         ElementListObserver.observe(bodyList, "list-item-body", body.getPartFO().getId());
235         
236         if (childLC.isKeepWithPreviousPending()) {
237             context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
238         }
239         this.keepWithNextPendingOnBody = childLC.isKeepWithNextPending();
240
241         // create a combined list
242
LinkedList JavaDoc returnedList = getCombinedKnuthElementsForListItem(labelList, bodyList, context);
243
244         // "wrap" the Position inside each element
245
wrapPositionElements(returnedList, returnList, true);
246         
247         addKnuthElementsForBorderPaddingAfter(returnList, true);
248         addKnuthElementsForSpaceAfter(returnList, alignment);
249         addKnuthElementsForBreakAfter(returnList, context);
250
251         if (keepWithNextPendingOnLabel || keepWithNextPendingOnBody || mustKeepWithNext()) {
252             context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
253         }
254         if (mustKeepWithPrevious()) {
255             context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
256         }
257
258         setFinished(true);
259         resetSpaces();
260         return returnList;
261     }
262
263     private LinkedList JavaDoc getCombinedKnuthElementsForListItem(LinkedList JavaDoc labelElements,
264                                                            LinkedList JavaDoc bodyElements,
265                                                            LayoutContext context) {
266         //Copy elements to array lists to improve element access performance
267
List JavaDoc[] elementLists = {new ArrayList JavaDoc(labelElements),
268                                new ArrayList JavaDoc(bodyElements)};
269         int[] fullHeights = {ElementListUtils.calcContentLength(elementLists[0]),
270                 ElementListUtils.calcContentLength(elementLists[1])};
271         int[] partialHeights = {0, 0};
272         int[] start = {-1, -1};
273         int[] end = {-1, -1};
274
275         int totalHeight = Math.max(fullHeights[0], fullHeights[1]);
276         int step;
277         int addedBoxHeight = 0;
278         boolean keepWithNextActive = false;
279
280         LinkedList JavaDoc returnList = new LinkedList JavaDoc();
281         while ((step = getNextStep(elementLists, start, end, partialHeights))
282                > 0) {
283             
284             if (end[0] + 1 == elementLists[0].size()) {
285                 if (keepWithNextPendingOnLabel) {
286                     keepWithNextActive = true;
287                 }
288             }
289             if (end[1] + 1 == elementLists[1].size()) {
290                 if (keepWithNextPendingOnBody) {
291                     keepWithNextActive = true;
292                 }
293             }
294             
295             // compute penalty height and box height
296
int penaltyHeight = step
297                 + getMaxRemainingHeight(fullHeights, partialHeights)
298                 - totalHeight;
299             
300             //Additional penalty height from penalties in the source lists
301
int additionalPenaltyHeight = 0;
302             KnuthElement endEl = (KnuthElement)elementLists[0].get(end[0]);
303             if (endEl instanceof KnuthPenalty) {
304                 additionalPenaltyHeight = ((KnuthPenalty)endEl).getW();
305             }
306             endEl = (KnuthElement)elementLists[1].get(end[1]);
307             if (endEl instanceof KnuthPenalty) {
308                 additionalPenaltyHeight = Math.max(
309                         additionalPenaltyHeight, ((KnuthPenalty)endEl).getW());
310             }
311             
312             int boxHeight = step - addedBoxHeight - penaltyHeight;
313             penaltyHeight += additionalPenaltyHeight; //Add AFTER calculating boxHeight!
314

315             // add the new elements
316
addedBoxHeight += boxHeight;
317             ListItemPosition stepPosition = new ListItemPosition(this,
318                     start[0], end[0], start[1], end[1]);
319             returnList.add(new KnuthBox(boxHeight, stepPosition, false));
320             if (addedBoxHeight < totalHeight) {
321                 int p = 0;
322                 if (keepWithNextActive || mustKeepTogether()) {
323                     p = KnuthPenalty.INFINITE;
324                 }
325                 returnList.add(new BreakElement(stepPosition, penaltyHeight, p, -1, context));
326             }
327         }
328
329         return returnList;
330     }
331
332     private int getNextStep(List JavaDoc[] elementLists, int[] start, int[] end, int[] partialHeights) {
333         // backup of partial heights
334
int[] backupHeights = {partialHeights[0], partialHeights[1]};
335
336         // set starting points
337
start[0] = end[0] + 1;
338         start[1] = end[1] + 1;
339
340         // get next possible sequence for label and body
341
int seqCount = 0;
342         for (int i = 0; i < start.length; i++) {
343             while (end[i] + 1 < elementLists[i].size()) {
344                 end[i]++;
345                 KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
346                 if (el.isPenalty()) {
347                     if (el.getP() < KnuthElement.INFINITE) {
348                         //First legal break point
349
break;
350                     }
351                 } else if (el.isGlue()) {
352                     if (end[i] > 0) {
353                         KnuthElement prev = (KnuthElement)elementLists[i].get(end[i] - 1);
354                         if (prev.isBox()) {
355                             //Second legal break point
356
break;
357                         }
358                     }
359                     partialHeights[i] += el.getW();
360                 } else {
361                     partialHeights[i] += el.getW();
362                 }
363             }
364             if (end[i] < start[i]) {
365                 partialHeights[i] = backupHeights[i];
366             } else {
367                 seqCount++;
368             }
369         }
370         if (seqCount == 0) {
371             return 0;
372         }
373         
374         // determine next step
375
int step;
376         if (backupHeights[0] == 0 && backupHeights[1] == 0) {
377             // this is the first step: choose the maximum increase, so that
378
// the smallest area in the first page will contain at least
379
// a label area and a body area
380
step = Math.max((end[0] >= start[0] ? partialHeights[0] : Integer.MIN_VALUE),
381                             (end[1] >= start[1] ? partialHeights[1] : Integer.MIN_VALUE));
382         } else {
383             // this is not the first step: choose the minimum increase
384
step = Math.min((end[0] >= start[0] ? partialHeights[0] : Integer.MAX_VALUE),
385                             (end[1] >= start[1] ? partialHeights[1] : Integer.MAX_VALUE));
386         }
387
388         // reset bigger-than-step sequences
389
for (int i = 0; i < partialHeights.length; i++) {
390             if (partialHeights[i] > step) {
391                 partialHeights[i] = backupHeights[i];
392                 end[i] = start[i] - 1;
393             }
394         }
395
396         return step;
397     }
398
399     private int getMaxRemainingHeight(int[] fullHeights, int[] partialHeights) {
400         return Math.max(fullHeights[0] - partialHeights[0],
401                         fullHeights[1] - partialHeights[1]);
402     }
403
404     /**
405      * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int)
406      */

407     public LinkedList JavaDoc getChangedKnuthElements(List JavaDoc oldList, int alignment) {
408         //log.debug(" LILM.getChanged> label");
409
// label
410
labelList = label.getChangedKnuthElements(labelList, alignment);
411
412         //log.debug(" LILM.getChanged> body");
413
// body
414
// "unwrap" the Positions stored in the elements
415
ListIterator JavaDoc oldListIterator = oldList.listIterator();
416         KnuthElement oldElement = null;
417         while (oldListIterator.hasNext()) {
418             oldElement = (KnuthElement)oldListIterator.next();
419             Position innerPosition = ((NonLeafPosition) oldElement.getPosition()).getPosition();
420             //log.debug(" BLM> unwrapping: " + (oldElement.isBox()
421
// ? "box " : (oldElement.isGlue() ? "glue " : "penalty"))
422
// + " creato da " + oldElement.getLayoutManager().getClass().getName());
423
//log.debug(" BLM> unwrapping: "
424
// + oldElement.getPosition().getClass().getName());
425
if (innerPosition != null) {
426                 // oldElement was created by a descendant of this BlockLM
427
oldElement.setPosition(innerPosition);
428             } else {
429                 // thisElement was created by this BlockLM
430
// modify its position in order to recognize it was not created
431
// by a child
432
oldElement.setPosition(new Position(this));
433             }
434         }
435
436         LinkedList JavaDoc returnedList = body.getChangedKnuthElements(oldList, alignment);
437         // "wrap" the Position inside each element
438
LinkedList JavaDoc tempList = returnedList;
439         KnuthElement tempElement;
440         returnedList = new LinkedList JavaDoc();
441         ListIterator JavaDoc listIter = tempList.listIterator();
442         while (listIter.hasNext()) {
443             tempElement = (KnuthElement)listIter.next();
444             tempElement.setPosition(new NonLeafPosition(this, tempElement.getPosition()));
445             returnedList.add(tempElement);
446         }
447
448         return returnedList;
449     }
450
451     /**
452      * Add the areas for the break points.
453      * This sets the offset of each cell as it is added.
454      *
455      * @param parentIter the position iterator
456      * @param layoutContext the layout context for adding areas
457      */

458     public void addAreas(PositionIterator parentIter,
459                          LayoutContext layoutContext) {
460         getParentArea(null);
461
462         getPSLM().addIDToPage(getListItemFO().getId());
463
464         LayoutContext lc = new LayoutContext(0);
465         Position firstPos = null;
466         Position lastPos = null;
467
468         // "unwrap" the NonLeafPositions stored in parentIter
469
LinkedList JavaDoc positionList = new LinkedList JavaDoc();
470         Position pos;
471         while (parentIter.hasNext()) {
472             pos = (Position) parentIter.next();
473             if (pos.getIndex() >= 0) {
474                 if (firstPos == null) {
475                     firstPos = pos;
476                 }
477                 lastPos = pos;
478             }
479             if (pos instanceof NonLeafPosition && pos.getPosition() != null) {
480                 // pos contains a ListItemPosition created by this ListBlockLM
481
positionList.add(((NonLeafPosition) pos).getPosition());
482             }
483         }
484
485         if (markers != null) {
486             getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
487         }
488
489         // use the first and the last ListItemPosition to determine the
490
// corresponding indexes in the original labelList and bodyList
491
int labelFirstIndex = ((ListItemPosition) positionList.getFirst()).getLabelFirstIndex();
492         int labelLastIndex = ((ListItemPosition) positionList.getLast()).getLabelLastIndex();
493         int bodyFirstIndex = ((ListItemPosition) positionList.getFirst()).getBodyFirstIndex();
494         int bodyLastIndex = ((ListItemPosition) positionList.getLast()).getBodyLastIndex();
495
496         //Determine previous break if any
497
int previousBreak = ElementListUtils.determinePreviousBreak(labelList, labelFirstIndex);
498         SpaceResolver.performConditionalsNotification(labelList,
499                 labelFirstIndex, labelLastIndex, previousBreak);
500
501         //Determine previous break if any
502
previousBreak = ElementListUtils.determinePreviousBreak(bodyList, bodyFirstIndex);
503         SpaceResolver.performConditionalsNotification(bodyList,
504                 bodyFirstIndex, bodyLastIndex, previousBreak);
505         
506         // add label areas
507
if (labelFirstIndex <= labelLastIndex) {
508             KnuthPossPosIter labelIter = new KnuthPossPosIter(labelList,
509                     labelFirstIndex, labelLastIndex + 1);
510             lc.setFlags(LayoutContext.FIRST_AREA, layoutContext.isFirstArea());
511             lc.setFlags(LayoutContext.LAST_AREA, layoutContext.isLastArea());
512             // set the space adjustment ratio
513
lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
514             // TO DO: use the right stack limit for the label
515
lc.setStackLimit(layoutContext.getStackLimit());
516             label.addAreas(labelIter, lc);
517         }
518
519         // reset the area bpd after adding the label areas and before adding the body areas
520
int savedBPD = 0;
521         if (labelFirstIndex <= labelLastIndex
522             && bodyFirstIndex <= bodyLastIndex) {
523             savedBPD = curBlockArea.getBPD();
524             curBlockArea.setBPD(0);
525         }
526
527         // add body areas
528
if (bodyFirstIndex <= bodyLastIndex) {
529             KnuthPossPosIter bodyIter = new KnuthPossPosIter(bodyList,
530                     bodyFirstIndex, bodyLastIndex + 1);
531             lc.setFlags(LayoutContext.FIRST_AREA, layoutContext.isFirstArea());
532             lc.setFlags(LayoutContext.LAST_AREA, layoutContext.isLastArea());
533             // set the space adjustment ratio
534
lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
535             // TO DO: use the right stack limit for the body
536
lc.setStackLimit(layoutContext.getStackLimit());
537             body.addAreas(bodyIter, lc);
538         }
539
540         // after adding body areas, set the maximum area bpd
541
if (curBlockArea.getBPD() < savedBPD) {
542             curBlockArea.setBPD(savedBPD);
543         }
544
545         if (markers != null) {
546             getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
547         }
548
549         // We are done with this area add the background
550
TraitSetter.addBackground(curBlockArea,
551                 getListItemFO().getCommonBorderPaddingBackground(),
552                 this);
553         TraitSetter.addSpaceBeforeAfter(curBlockArea, layoutContext.getSpaceAdjust(),
554                 effSpaceBefore, effSpaceAfter);
555
556         flush();
557
558         curBlockArea = null;
559         resetSpaces();
560         
561         getPSLM().notifyEndOfLayout(((ListItem)getFObj()).getId());
562     }
563
564     /**
565      * Get the height of the list item after adjusting.
566      * Should only be called after adding the list item areas.
567      *
568      * @return the height of this list item after adjustment
569      */

570     public int getListItemHeight() {
571         return listItemHeight;
572     }
573
574     /**
575      * Return an Area which can contain the passed childArea. The childArea
576      * may not yet have any content, but it has essential traits set.
577      * In general, if the LayoutManager already has an Area it simply returns
578      * it. Otherwise, it makes a new Area of the appropriate class.
579      * It gets a parent area for its area by calling its parent LM.
580      * Finally, based on the dimensions of the parent area, it initializes
581      * its own area. This includes setting the content IPD and the maximum
582      * BPD.
583      *
584      * @param childArea the child area
585      * @return the parent are for the child
586      */

587     public Area getParentArea(Area childArea) {
588         if (curBlockArea == null) {
589             curBlockArea = new Block();
590
591             // Set up dimensions
592
/*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
593             
594             // set traits
595
TraitSetter.setProducerID(curBlockArea, getListItemFO().getId());
596             TraitSetter.addBorders(curBlockArea,
597                     getListItemFO().getCommonBorderPaddingBackground(),
598                     discardBorderBefore, discardBorderAfter, false, false, this);
599             TraitSetter.addPadding(curBlockArea,
600                     getListItemFO().getCommonBorderPaddingBackground(),
601                     discardPaddingBefore, discardPaddingAfter, false, false, this);
602             TraitSetter.addMargins(curBlockArea,
603                     getListItemFO().getCommonBorderPaddingBackground(),
604                     getListItemFO().getCommonMarginBlock(), this);
605             TraitSetter.addBreaks(curBlockArea,
606                     getListItemFO().getBreakBefore(),
607                     getListItemFO().getBreakAfter());
608             
609             int contentIPD = referenceIPD - getIPIndents();
610             curBlockArea.setIPD(contentIPD);
611
612             setCurrentArea(curBlockArea);
613         }
614         return curBlockArea;
615     }
616
617     /**
618      * Add the child.
619      * Rows return the areas returned by the child elements.
620      * This simply adds the area to the parent layout manager.
621      *
622      * @param childArea the child area
623      */

624     public void addChildArea(Area childArea) {
625         if (curBlockArea != null) {
626             curBlockArea.addBlock((Block) childArea);
627         }
628     }
629
630     /**
631      * Reset the position of this layout manager.
632      *
633      * @param resetPos the position to reset to
634      */

635     public void resetPosition(Position resetPos) {
636         if (resetPos == null) {
637             reset(null);
638         }
639     }
640     
641     /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() */
642     public boolean mustKeepTogether() {
643         //TODO Keeps will have to be more sophisticated sooner or later
644
return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()
645                 || !getListItemFO().getKeepTogether().getWithinPage().isAuto()
646                 || !getListItemFO().getKeepTogether().getWithinColumn().isAuto();
647     }
648
649     /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious() */
650     public boolean mustKeepWithPrevious() {
651         return !getListItemFO().getKeepWithPrevious().getWithinPage().isAuto()
652             || !getListItemFO().getKeepWithPrevious().getWithinColumn().isAuto();
653     }
654
655     /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext() */
656     public boolean mustKeepWithNext() {
657         return !getListItemFO().getKeepWithNext().getWithinPage().isAuto()
658                 || !getListItemFO().getKeepWithNext().getWithinColumn().isAuto();
659     }
660
661     /** @see org.apache.fop.layoutmgr.ConditionalElementListener */
662     public void notifySpace(RelSide side, MinOptMax effectiveLength) {
663         if (RelSide.BEFORE == side) {
664             if (log.isDebugEnabled()) {
665                 log.debug(this + ": Space " + side + ", "
666                         + this.effSpaceBefore + "-> " + effectiveLength);
667             }
668             this.effSpaceBefore = effectiveLength;
669         } else {
670             if (log.isDebugEnabled()) {
671                 log.debug(this + ": Space " + side + ", "
672                         + this.effSpaceAfter + "-> " + effectiveLength);
673             }
674             this.effSpaceAfter = effectiveLength;
675         }
676     }
677
678     /** @see org.apache.fop.layoutmgr.ConditionalElementListener */
679     public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
680         if (effectiveLength == null) {
681             if (RelSide.BEFORE == side) {
682                 this.discardBorderBefore = true;
683             } else {
684                 this.discardBorderAfter = true;
685             }
686         }
687         if (log.isDebugEnabled()) {
688             log.debug(this + ": Border " + side + " -> " + effectiveLength);
689         }
690     }
691
692     /** @see org.apache.fop.layoutmgr.ConditionalElementListener */
693     public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
694         if (effectiveLength == null) {
695             if (RelSide.BEFORE == side) {
696                 this.discardPaddingBefore = true;
697             } else {
698                 this.discardPaddingAfter = true;
699             }
700         }
701         if (log.isDebugEnabled()) {
702             log.debug(this + ": Padding " + side + " -> " + effectiveLength);
703         }
704     }
705
706     
707 }
708
709
Popular Tags