001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: ListItemContentLayoutManager.java 428011 2006-08-02 14:49:00Z jeremias $ */
019:
020: package org.apache.fop.layoutmgr.list;
021:
022: import org.apache.fop.fo.flow.AbstractListItemPart;
023: import org.apache.fop.fo.flow.ListItemBody;
024: import org.apache.fop.fo.flow.ListItemLabel;
025: import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
026: import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
027: import org.apache.fop.layoutmgr.LayoutManager;
028: import org.apache.fop.layoutmgr.LayoutContext;
029: import org.apache.fop.layoutmgr.PositionIterator;
030: import org.apache.fop.layoutmgr.Position;
031: import org.apache.fop.layoutmgr.NonLeafPosition;
032: import org.apache.fop.layoutmgr.TraitSetter;
033: import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition;
034: import org.apache.fop.area.Area;
035: import org.apache.fop.area.Block;
036:
037: import java.util.Iterator;
038: import java.util.List;
039: import java.util.LinkedList;
040:
041: /**
042: * LayoutManager for a list-item-label or list-item-body FO.
043: */
044: public class ListItemContentLayoutManager extends
045: BlockStackingLayoutManager {
046:
047: private Block curBlockArea;
048:
049: private int xoffset;
050: private int itemIPD;
051:
052: private static class StackingIter extends PositionIterator {
053: StackingIter(Iterator parentIter) {
054: super (parentIter);
055: }
056:
057: protected LayoutManager getLM(Object nextObj) {
058: return ((Position) nextObj).getLM();
059: }
060:
061: protected Position getPos(Object nextObj) {
062: return ((Position) nextObj);
063: }
064: }
065:
066: /**
067: * Create a new Cell layout manager.
068: * @param node list-item-label node
069: */
070: public ListItemContentLayoutManager(ListItemLabel node) {
071: super (node);
072: }
073:
074: /**
075: * Create a new Cell layout manager.
076: * @param node list-item-body node
077: */
078: public ListItemContentLayoutManager(ListItemBody node) {
079: super (node);
080: }
081:
082: /**
083: * Convenience method.
084: * @return the ListBlock node
085: */
086: protected AbstractListItemPart getPartFO() {
087: return (AbstractListItemPart) fobj;
088: }
089:
090: /**
091: * Set the x offset of this list item.
092: * This offset is used to set the absolute position
093: * of the list item within the parent block area.
094: *
095: * @param off the x offset
096: */
097: public void setXOffset(int off) {
098: xoffset = off;
099: }
100:
101: /** @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int) */
102: public LinkedList getChangedKnuthElements(List oldList,
103: int alignment) {
104: //log.debug(" ListItemContentLayoutManager.getChanged>");
105: return super .getChangedKnuthElements(oldList, alignment);
106: }
107:
108: /**
109: * Add the areas for the break points.
110: * The list item contains block stacking layout managers
111: * that add block areas.
112: *
113: * @param parentIter the iterator of the break positions
114: * @param layoutContext the layout context for adding the areas
115: */
116: public void addAreas(PositionIterator parentIter,
117: LayoutContext layoutContext) {
118: getParentArea(null);
119:
120: getPSLM().addIDToPage(getPartFO().getId());
121:
122: LayoutManager childLM = null;
123: LayoutContext lc = new LayoutContext(0);
124: LayoutManager firstLM = null;
125: LayoutManager lastLM = null;
126: Position firstPos = null;
127: Position lastPos = null;
128:
129: // "unwrap" the NonLeafPositions stored in parentIter
130: // and put them in a new list;
131: LinkedList positionList = new LinkedList();
132: Position pos;
133: while (parentIter.hasNext()) {
134: pos = (Position) parentIter.next();
135: if (pos == null) {
136: continue;
137: }
138: if (pos.getIndex() >= 0) {
139: if (firstPos == null) {
140: firstPos = pos;
141: }
142: lastPos = pos;
143: }
144: if (pos instanceof NonLeafPosition) {
145: // pos was created by a child of this ListBlockLM
146: positionList.add(((NonLeafPosition) pos).getPosition());
147: lastLM = ((NonLeafPosition) pos).getPosition().getLM();
148: if (firstLM == null) {
149: firstLM = lastLM;
150: }
151: } else if (pos instanceof SpaceHandlingBreakPosition) {
152: positionList.add(pos);
153: } else {
154: // pos was created by this ListBlockLM, so it must be ignored
155: }
156: }
157:
158: if (markers != null) {
159: getCurrentPV().addMarkers(markers, true, isFirst(firstPos),
160: isLast(lastPos));
161: }
162:
163: StackingIter childPosIter = new StackingIter(positionList
164: .listIterator());
165: while ((childLM = childPosIter.getNextChildLM()) != null) {
166: // Add the block areas to Area
167: lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM);
168: lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM);
169: // set the space adjustment ratio
170: lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
171: lc.setStackLimit(layoutContext.getStackLimit());
172: childLM.addAreas(childPosIter, lc);
173: }
174:
175: if (markers != null) {
176: getCurrentPV().addMarkers(markers, false,
177: isFirst(firstPos), isLast(lastPos));
178: }
179:
180: flush();
181:
182: curBlockArea = null;
183:
184: getPSLM().notifyEndOfLayout(
185: ((AbstractListItemPart) getFObj()).getId());
186: }
187:
188: /**
189: * Return an Area which can contain the passed childArea. The childArea
190: * may not yet have any content, but it has essential traits set.
191: * In general, if the LayoutManager already has an Area it simply returns
192: * it. Otherwise, it makes a new Area of the appropriate class.
193: * It gets a parent area for its area by calling its parent LM.
194: * Finally, based on the dimensions of the parent area, it initializes
195: * its own area. This includes setting the content IPD and the maximum
196: * BPD.
197: *
198: * @param childArea the child area to get the parent for
199: * @return the parent area
200: */
201: public Area getParentArea(Area childArea) {
202: if (curBlockArea == null) {
203: curBlockArea = new Block();
204: curBlockArea.setPositioning(Block.ABSOLUTE);
205: // set position
206: curBlockArea.setXOffset(xoffset);
207: curBlockArea.setIPD(itemIPD);
208: //curBlockArea.setHeight();
209:
210: TraitSetter
211: .setProducerID(curBlockArea, getPartFO().getId());
212:
213: // Set up dimensions
214: Area parentArea = parentLM.getParentArea(curBlockArea);
215: int referenceIPD = parentArea.getIPD();
216: curBlockArea.setIPD(referenceIPD);
217: // Get reference IPD from parentArea
218: setCurrentArea(curBlockArea); // ??? for generic operations
219: }
220: return curBlockArea;
221: }
222:
223: /**
224: * Add the child to the list item area.
225: *
226: * @param childArea the child to add to the cell
227: */
228: public void addChildArea(Area childArea) {
229: if (curBlockArea != null) {
230: curBlockArea.addBlock((Block) childArea);
231: }
232: }
233:
234: /**
235: * Reset the position of the layout.
236: *
237: * @param resetPos the position to reset to
238: */
239: public void resetPosition(Position resetPos) {
240: if (resetPos == null) {
241: reset(null);
242: } else {
243: setFinished(false);
244: //reset(resetPos);
245: }
246: }
247:
248: /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() */
249: public boolean mustKeepTogether() {
250: //TODO Keeps will have to be more sophisticated sooner or later
251: return ((BlockLevelLayoutManager) getParent())
252: .mustKeepTogether()
253: || !getPartFO().getKeepTogether().getWithinPage()
254: .isAuto()
255: || !getPartFO().getKeepTogether().getWithinColumn()
256: .isAuto();
257: }
258:
259: }
|