1 17 18 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.ListBlock; 25 import org.apache.fop.layoutmgr.BlockLevelLayoutManager; 26 import org.apache.fop.layoutmgr.BlockStackingLayoutManager; 27 import org.apache.fop.layoutmgr.ConditionalElementListener; 28 import org.apache.fop.layoutmgr.ElementListUtils; 29 import org.apache.fop.layoutmgr.LayoutManager; 30 import org.apache.fop.layoutmgr.LayoutContext; 31 import org.apache.fop.layoutmgr.PositionIterator; 32 import org.apache.fop.layoutmgr.Position; 33 import org.apache.fop.layoutmgr.NonLeafPosition; 34 import org.apache.fop.layoutmgr.RelSide; 35 import org.apache.fop.layoutmgr.TraitSetter; 36 import org.apache.fop.area.Area; 37 import org.apache.fop.area.Block; 38 import org.apache.fop.traits.MinOptMax; 39 import org.apache.fop.traits.SpaceVal; 40 41 import java.util.Iterator ; 42 import java.util.LinkedList ; 43 import java.util.List ; 44 45 50 public class ListBlockLayoutManager extends BlockStackingLayoutManager 51 implements ConditionalElementListener { 52 53 56 private static Log log = LogFactory.getLog(ListBlockLayoutManager.class); 57 58 private Block curBlockArea; 59 60 private boolean discardBorderBefore; 61 private boolean discardBorderAfter; 62 private boolean discardPaddingBefore; 63 private boolean discardPaddingAfter; 64 private MinOptMax effSpaceBefore; 65 private MinOptMax effSpaceAfter; 66 67 private static class StackingIter extends PositionIterator { 68 StackingIter(Iterator parentIter) { 69 super(parentIter); 70 } 71 72 protected LayoutManager getLM(Object nextObj) { 73 return ((Position) nextObj).getLM(); 74 } 75 76 protected Position getPos(Object nextObj) { 77 return ((Position) nextObj); 78 } 79 } 80 81 85 public ListBlockLayoutManager(ListBlock node) { 86 super(node); 87 } 88 89 93 protected ListBlock getListBlockFO() { 94 return (ListBlock)fobj; 95 } 96 97 98 public void initialize() { 99 foSpaceBefore = new SpaceVal( 100 getListBlockFO().getCommonMarginBlock().spaceBefore, this).getSpace(); 101 foSpaceAfter = new SpaceVal( 102 getListBlockFO().getCommonMarginBlock().spaceAfter, this).getSpace(); 103 startIndent = getListBlockFO().getCommonMarginBlock().startIndent.getValue(this); 104 endIndent = getListBlockFO().getCommonMarginBlock().endIndent.getValue(this); 105 } 106 107 private void resetSpaces() { 108 this.discardBorderBefore = false; 109 this.discardBorderAfter = false; 110 this.discardPaddingBefore = false; 111 this.discardPaddingAfter = false; 112 this.effSpaceBefore = null; 113 this.effSpaceAfter = null; 114 } 115 116 117 public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { 118 resetSpaces(); 119 LinkedList returnList = super.getNextKnuthElements(context, alignment); 120 121 int widowRowLimit = getListBlockFO().getWidowContentLimit().getValue(); 123 if (widowRowLimit != 0) { 124 ElementListUtils.removeLegalBreaks(returnList, widowRowLimit); 125 } 126 127 int orphanRowLimit = getListBlockFO().getOrphanContentLimit().getValue(); 129 if (orphanRowLimit != 0) { 130 ElementListUtils.removeLegalBreaksFromEnd(returnList, orphanRowLimit); 131 } 132 133 return returnList; 134 } 135 136 137 public LinkedList getChangedKnuthElements(List oldList, int alignment) { 138 return super.getChangedKnuthElements(oldList, alignment); 140 } 141 142 149 public void addAreas(PositionIterator parentIter, 150 LayoutContext layoutContext) { 151 getParentArea(null); 152 153 if (layoutContext.getSpaceBefore() > 0) { 156 addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore())); 157 } 158 159 getPSLM().addIDToPage(getListBlockFO().getId()); 160 161 163 LayoutManager childLM = null; 164 LayoutContext lc = new LayoutContext(0); 165 LayoutManager firstLM = null; 166 LayoutManager lastLM = null; 167 Position firstPos = null; 168 Position lastPos = null; 169 170 LinkedList positionList = new LinkedList (); 173 Position pos; 174 while (parentIter.hasNext()) { 175 pos = (Position)parentIter.next(); 176 if (pos.getIndex() >= 0) { 177 if (firstPos == null) { 178 firstPos = pos; 179 } 180 lastPos = pos; 181 } 182 if (pos instanceof NonLeafPosition 183 && (pos.getPosition() != null) 184 && ((NonLeafPosition) pos).getPosition().getLM() != this) { 185 positionList.add(((NonLeafPosition) pos).getPosition()); 187 lastLM = ((NonLeafPosition) pos).getPosition().getLM(); 188 if (firstLM == null) { 189 firstLM = lastLM; 190 } 191 } 192 } 193 194 if (markers != null) { 195 getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos)); 196 } 197 198 StackingIter childPosIter = new StackingIter(positionList.listIterator()); 199 while ((childLM = childPosIter.getNextChildLM()) != null) { 200 lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); 203 lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM); 204 lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM); 205 lc.setStackLimit(layoutContext.getStackLimit()); 206 childLM.addAreas(childPosIter, lc); 207 } 208 209 if (markers != null) { 210 getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos)); 211 } 212 213 TraitSetter.addBackground(curBlockArea, 215 getListBlockFO().getCommonBorderPaddingBackground(), 216 this); 217 TraitSetter.addSpaceBeforeAfter(curBlockArea, layoutContext.getSpaceAdjust(), 218 effSpaceBefore, effSpaceAfter); 219 220 flush(); 221 222 curBlockArea = null; 223 resetSpaces(); 224 225 getPSLM().notifyEndOfLayout(((ListBlock)getFObj()).getId()); 226 } 227 228 241 public Area getParentArea(Area childArea) { 242 if (curBlockArea == null) { 243 curBlockArea = new Block(); 244 245 parentLM.getParentArea(curBlockArea); 248 249 TraitSetter.setProducerID(curBlockArea, getListBlockFO().getId()); 251 TraitSetter.addBorders(curBlockArea, 252 getListBlockFO().getCommonBorderPaddingBackground(), 253 discardBorderBefore, discardBorderAfter, false, false, this); 254 TraitSetter.addPadding(curBlockArea, 255 getListBlockFO().getCommonBorderPaddingBackground(), 256 discardPaddingBefore, discardPaddingAfter, false, false, this); 257 TraitSetter.addMargins(curBlockArea, 258 getListBlockFO().getCommonBorderPaddingBackground(), 259 getListBlockFO().getCommonMarginBlock(), 260 this); 261 TraitSetter.addBreaks(curBlockArea, 262 getListBlockFO().getBreakBefore(), 263 getListBlockFO().getBreakAfter()); 264 265 int contentIPD = referenceIPD - getIPIndents(); 266 curBlockArea.setIPD(contentIPD); 267 268 setCurrentArea(curBlockArea); 269 } 270 return curBlockArea; 271 } 272 273 278 public void addChildArea(Area childArea) { 279 if (curBlockArea != null) { 280 curBlockArea.addBlock((Block) childArea); 281 } 282 } 283 284 289 public void resetPosition(Position resetPos) { 290 if (resetPos == null) { 291 reset(null); 292 } else { 293 } 295 } 296 297 298 public boolean mustKeepTogether() { 299 return ((BlockLevelLayoutManager)getParent()).mustKeepTogether() 301 || !getListBlockFO().getKeepTogether().getWithinPage().isAuto() 302 || !getListBlockFO().getKeepTogether().getWithinColumn().isAuto(); 303 } 304 305 306 public boolean mustKeepWithPrevious() { 307 return !getListBlockFO().getKeepWithPrevious().getWithinPage().isAuto() 308 || !getListBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); 309 } 310 311 312 public boolean mustKeepWithNext() { 313 return !getListBlockFO().getKeepWithNext().getWithinPage().isAuto() 314 || !getListBlockFO().getKeepWithNext().getWithinColumn().isAuto(); 315 } 316 317 318 public void notifySpace(RelSide side, MinOptMax effectiveLength) { 319 if (RelSide.BEFORE == side) { 320 if (log.isDebugEnabled()) { 321 log.debug(this + ": Space " + side + ", " 322 + this.effSpaceBefore + "-> " + effectiveLength); 323 } 324 this.effSpaceBefore = effectiveLength; 325 } else { 326 if (log.isDebugEnabled()) { 327 log.debug(this + ": Space " + side + ", " 328 + this.effSpaceAfter + "-> " + effectiveLength); 329 } 330 this.effSpaceAfter = effectiveLength; 331 } 332 } 333 334 335 public void notifyBorder(RelSide side, MinOptMax effectiveLength) { 336 if (effectiveLength == null) { 337 if (RelSide.BEFORE == side) { 338 this.discardBorderBefore = true; 339 } else { 340 this.discardBorderAfter = true; 341 } 342 } 343 if (log.isDebugEnabled()) { 344 log.debug(this + ": Border " + side + " -> " + effectiveLength); 345 } 346 } 347 348 349 public void notifyPadding(RelSide side, MinOptMax effectiveLength) { 350 if (effectiveLength == null) { 351 if (RelSide.BEFORE == side) { 352 this.discardPaddingBefore = true; 353 } else { 354 this.discardPaddingAfter = true; 355 } 356 } 357 if (log.isDebugEnabled()) { 358 log.debug(this + ": Padding " + side + " -> " + effectiveLength); 359 } 360 } 361 362 } 363 364 | Popular Tags |