1 50 51 package com.lowagie.text.pdf; 52 53 import java.awt.Color ; 54 55 import com.lowagie.text.DocumentException; 56 import com.lowagie.text.Element; 57 import com.lowagie.text.ExceptionConverter; 58 import com.lowagie.text.Image; 59 import com.lowagie.text.Rectangle; 60 61 66 67 public class PdfPRow { 68 69 70 public static final float BOTTOM_LIMIT = -(1 << 30); 71 72 protected PdfPCell cells[]; 73 74 protected float widths[]; 75 76 protected float maxHeight = 0; 77 78 protected boolean calculated = false; 79 80 private int[] canvasesPos; 81 82 86 public PdfPRow(PdfPCell cells[]) { 87 this.cells = cells; 88 widths = new float[cells.length]; 89 } 90 91 95 public PdfPRow(PdfPRow row) { 96 maxHeight = row.maxHeight; 97 calculated = row.calculated; 98 cells = new PdfPCell[row.cells.length]; 99 for (int k = 0; k < cells.length; ++k) { 100 if (row.cells[k] != null) 101 cells[k] = new PdfPCell(row.cells[k]); 102 } 103 widths = new float[cells.length]; 104 System.arraycopy(row.widths, 0, widths, 0, cells.length); 105 } 106 107 112 public boolean setWidths(float widths[]) { 113 if (widths.length != cells.length) 114 return false; 115 System.arraycopy(widths, 0, this.widths, 0, cells.length); 116 float total = 0; 117 calculated = false; 118 for (int k = 0; k < widths.length; ++k) { 119 PdfPCell cell = cells[k]; 120 cell.setLeft(total); 121 int last = k + cell.getColspan(); 122 for (; k < last; ++k) 123 total += widths[k]; 124 --k; 125 cell.setRight(total); 126 cell.setTop(0); 127 } 128 return true; 129 } 130 131 135 public float calculateHeights() { 136 maxHeight = 0; 137 for (int k = 0; k < cells.length; ++k) { 138 PdfPCell cell = cells[k]; 139 if (cell == null) 140 continue; 141 Image img = cell.getImage(); 142 if (img != null) { 143 img.scalePercent(100); 144 float refWidth = img.getScaledWidth(); 145 if (cell.getRotation() == 90 || cell.getRotation() == 270) { 146 refWidth = img.getScaledHeight(); 147 } 148 float scale = (cell.getRight() - cell.getEffectivePaddingRight() 149 - cell.getEffectivePaddingLeft() - cell.getLeft()) 150 / refWidth; 151 img.scalePercent(scale * 100); 152 float refHeight = img.getScaledHeight(); 153 if (cell.getRotation() == 90 || cell.getRotation() == 270) { 154 refHeight = img.getScaledWidth(); 155 } 156 cell.setBottom(cell.getTop() - cell.getEffectivePaddingTop() 157 - cell.getEffectivePaddingBottom() 158 - refHeight); 159 } else { 160 if (cell.getRotation() == 0 || cell.getRotation() == 180) { 161 float rightLimit = cell.isNoWrap() ? 20000 : cell.getRight() 162 - cell.getEffectivePaddingRight(); 163 float bry = (cell.getFixedHeight() > 0) ? cell.getTop() 164 - cell.getEffectivePaddingTop() 165 + cell.getEffectivePaddingBottom() 166 - cell.getFixedHeight() : BOTTOM_LIMIT; 167 ColumnText ct = ColumnText.duplicate(cell.getColumn()); 168 setColumn(ct, 169 cell.getLeft() + cell.getEffectivePaddingLeft(), bry, 170 rightLimit, cell.getTop() - cell.getEffectivePaddingTop()); 171 try { 172 ct.go(true); 173 } catch (DocumentException e) { 174 throw new ExceptionConverter(e); 175 } 176 float yLine = ct.getYLine(); 177 if (cell.isUseDescender()) 178 yLine += ct.getDescender(); 179 cell.setBottom(yLine - cell.getEffectivePaddingBottom()); 180 } 181 else { 182 if (cell.getFixedHeight() > 0) { 183 cell.setBottom(cell.getTop() - cell.getFixedHeight()); 184 } 185 else { 186 ColumnText ct = ColumnText.duplicate(cell.getColumn()); 187 setColumn(ct, 0, cell.getLeft() + cell.getEffectivePaddingLeft(), 188 20000, cell.getRight() - cell.getEffectivePaddingRight()); 189 try { 190 ct.go(true); 191 } catch (DocumentException e) { 192 throw new ExceptionConverter(e); 193 } 194 cell.setBottom(cell.getTop() - cell.getEffectivePaddingTop() 195 - cell.getEffectivePaddingBottom() - ct.getFilledWidth()); 196 } 197 } 198 } 199 float height = cell.getFixedHeight(); 200 if (height <= 0) 201 height = cell.getHeight(); 202 if (height < cell.getFixedHeight()) 203 height = cell.getFixedHeight(); 204 else if (height < cell.getMinimumHeight()) 205 height = cell.getMinimumHeight(); 206 if (height > maxHeight) 207 maxHeight = height; 208 } 209 calculated = true; 210 return maxHeight; 211 } 212 213 220 public void writeBorderAndBackground(float xPos, float yPos, PdfPCell cell, 221 PdfContentByte[] canvases) { 222 PdfContentByte lines = canvases[PdfPTable.LINECANVAS]; 223 PdfContentByte backgr = canvases[PdfPTable.BACKGROUNDCANVAS]; 224 float x1 = cell.getLeft() + xPos; 226 float y2 = cell.getTop() + yPos; 227 float x2 = cell.getRight() + xPos; 228 float y1 = y2 - maxHeight; 229 230 Color background = cell.getBackgroundColor(); 232 if (background != null) { 233 backgr.setColorFill(background); 234 backgr.rectangle(x1, y1, x2 - x1, y2 - y1); 235 backgr.fill(); 236 } 237 if (cell.hasBorders()) { 239 if (cell.isUseVariableBorders()) { 240 Rectangle borderRect = new Rectangle(cell.getLeft() + xPos, cell 241 .getTop() 242 - maxHeight + yPos, cell.getRight() + xPos, cell.getTop() 243 + yPos); 244 borderRect.cloneNonPositionParameters(cell); 245 borderRect.setBackgroundColor(null); 246 lines.rectangle(borderRect); 247 } else { 248 if (cell.getBorderWidth() != Rectangle.UNDEFINED) { 250 lines.setLineWidth(cell.getBorderWidth()); 251 } 252 Color color = cell.getBorderColor(); 254 if (color != null) { 255 lines.setColorStroke(color); 256 } 257 258 if (cell.hasBorder(Rectangle.BOX)) { 260 lines.rectangle(x1, y1, x2 - x1, y2 - y1); 261 } 262 else { 265 if (cell.hasBorder(Rectangle.RIGHT)) { 266 lines.moveTo(x2, y1); 267 lines.lineTo(x2, y2); 268 } 269 if (cell.hasBorder(Rectangle.LEFT)) { 270 lines.moveTo(x1, y1); 271 lines.lineTo(x1, y2); 272 } 273 if (cell.hasBorder(Rectangle.BOTTOM)) { 274 lines.moveTo(x1, y1); 275 lines.lineTo(x2, y1); 276 } 277 if (cell.hasBorder(Rectangle.TOP)) { 278 lines.moveTo(x1, y2); 279 lines.lineTo(x2, y2); 280 } 281 } 282 lines.stroke(); 283 if (color != null) { 284 lines.resetRGBColorStroke(); 285 } 286 } 287 } 288 } 289 290 private void saveAndRotateCanvases(PdfContentByte[] canvases, float a, float b, float c, float d, float e, float f) { 291 int last = PdfPTable.TEXTCANVAS + 1; 292 if (canvasesPos == null) { 293 canvasesPos = new int[last * 2]; 294 } 295 for (int k = 0; k < last; ++k) { 296 ByteBuffer bb = canvases[k].getInternalBuffer(); 297 canvasesPos[k * 2] = bb.size(); 298 canvases[k].saveState(); 299 canvases[k].concatCTM(a, b, c, d, e, f); 300 canvasesPos[k * 2 + 1] = bb.size(); 301 } 302 } 303 304 private void restoreCanvases(PdfContentByte[] canvases) { 305 int last = PdfPTable.TEXTCANVAS + 1; 306 for (int k = 0; k < last; ++k) { 307 ByteBuffer bb = canvases[k].getInternalBuffer(); 308 int p1 = bb.size(); 309 canvases[k].restoreState(); 310 if (p1 == canvasesPos[k * 2 + 1]) 311 bb.setSize(canvasesPos[k * 2]); 312 } 313 } 314 315 private float setColumn(ColumnText ct, float llx, float lly, float urx, float ury) { 316 if (llx > urx) 317 urx = llx; 318 if (lly > ury) 319 ury = lly; 320 ct.setSimpleColumn(llx, lly, urx, ury); 321 return ury; 322 } 323 324 332 public void writeCells(int colStart, int colEnd, float xPos, float yPos, 333 PdfContentByte[] canvases) { 334 if (!calculated) 335 calculateHeights(); 336 if (colEnd < 0) 337 colEnd = cells.length; 338 colEnd = Math.min(colEnd, cells.length); 339 if (colStart < 0) 340 colStart = 0; 341 if (colStart >= colEnd) 342 return; 343 int newStart; 344 for (newStart = colStart; newStart >= 0; --newStart) { 345 if (cells[newStart] != null) 346 break; 347 xPos -= widths[newStart - 1]; 348 } 349 xPos -= cells[newStart].getLeft(); 350 for (int k = newStart; k < colEnd; ++k) { 351 PdfPCell cell = cells[k]; 352 if (cell == null) 353 continue; 354 writeBorderAndBackground(xPos, yPos, cell, canvases); 355 Image img = cell.getImage(); 356 float tly = 0; 357 switch (cell.getVerticalAlignment()) { 358 case Element.ALIGN_BOTTOM: 359 tly = cell.getTop() + yPos - maxHeight + cell.getHeight() 360 - cell.getEffectivePaddingTop(); 361 break; 362 case Element.ALIGN_MIDDLE: 363 tly = cell.getTop() + yPos + (cell.getHeight() - maxHeight) / 2 364 - cell.getEffectivePaddingTop(); 365 break; 366 default: 367 tly = cell.getTop() + yPos - cell.getEffectivePaddingTop(); 368 break; 369 } 370 if (img != null) { 371 if (cell.getRotation() != 0) { 372 img = Image.getInstance(img); 373 img.setRotation(img.getImageRotation() + (float)(cell.getRotation() * Math.PI / 180.0)); 374 } 375 boolean vf = false; 376 if (cell.getHeight() > maxHeight) { 377 img.scalePercent(100); 378 float scale = (maxHeight - cell.getEffectivePaddingTop() - cell 379 .getEffectivePaddingBottom()) 380 / img.getScaledHeight(); 381 img.scalePercent(scale * 100); 382 vf = true; 383 } 384 float left = cell.getLeft() + xPos 385 + cell.getEffectivePaddingLeft(); 386 if (vf) { 387 switch (cell.getHorizontalAlignment()) { 388 case Element.ALIGN_CENTER: 389 left = xPos 390 + (cell.getLeft() + cell.getEffectivePaddingLeft() 391 + cell.getRight() 392 - cell.getEffectivePaddingRight() - img 393 .getScaledWidth()) / 2; 394 break; 395 case Element.ALIGN_RIGHT: 396 left = xPos + cell.getRight() 397 - cell.getEffectivePaddingRight() 398 - img.getScaledWidth(); 399 break; 400 default: 401 break; 402 } 403 tly = cell.getTop() + yPos - cell.getEffectivePaddingTop(); 404 } 405 img.setAbsolutePosition(left, tly - img.getScaledHeight()); 406 try { 407 canvases[PdfPTable.TEXTCANVAS].addImage(img); 408 } catch (DocumentException e) { 409 throw new ExceptionConverter(e); 410 } 411 } else { 412 if (cell.getRotation() == 90 || cell.getRotation() == 270) { 414 float netWidth = maxHeight - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom(); 415 float netHeight = cell.getWidth() - cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight(); 416 ColumnText ct = ColumnText.duplicate(cell.getColumn()); 417 ct.setCanvases(canvases); 418 ct.setSimpleColumn(0, 0, netWidth + 0.001f, -netHeight); 419 try { 420 ct.go(true); 421 } catch (DocumentException e) { 422 throw new ExceptionConverter(e); 423 } 424 float calcHeight = -ct.getYLine(); 425 if (netWidth <= 0 || netHeight <= 0) 426 calcHeight = 0; 427 if (calcHeight > 0) { 428 if (cell.isUseDescender()) 429 calcHeight -= ct.getDescender(); 430 ct = ColumnText.duplicate(cell.getColumn()); 431 ct.setCanvases(canvases); 432 ct.setSimpleColumn(0, -0.001f, netWidth + 0.001f, calcHeight); 433 float pivotX; 434 float pivotY; 435 if (cell.getRotation() == 90) { 436 pivotY = cell.getTop() + yPos - maxHeight + cell.getEffectivePaddingBottom(); 437 switch (cell.getVerticalAlignment()) { 438 case Element.ALIGN_BOTTOM: 439 pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight(); 440 break; 441 case Element.ALIGN_MIDDLE: 442 pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() + calcHeight) / 2; 443 break; 444 default: pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft() + calcHeight; 446 break; 447 } 448 saveAndRotateCanvases(canvases, 0,1,-1,0,pivotX,pivotY); 449 } 450 else { 451 pivotY = cell.getTop() + yPos - cell.getEffectivePaddingTop(); 452 switch (cell.getVerticalAlignment()) { 453 case Element.ALIGN_BOTTOM: 454 pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft(); 455 break; 456 case Element.ALIGN_MIDDLE: 457 pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() - calcHeight) / 2; 458 break; 459 default: pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight() - calcHeight; 461 break; 462 } 463 saveAndRotateCanvases(canvases, 0,-1,1,0,pivotX,pivotY); 464 } 465 try { 466 ct.go(); 467 } catch (DocumentException e) { 468 throw new ExceptionConverter(e); 469 } finally { 470 restoreCanvases(canvases); 471 } 472 } 473 } 474 else { 475 float fixedHeight = cell.getFixedHeight(); 476 float rightLimit = cell.getRight() + xPos 477 - cell.getEffectivePaddingRight(); 478 float leftLimit = cell.getLeft() + xPos 479 + cell.getEffectivePaddingLeft(); 480 if (cell.isNoWrap()) { 481 switch (cell.getHorizontalAlignment()) { 482 case Element.ALIGN_CENTER: 483 rightLimit += 10000; 484 leftLimit -= 10000; 485 break; 486 case Element.ALIGN_RIGHT: 487 leftLimit -= 20000; 488 break; 489 default: 490 rightLimit += 20000; 491 break; 492 } 493 } 494 ColumnText ct = ColumnText.duplicate(cell.getColumn()); 495 ct.setCanvases(canvases); 496 float bry = tly 497 - (maxHeight 498 - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom()); 499 if (fixedHeight > 0) { 500 if (cell.getHeight() > maxHeight) { 501 tly = cell.getTop() + yPos - cell.getEffectivePaddingTop(); 502 bry = cell.getTop() + yPos - maxHeight + cell.getEffectivePaddingBottom(); 503 } 504 } 505 if (tly > bry && leftLimit < rightLimit) { 506 ct.setSimpleColumn(leftLimit, bry - 0.001f, rightLimit, tly); 507 if (cell.getRotation() == 180) { 508 float shx = leftLimit + rightLimit; 509 float shy = yPos + yPos - maxHeight + cell.getEffectivePaddingBottom() - cell.getEffectivePaddingTop(); 510 saveAndRotateCanvases(canvases, -1,0,0,-1,shx,shy); 511 } 512 try { 513 ct.go(); 514 } catch (DocumentException e) { 515 throw new ExceptionConverter(e); 516 } finally { 517 if (cell.getRotation() == 180) { 518 restoreCanvases(canvases); 519 } 520 } 521 } 522 } 523 } 524 PdfPCellEvent evt = cell.getCellEvent(); 525 if (evt != null) { 526 Rectangle rect = new Rectangle(cell.getLeft() + xPos, cell.getTop() 527 + yPos - maxHeight, cell.getRight() + xPos, cell.getTop() 528 + yPos); 529 evt.cellLayout(cell, rect, canvases); 530 } 531 } 532 } 533 534 538 public boolean isCalculated() { 539 return calculated; 540 } 541 542 546 public float getMaxHeights() { 547 if (calculated) 548 return maxHeight; 549 else 550 return calculateHeights(); 551 } 552 553 558 public void setMaxHeights(float maxHeight) { 559 this.maxHeight = maxHeight; 560 } 561 562 564 float[] getEventWidth(float xPos) { 565 int n = 0; 566 for (int k = 0; k < cells.length; ++k) { 567 if (cells[k] != null) 568 ++n; 569 } 570 float width[] = new float[n + 1]; 571 n = 0; 572 width[n++] = xPos; 573 for (int k = 0; k < cells.length; ++k) { 574 if (cells[k] != null) { 575 width[n] = width[n - 1] + cells[k].getWidth(); 576 ++n; 577 } 578 } 579 return width; 580 } 581 582 592 public PdfPRow splitRow(float newHeight) { 593 PdfPCell newCells[] = new PdfPCell[cells.length]; 594 float fh[] = new float[cells.length * 2]; 595 boolean allEmpty = true; 596 for (int k = 0; k < cells.length; ++k) { 597 PdfPCell cell = cells[k]; 598 if (cell == null) 599 continue; 600 fh[k * 2] = cell.getFixedHeight(); 601 fh[k * 2 + 1] = cell.getMinimumHeight(); 602 Image img = cell.getImage(); 603 PdfPCell c2 = new PdfPCell(cell); 604 if (img != null) { 605 if (newHeight > cell.getEffectivePaddingBottom() 606 + cell.getEffectivePaddingTop() + 2) { 607 c2.setPhrase(null); 608 allEmpty = false; 609 } 610 } else { 611 int status; 612 float y; 613 ColumnText ct = ColumnText.duplicate(cell.getColumn()); 614 if (cell.getRotation() == 90 || cell.getRotation() == 270) { 615 y = setColumn(ct, 616 cell.getTop() - newHeight + cell.getEffectivePaddingBottom(), 617 cell.getLeft() + cell.getEffectivePaddingLeft(), 618 cell.getTop() - cell.getEffectivePaddingTop(), 619 cell.getRight() - cell.getEffectivePaddingRight()); 620 } 621 else { 622 float rightLimit = cell.isNoWrap() ? 20000 : cell.getRight() 623 - cell.getEffectivePaddingRight(); 624 float y1 = cell.getTop() - newHeight 625 + cell.getEffectivePaddingBottom(); 626 float y2 = cell.getTop() - cell.getEffectivePaddingTop(); 627 y = setColumn(ct, 628 cell.getLeft() + cell.getEffectivePaddingLeft(), y1, 629 rightLimit, y2); 630 } 631 try { 632 status = ct.go(true); 633 } catch (DocumentException e) { 634 throw new ExceptionConverter(e); 635 } 636 boolean thisEmpty = (ct.getYLine() == y); 637 if (thisEmpty) 638 ct = ColumnText.duplicate(cell.getColumn()); 639 allEmpty = (allEmpty && thisEmpty); 640 if ((status & ColumnText.NO_MORE_TEXT) == 0 || thisEmpty) { 641 c2.setColumn(ct); 642 ct.setFilledWidth(0); 643 } else { 644 c2.setPhrase(null); 645 } 646 } 647 newCells[k] = c2; 648 cell.setFixedHeight(newHeight); 649 } 650 if (allEmpty) { 651 for (int k = 0; k < cells.length; ++k) { 652 PdfPCell cell = cells[k]; 653 if (cell == null) 654 continue; 655 float f = fh[k * 2]; 656 float m = fh[k * 2 + 1]; 657 if (f <= 0) 658 cell.setMinimumHeight(m); 659 else 660 cell.setFixedHeight(f); 661 } 662 return null; 663 } 664 calculateHeights(); 665 PdfPRow split = new PdfPRow(newCells); 666 split.widths = (float[]) widths.clone(); 667 split.calculateHeights(); 668 return split; 669 } 670 } | Popular Tags |