1 17 18 19 20 package org.apache.fop.layoutmgr; 21 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 import org.apache.fop.fo.pagination.Flow; 25 import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager; 26 import org.apache.fop.area.Area; 27 import org.apache.fop.area.BlockParent; 28 29 import java.util.LinkedList ; 30 import java.util.List ; 31 import java.util.ListIterator ; 32 33 40 public class FlowLayoutManager extends BlockStackingLayoutManager 41 implements BlockLevelLayoutManager { 42 43 46 private static Log log = LogFactory.getLog(FlowLayoutManager.class); 47 48 49 private BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX]; 50 51 private int currentSpan = EN_NONE; 52 53 59 public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) { 60 super(node); 61 setParent(pslm); 62 } 63 64 65 public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { 66 67 int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth(); 69 int flowBPD = (int) getCurrentPV().getBodyRegion().getBPD(); 70 71 BlockLevelLayoutManager curLM; 73 LinkedList returnedList; 74 LinkedList returnList = new LinkedList (); 75 76 while ((curLM = ((BlockLevelLayoutManager) getChildLM())) != null) { 77 if (curLM instanceof InlineLevelLayoutManager) { 78 log.error("inline area not allowed under flow - ignoring"); 79 curLM.setFinished(true); 80 continue; 81 } 82 83 int span = EN_NONE; 84 if (curLM instanceof BlockLayoutManager) { 85 span = ((BlockLayoutManager)curLM).getBlockFO().getSpan(); 86 } else if (curLM instanceof BlockContainerLayoutManager) { 87 span = ((BlockContainerLayoutManager)curLM).getBlockContainerFO().getSpan(); 88 } 89 if (currentSpan != span) { 90 log.debug("span change from " + currentSpan + " to " + span); 91 context.signalSpanChange(span); 92 currentSpan = span; 93 SpaceResolver.resolveElementList(returnList); 94 return returnList; 95 } 96 97 100 LayoutContext childLC = new LayoutContext(0); 101 childLC.setStackLimit(context.getStackLimit()); 102 childLC.setRefIPD(context.getRefIPD()); 103 childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode()); 104 105 returnedList = curLM.getNextKnuthElements(childLC, alignment); 107 if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { 109 context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); 110 childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); 111 } 112 113 LinkedList tempList = returnedList; 115 returnedList = new LinkedList (); 116 wrapPositionElements(tempList, returnedList); 117 118 if (returnedList.size() == 1 119 && ElementListUtils.endsWithForcedBreak(returnedList)) { 120 returnList.addAll(returnedList); 122 SpaceResolver.resolveElementList(returnList); 123 return returnList; 124 } else { 125 if (returnList.size() > 0) { 126 if (context.isKeepWithNextPending() 128 || childLC.isKeepWithPreviousPending()) { 129 context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); 131 childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); 132 returnList.add(new BreakElement( 134 new Position(this), KnuthElement.INFINITE, context)); 135 } else if (!((ListElement) returnList.getLast()).isGlue()) { 136 returnList.add(new BreakElement( 138 new Position(this), 0, context)); 139 } 140 } 141 if (returnedList.size() > 0) { 142 returnList.addAll(returnedList); 143 if (ElementListUtils.endsWithForcedBreak(returnList)) { 144 SpaceResolver.resolveElementList(returnList); 146 return returnList; 147 } 148 } 149 } 150 if (childLC.isKeepWithNextPending()) { 151 childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); 153 context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); 154 } 155 } 156 157 SpaceResolver.resolveElementList(returnList); 158 setFinished(true); 159 160 if (returnList.size() > 0) { 161 return returnList; 162 } else { 163 return null; 164 } 165 } 166 167 170 public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) { 171 log.debug(" FLM.negotiateBPDAdjustment> " + adj); 172 173 if (lastElement.getPosition() instanceof NonLeafPosition) { 174 NonLeafPosition savedPos = (NonLeafPosition)lastElement.getPosition(); 176 lastElement.setPosition(savedPos.getPosition()); 177 int returnValue = ((BlockLevelLayoutManager)lastElement.getLayoutManager()) 178 .negotiateBPDAdjustment(adj, lastElement); 179 lastElement.setPosition(savedPos); 180 log.debug(" FLM.negotiateBPDAdjustment> result " + returnValue); 181 return returnValue; 182 } else { 183 return 0; 184 } 185 } 186 187 190 public void discardSpace(KnuthGlue spaceGlue) { 191 log.debug(" FLM.discardSpace> "); 192 193 if (spaceGlue.getPosition() instanceof NonLeafPosition) { 194 NonLeafPosition savedPos = (NonLeafPosition)spaceGlue.getPosition(); 196 spaceGlue.setPosition(savedPos.getPosition()); 197 ((BlockLevelLayoutManager) spaceGlue.getLayoutManager()).discardSpace(spaceGlue); 198 spaceGlue.setPosition(savedPos); 199 } 200 } 201 202 203 public boolean mustKeepTogether() { 204 return false; 205 } 206 207 208 public boolean mustKeepWithPrevious() { 209 return false; 210 } 211 212 213 public boolean mustKeepWithNext() { 214 return false; 215 } 216 217 220 public LinkedList getChangedKnuthElements(List oldList, int alignment) { 221 ListIterator oldListIterator = oldList.listIterator(); 222 KnuthElement returnedElement; 223 LinkedList returnedList = new LinkedList (); 224 LinkedList returnList = new LinkedList (); 225 KnuthElement prevElement = null; 226 KnuthElement currElement = null; 227 int fromIndex = 0; 228 229 KnuthElement oldElement; 231 while (oldListIterator.hasNext()) { 232 oldElement = (KnuthElement)oldListIterator.next(); 233 if (oldElement.getPosition() instanceof NonLeafPosition) { 234 oldElement.setPosition(((NonLeafPosition)oldElement.getPosition()).getPosition()); 236 } else { 237 oldListIterator.remove(); 239 } 240 } 241 oldListIterator = oldList.listIterator(); 243 244 245 while (oldListIterator.hasNext()) { 246 currElement = (KnuthElement) oldListIterator.next(); 247 if (prevElement != null 248 && prevElement.getLayoutManager() != currElement.getLayoutManager()) { 249 BlockLevelLayoutManager prevLM = (BlockLevelLayoutManager) 251 prevElement.getLayoutManager(); 252 BlockLevelLayoutManager currLM = (BlockLevelLayoutManager) 253 currElement.getLayoutManager(); 254 returnedList.addAll(prevLM.getChangedKnuthElements( 255 oldList.subList(fromIndex, oldListIterator.previousIndex()), alignment)); 256 fromIndex = oldListIterator.previousIndex(); 257 258 if (prevLM.mustKeepWithNext() 260 || currLM.mustKeepWithPrevious()) { 261 returnedList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, 263 new Position(this), false)); 264 } else if (!((KnuthElement) returnedList.getLast()).isGlue()) { 265 returnedList.add(new KnuthPenalty(0, 0, false, new Position(this), false)); 267 } 268 } 269 prevElement = currElement; 270 } 271 if (currElement != null) { 272 BlockLevelLayoutManager currLM = (BlockLevelLayoutManager) 273 currElement.getLayoutManager(); 274 returnedList.addAll(currLM.getChangedKnuthElements( 275 oldList.subList(fromIndex, oldList.size()), alignment)); 276 } 277 278 ListIterator listIter = returnedList.listIterator(); 281 while (listIter.hasNext()) { 282 returnedElement = (KnuthElement)listIter.next(); 283 if (returnedElement.getLayoutManager() != this) { 284 returnedElement.setPosition( 285 new NonLeafPosition(this, returnedElement.getPosition())); 286 } 287 returnList.add(returnedElement); 288 } 289 290 return returnList; 291 } 292 293 296 public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { 297 AreaAdditionUtil.addAreas(this, parentIter, layoutContext); 298 flush(); 299 } 300 301 307 public void addChildArea(Area childArea) { 308 getParentArea(childArea); 309 addChildToArea(childArea, 310 this.currentAreas[childArea.getAreaClass()]); 311 } 312 313 316 public Area getParentArea(Area childArea) { 317 BlockParent parentArea = null; 318 int aclass = childArea.getAreaClass(); 319 320 if (aclass == Area.CLASS_NORMAL) { 321 parentArea = getCurrentPV().getCurrentFlow(); 322 } else if (aclass == Area.CLASS_BEFORE_FLOAT) { 323 parentArea = getCurrentPV().getBodyRegion().getBeforeFloat(); 324 } else if (aclass == Area.CLASS_FOOTNOTE) { 325 parentArea = getCurrentPV().getBodyRegion().getFootnote(); 326 } else { 327 throw new IllegalStateException ("(internal error) Invalid " 328 + "area class (" + aclass + ") requested."); 329 } 330 331 this.currentAreas[aclass] = parentArea; 332 setCurrentArea(parentArea); 333 return parentArea; 334 } 335 336 339 public void resetPosition(Position resetPos) { 340 if (resetPos == null) { 341 reset(null); 342 } 343 } 344 348 public int getContentAreaIPD() { 349 return getCurrentPV().getCurrentSpan().getColumnWidth(); 350 } 351 352 356 public int getContentAreaBPD() { 357 return (int) getCurrentPV().getBodyRegion().getBPD(); 358 } 359 360 } 361 362 | Popular Tags |