1 51 package org.apache.fop.layout; 52 53 import org.apache.fop.render.Renderer; 55 import org.apache.fop.datatypes.IDReferences; 56 import org.apache.fop.apps.FOPException; 57 import org.apache.fop.fo.FObj; 58 import org.apache.fop.fo.flow.Block; 59 import org.apache.fop.fo.flow.BlockContainer; 60 import org.apache.fop.fo.properties.Span; 61 62 import org.apache.fop.fo.properties.Position; 63 64 import java.util.ArrayList ; 66 67 public class BodyAreaContainer extends Area { 68 69 private int xPosition; private int yPosition; private int position; 73 74 private int columnCount; 76 private int columnGap; 77 78 private AreaContainer mainReferenceArea; 80 private AreaContainer beforeFloatReferenceArea; 81 private AreaContainer footnoteReferenceArea; 82 83 private int mainRefAreaHeight; 85 86 private int mainYPosition; 88 private int beforeFloatYPosition; 89 private int footnoteYPosition; 90 91 private FObj startFO; 93 private boolean isNewSpanArea; 94 95 private int footnoteState = 0; 97 98 public BodyAreaContainer(FontState fontState, int xPosition, 99 int yPosition, int allocationWidth, 100 int maxHeight, int position, int columnCount, 101 int columnGap) { 102 super(fontState, allocationWidth, maxHeight); 103 this.xPosition = xPosition; 104 this.yPosition = yPosition; 105 this.position = position; 106 this.columnCount = columnCount; 107 this.columnGap = columnGap; 108 109 mainRefAreaHeight = maxHeight; 111 beforeFloatReferenceArea = new AreaContainer(fontState, xPosition, 112 yPosition, 113 allocationWidth, 0, 114 Position.ABSOLUTE); 115 beforeFloatReferenceArea.setAreaName("before-float-reference-area"); 116 this.addChild(beforeFloatReferenceArea); 117 mainReferenceArea = new AreaContainer(fontState, xPosition, 118 yPosition, allocationWidth, 119 mainRefAreaHeight, 120 Position.ABSOLUTE); 121 mainReferenceArea.setAreaName("main-reference-area"); 122 this.addChild(mainReferenceArea); 123 footnoteReferenceArea = new AreaContainer(fontState, xPosition, 124 yPosition - mainRefAreaHeight, 125 allocationWidth, 0, 126 Position.ABSOLUTE); 127 footnoteReferenceArea.setAreaName("footnote-reference-area"); 128 this.addChild(footnoteReferenceArea); 129 130 } 135 136 public void render(Renderer renderer) { 137 renderer.renderBodyAreaContainer(this); 138 } 139 140 public int getPosition() { 141 return position; 142 } 143 144 public int getXPosition() { 145 return xPosition + getPaddingLeft() + getBorderLeftWidth(); 146 } 147 148 public void setXPosition(int value) { 149 xPosition = value; 150 } 151 152 public int getYPosition() { 153 return yPosition + getPaddingTop() + getBorderTopWidth(); 154 } 155 156 public void setYPosition(int value) { 157 yPosition = value; 158 } 159 160 public AreaContainer getMainReferenceArea() { 161 return mainReferenceArea; 162 } 163 164 public AreaContainer getBeforeFloatReferenceArea() { 165 return beforeFloatReferenceArea; 166 } 167 168 public AreaContainer getFootnoteReferenceArea() { 169 return footnoteReferenceArea; 170 } 171 172 public void setIDReferences(IDReferences idReferences) { 173 mainReferenceArea.setIDReferences(idReferences); 174 } 175 176 public IDReferences getIDReferences() { 177 return mainReferenceArea.getIDReferences(); 178 } 179 180 190 public AreaContainer getNextArea(FObj fo) throws FOPException { 191 isNewSpanArea = false; 192 193 int span = Span.NONE; 194 if (fo instanceof Block) 195 span = ((Block)fo).getSpan(); 196 else if (fo instanceof BlockContainer) 197 span = ((BlockContainer)fo).getSpan(); 198 199 if (this.mainReferenceArea.getChildren().isEmpty()) { 200 if (span == Span.ALL) 201 return addSpanArea(1); 202 else 203 return addSpanArea(columnCount); 204 } 205 206 ArrayList spanAreas = this.mainReferenceArea.getChildren(); 207 SpanArea spanArea = (SpanArea)spanAreas.get(spanAreas.size() 208 - 1); 209 210 if ((span == Span.ALL) && (spanArea.getColumnCount() == 1)) { 211 return spanArea.getCurrentColumnArea(); 213 } else if ((span == Span.NONE) 214 && (spanArea.getColumnCount() == columnCount)) { 215 return spanArea.getCurrentColumnArea(); 217 } else if (span == Span.ALL) { 218 return addSpanArea(1); 220 } else if (span == Span.NONE) { 221 return addSpanArea(columnCount); 223 } else { 224 throw new FOPException("BodyAreaContainer::getNextArea(): Span attribute messed up"); 225 } 226 } 227 228 233 private AreaContainer addSpanArea(int numColumns) { 234 resetHeights(); 235 int spanAreaYPosition = getYPosition() 239 - this.mainReferenceArea.getContentHeight(); 240 241 SpanArea spanArea = new SpanArea(fontState, getXPosition(), 242 spanAreaYPosition, allocationWidth, 243 getRemainingHeight(), numColumns, 244 columnGap); 245 this.mainReferenceArea.addChild(spanArea); 246 spanArea.setPage(this.getPage()); 247 this.isNewSpanArea = true; 248 return spanArea.getCurrentColumnArea(); 249 } 250 251 257 public boolean isBalancingRequired(FObj fo) { 258 if (this.mainReferenceArea.getChildren().isEmpty()) 259 return false; 260 261 ArrayList spanAreas = this.mainReferenceArea.getChildren(); 262 SpanArea spanArea = (SpanArea)spanAreas.get(spanAreas.size() 263 - 1); 264 265 if (spanArea.isBalanced()) 266 return false; 267 268 int span = Span.NONE; 269 if (fo instanceof Block) 270 span = ((Block)fo).getSpan(); 271 else if (fo instanceof BlockContainer) 272 span = ((BlockContainer)fo).getSpan(); 273 274 if ((span == Span.ALL) && (spanArea.getColumnCount() == 1)) 275 return false; 276 else if ((span == Span.NONE) 277 && (spanArea.getColumnCount() == columnCount)) 278 return false; 279 else if (span == Span.ALL) 280 return true; 281 else if (span == Span.NONE) 282 return false; 283 else 284 return false; 285 } 286 287 295 public void resetSpanArea() { 296 ArrayList spanAreas = this.mainReferenceArea.getChildren(); 297 SpanArea spanArea = (SpanArea)spanAreas.get(spanAreas.size() - 1); 298 299 if (!spanArea.isBalanced()) { 300 int newHeight = spanArea.getTotalContentHeight() 303 / spanArea.getColumnCount(); 304 newHeight += 2 * 15600; 306 this.mainReferenceArea.removeChild(spanArea); 307 resetHeights(); 308 SpanArea newSpanArea = new SpanArea(fontState, getXPosition(), 309 spanArea.getYPosition(), 310 allocationWidth, newHeight, 311 spanArea.getColumnCount(), 312 columnGap); 313 this.mainReferenceArea.addChild(newSpanArea); 314 newSpanArea.setPage(this.getPage()); 315 newSpanArea.setIsBalanced(); 316 this.isNewSpanArea = true; 317 } else { 318 throw new IllegalStateException ("Trying to balance balanced area"); 319 } 320 } 321 322 328 public int getRemainingHeight() { 329 return this.mainReferenceArea.getMaxHeight() 330 - this.mainReferenceArea.getContentHeight(); 331 } 332 333 337 private void resetHeights() { 338 int totalHeight = 0; 339 ArrayList children = this.mainReferenceArea.getChildren(); 340 for (int i = 0; i < children.size(); i++) { 341 SpanArea spanArea = (SpanArea)children.get(i); 342 int spanContentHeight = spanArea.getMaxContentHeight(); 343 int spanMaxHeight = spanArea.getMaxHeight(); 344 345 totalHeight += (spanContentHeight < spanMaxHeight) 346 ? spanContentHeight : spanMaxHeight; 347 } 348 this.mainReferenceArea.setHeight(totalHeight); 349 } 350 351 355 public boolean isLastColumn() { 356 ArrayList spanAreas = this.mainReferenceArea.getChildren(); 357 SpanArea spanArea = (SpanArea)spanAreas.get(spanAreas.size() - 1); 358 return spanArea.isLastColumn(); 359 } 360 361 366 public boolean isNewSpanArea() { 367 return isNewSpanArea; 368 } 369 370 public AreaContainer getCurrentColumnArea() { 371 ArrayList spanAreas = this.mainReferenceArea.getChildren(); 372 SpanArea spanArea = (SpanArea)spanAreas.get(spanAreas.size() - 1); 373 return spanArea.getCurrentColumnArea(); 374 } 375 376 public int getFootnoteState() { 377 return footnoteState; 378 } 379 380 public boolean needsFootnoteAdjusting() { 381 footnoteYPosition = footnoteReferenceArea.getYPosition(); 382 switch (footnoteState) { 383 case 0: 384 resetHeights(); 385 if (footnoteReferenceArea.getHeight() > 0 386 && mainYPosition + mainReferenceArea.getHeight() 387 > footnoteYPosition) { 388 return true; 389 } 390 case 1: 391 break; 392 } 393 return false; 394 } 395 396 public void adjustFootnoteArea() { 397 footnoteState++; 398 if (footnoteState == 1) { 399 mainReferenceArea.setMaxHeight(footnoteReferenceArea.getYPosition() 400 - mainYPosition); 401 footnoteYPosition = footnoteReferenceArea.getYPosition(); 402 footnoteReferenceArea.setMaxHeight(footnoteReferenceArea.getHeight()); 403 404 ArrayList children = footnoteReferenceArea.getChildren(); 405 for (int i = 0; i < children.size(); i++) { 406 Object obj = children.get(i); 407 if (obj instanceof Area) { 408 Area childArea = (Area)obj; 409 footnoteReferenceArea.removeChild(childArea); 410 } 411 } 412 413 getPage().setPendingFootnotes(null); 414 } 415 } 416 417 protected static void resetMaxHeight(Area ar, int change) { 418 ar.setMaxHeight(change); 419 ArrayList childs = ar.getChildren(); 420 for (int i = 0; i < childs.size(); i++) { 421 Object obj = childs.get(i); 422 if (obj instanceof Area) { 423 Area childArea = (Area)obj; 424 resetMaxHeight(childArea, change); 425 } 426 } 427 } 428 429 } 430 | Popular Tags |