1 51 package org.apache.fop.fo.flow; 52 53 import org.apache.fop.fo.*; 55 import org.apache.fop.fo.properties.*; 56 import org.apache.fop.layout.*; 57 import org.apache.fop.apps.FOPException; 58 59 public class TableCell extends FObj { 60 61 public static class Maker extends FObj.Maker { 62 public FObj make(FObj parent, PropertyList propertyList, 63 String systemId, int line, int column) 64 throws FOPException { 65 return new TableCell(parent, propertyList, systemId, line, column); 66 } 67 68 } 69 70 public static FObj.Maker maker() { 71 return new TableCell.Maker(); 72 } 73 74 77 String id; 78 int numColumnsSpanned; 79 int numRowsSpanned; 80 int iColNumber = -1; 82 86 protected int startOffset; 87 88 92 protected int width; 93 94 98 protected int beforeOffset = 0; 99 100 104 protected int startAdjust = 0; 105 106 110 protected int widthAdjust = 0; 111 112 113 protected int borderHeight = 0; 114 115 118 protected int minCellHeight = 0; 119 120 protected int height = 0; 121 protected int top; protected int verticalAlign; 123 protected boolean bRelativeAlign = false; 124 125 boolean bSepBorders = true; 127 128 131 boolean bDone=false; 132 133 137 int m_borderSeparation = 0; 138 139 AreaContainer cellArea; 140 141 public TableCell(FObj parent, PropertyList propertyList, 142 String systemId, int line, int column) 143 throws FOPException { 144 super(parent, propertyList, systemId, line, column); 145 if (!(parent instanceof TableRow)) { 146 throw new FOPException("A table cell must be child of fo:table-row," 147 + " not " + parent.getName(), systemId, line, column); 148 } 149 doSetup(); } 151 152 public String getName() { 153 return "fo:table-cell"; 154 } 155 156 public void setStartOffset(int offset) { 158 startOffset = offset; 159 } 160 161 public void setWidth(int width) { 164 this.width = width; 165 } 166 167 public int getColumnNumber() { 168 return iColNumber; 169 } 170 171 public int getNumColumnsSpanned() { 172 return numColumnsSpanned; 173 } 174 175 public int getNumRowsSpanned() { 176 return numRowsSpanned; 177 } 178 179 public void doSetup() { 181 AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); 183 184 AuralProps mAurProps = propMgr.getAuralProps(); 186 187 BorderAndPadding bap = propMgr.getBorderAndPadding(); 189 BackgroundProps bProps = propMgr.getBackgroundProps(); 190 191 RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); 193 194 211 this.iColNumber = 212 properties.get("column-number").getNumber().intValue(); 213 if (iColNumber < 0) { 214 iColNumber = 0; 215 } 216 this.numColumnsSpanned = 217 this.properties.get("number-columns-spanned").getNumber().intValue(); 218 if (numColumnsSpanned < 1) { 219 numColumnsSpanned = 1; 220 } 221 this.numRowsSpanned = 222 this.properties.get("number-rows-spanned").getNumber().intValue(); 223 if (numRowsSpanned < 1) { 224 numRowsSpanned = 1; 225 } 226 227 this.id = this.properties.get("id").getString(); 228 229 bSepBorders = (this.properties.get("border-collapse").getEnum() 230 == BorderCollapse.SEPARATE); 231 232 calcBorders(propMgr.getBorderAndPadding()); 233 234 verticalAlign = this.properties.get("display-align").getEnum(); 236 if (verticalAlign == DisplayAlign.AUTO) { 237 bRelativeAlign = true; 239 verticalAlign = this.properties.get("relative-align").getEnum(); 240 } else 241 bRelativeAlign = false; 243 this.minCellHeight = 244 this.properties.get("height").getLength().mvalue(); 245 } 246 247 248 public int layout(Area area) throws FOPException { 249 int originalAbsoluteHeight = area.getAbsoluteHeight(); 250 if (this.marker == BREAK_AFTER) { 251 return Status.OK; 252 } 253 254 if (this.marker == START) { 255 259 262 try { 263 area.getIDReferences().createID(id); 264 } 265 catch(FOPException e) { 266 if (!e.isLocationSet()) { 267 e.setLocation(systemId, line, column); 268 } 269 throw e; 270 } 271 272 this.marker = 0; 273 this.bDone=false; 274 } 275 276 281 282 if (marker == 0) { 283 area.getIDReferences().configureID(id, area); 285 } 286 287 int spaceLeft = area.spaceLeft() - m_borderSeparation; 289 this.cellArea = 292 new AreaContainer(propMgr.getFontState(area.getFontInfo()), 293 startOffset + startAdjust, beforeOffset, 294 width - widthAdjust, spaceLeft, 295 Position.RELATIVE); 296 297 cellArea.foCreator = this; cellArea.setPage(area.getPage()); 299 cellArea.setParent(area); 300 try { 301 cellArea.setBorderAndPadding((BorderAndPadding) 302 propMgr.getBorderAndPadding().clone()); 303 } catch (CloneNotSupportedException e) { 304 System.err.println("Can't clone BorderAndPadding: " + e) ; 305 cellArea.setBorderAndPadding(propMgr.getBorderAndPadding()); 306 } 307 cellArea.setBackground(propMgr.getBackgroundProps()); 308 cellArea.start(); 309 310 cellArea.setAbsoluteHeight(area.getAbsoluteHeight()); cellArea.setIDReferences(area.getIDReferences()); 312 cellArea.setTableCellXOffset(startOffset + startAdjust); 314 315 int numChildren = this.children.size(); 316 for (int i = this.marker; bDone==false && i < numChildren; i++) { 317 FObj fo = (FObj)children.get(i); 318 fo.setIsInTableCell(); 319 fo.forceWidth(width); 321 this.marker = i; 324 325 int status; 326 if (Status.isIncomplete((status = fo.layout(cellArea)))) { 327 if ((i == 0) && (status == Status.AREA_FULL_NONE)) { 329 return Status.AREA_FULL_NONE; 330 } else { 331 area.addChild(cellArea); 333 return Status.AREA_FULL_SOME; 335 } 336 } 337 338 area.setMaxHeight(area.getMaxHeight() - spaceLeft 339 + this.cellArea.getMaxHeight()); 340 } 341 this.bDone=true; 342 cellArea.end(); 343 area.addChild(cellArea); 344 345 if (minCellHeight > cellArea.getContentHeight()) { 347 cellArea.setHeight(minCellHeight); 348 } 349 350 height = cellArea.getHeight(); 354 top = cellArea.getCurrentYPosition(); 356 362 return Status.OK; 363 } 364 365 373 public int getHeight() { 374 return cellArea.getHeight() + m_borderSeparation - borderHeight; 375 } 376 377 384 public void setRowHeight(int h) { 385 int delta = h - getHeight(); 386 if (bRelativeAlign) { 388 cellArea.increaseHeight(delta); 392 } else if (delta > 0) { 393 BorderAndPadding cellBP = cellArea.getBorderAndPadding(); 394 switch (verticalAlign) { 395 case DisplayAlign.CENTER: 396 cellArea.shiftYPosition(delta / 2); 399 cellBP.setPaddingLength(BorderAndPadding.TOP, 400 cellBP.getPaddingTop(false) 401 + delta / 2); 402 cellBP.setPaddingLength(BorderAndPadding.BOTTOM, 403 cellBP.getPaddingBottom(false) 404 + delta - delta / 2); 405 break; 406 case DisplayAlign.AFTER: 407 cellBP.setPaddingLength(BorderAndPadding.TOP, 410 cellBP.getPaddingTop(false) + delta); 411 cellArea.shiftYPosition(delta); 412 break; 413 case DisplayAlign.BEFORE: 414 cellBP.setPaddingLength(BorderAndPadding.BOTTOM, 416 cellBP.getPaddingBottom(false) 417 + delta); 418 419 default: break; 421 } 422 } 423 } 424 425 429 private void calcBorders(BorderAndPadding bp) { 430 if (this.bSepBorders) { 431 439 int iSep = 440 properties.get("border-separation.inline-progression-direction").getLength().mvalue(); 441 int iSpacing = 443 properties.get("border-spacing.inline-progression-direction").getLength().mvalue(); 444 if (iSpacing > iSep) 445 iSep = iSpacing; 446 this.startAdjust = iSep / 2 + bp.getBorderLeftWidth(false) 447 + bp.getPaddingLeft(false); 448 452 this.widthAdjust = startAdjust + iSep - iSep / 2 453 + bp.getBorderRightWidth(false) 454 + bp.getPaddingRight(false); 455 m_borderSeparation = 458 properties.get("border-separation.block-progression-direction").getLength().mvalue(); 459 int m_borderSpacing = 460 properties.get("border-spacing.block-progression-direction").getLength().mvalue(); 461 if (m_borderSpacing > m_borderSeparation) 462 m_borderSeparation = m_borderSpacing; 463 this.beforeOffset = m_borderSeparation / 2 464 + bp.getBorderTopWidth(false) 465 + bp.getPaddingTop(false); 466 468 } else { 469 476 477 481 501 502 509 516 517 518 519 int borderStart = bp.getBorderLeftWidth(false); 520 int borderEnd = bp.getBorderRightWidth(false); 521 int borderBefore = bp.getBorderTopWidth(false); 522 int borderAfter = bp.getBorderBottomWidth(false); 523 524 this.startAdjust = borderStart / 2 + bp.getPaddingLeft(false); 525 526 this.widthAdjust = startAdjust + borderEnd / 2 527 + bp.getPaddingRight(false); 528 this.beforeOffset = borderBefore / 2 + bp.getPaddingTop(false); 529 this.borderHeight = (borderBefore + borderAfter) / 2; 531 } 532 } 533 534 535 } 536 | Popular Tags |