001/* 002 * $Id: PdfPCell.java 4923 2011-07-05 15:13:19Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf; 045 046import java.util.List; 047 048import com.itextpdf.text.Chunk; 049import com.itextpdf.text.DocumentException; 050import com.itextpdf.text.Element; 051import com.itextpdf.text.ExceptionConverter; 052import com.itextpdf.text.Image; 053import com.itextpdf.text.Phrase; 054import com.itextpdf.text.Rectangle; 055import com.itextpdf.text.error_messages.MessageLocalization; 056import com.itextpdf.text.pdf.events.PdfPCellEventForwarder; 057 058/** 059 * A cell in a PdfPTable. 060 */ 061 062public class PdfPCell extends Rectangle{ 063 064 private ColumnText column = new ColumnText(null); 065 066 /** Vertical alignment of the cell. */ 067 private int verticalAlignment = Element.ALIGN_TOP; 068 069 /** Left padding of the cell. */ 070 private float paddingLeft = 2; 071 072 /** Right padding of the cell. */ 073 private float paddingRight = 2; 074 075 /** Top padding of the cell. */ 076 private float paddingTop = 2; 077 078 /** Bottom padding of the cell. */ 079 private float paddingBottom = 2; 080 081 /** Fixed height of the cell. */ 082 private float fixedHeight = 0; 083 084 /** Minimum height of the cell. */ 085 private float minimumHeight; 086 087 /** Holds value of property noWrap. */ 088 private boolean noWrap = false; 089 090 /** Holds value of property table. */ 091 private PdfPTable table; 092 093 /** Holds value of property colspan. */ 094 private int colspan = 1; 095 096 /** 097 * Holds value of property rowspan. 098 * @since 2.1.6 099 */ 100 private int rowspan = 1; 101 102 /** Holds value of property image. */ 103 private Image image; 104 105 /** Holds value of property cellEvent. */ 106 private PdfPCellEvent cellEvent; 107 108 /** Holds value of property useDescender. */ 109 private boolean useDescender = true; 110 111 /** Increases padding to include border if true */ 112 private boolean useBorderPadding = false; 113 114 /** The text in the cell. */ 115 protected Phrase phrase; 116 117 /** 118 * The rotation of the cell. Possible values are 119 * 0, 90, 180 and 270. 120 */ 121 private int rotation; 122 123 /** 124 * Constructs an empty <CODE>PdfPCell</CODE>. 125 * The default padding is 2. 126 */ 127 public PdfPCell() { 128 super(0, 0, 0, 0); 129 borderWidth = 0.5f; 130 border = BOX; 131 column.setLeading(0, 1); 132 column.setUseAscender(true); 133 } 134 135 /** 136 * Constructs a <CODE>PdfPCell</CODE> with a <CODE>Phrase</CODE>. 137 * The default padding is 2. 138 * 139 * @param phrase the text 140 */ 141 public PdfPCell(Phrase phrase) { 142 super(0, 0, 0, 0); 143 borderWidth = 0.5f; 144 border = BOX; 145 column.addText(this.phrase = phrase); 146 column.setLeading(0, 1); 147 column.setUseAscender(true); 148 } 149 150 /** 151 * Constructs a <CODE>PdfPCell</CODE> with an <CODE>Image</CODE>. 152 * The default padding is 0. 153 * 154 * @param image the <CODE>Image</CODE> 155 */ 156 public PdfPCell(Image image) { 157 this(image, false); 158 } 159 160 /** 161 * Constructs a <CODE>PdfPCell</CODE> with an <CODE>Image</CODE>. 162 * The default padding is 0.25 for a border width of 0.5. 163 * 164 * @param image the <CODE>Image</CODE> 165 * @param fit <CODE>true</CODE> to fit the image to the cell 166 */ 167 public PdfPCell(Image image, boolean fit) { 168 super(0, 0, 0, 0); 169 borderWidth = 0.5f; 170 border = BOX; 171 if (fit) { 172 this.image = image; 173 column.setLeading(0, 1); 174 setPadding(borderWidth / 2); 175 } 176 else { 177 column.addText(this.phrase = new Phrase(new Chunk(image, 0, 0, true))); 178 column.setLeading(0, 1); 179 setPadding(0); 180 } 181 } 182 183 /** 184 * Constructs a <CODE>PdfPCell</CODE> with a <CODE>PdfPtable</CODE>. 185 * This constructor allows nested tables. 186 * The default padding is 0. 187 * 188 * @param table The <CODE>PdfPTable</CODE> 189 */ 190 public PdfPCell(PdfPTable table) { 191 this(table, null); 192 } 193 194 /** 195 * Constructs a <CODE>PdfPCell</CODE> with a <CODE>PdfPtable</CODE>. 196 * This constructor allows nested tables. 197 * 198 * @param table The <CODE>PdfPTable</CODE> 199 * @param style The style to apply to the cell (you could use getDefaultCell()) 200 * @since 2.1.0 201 */ 202 public PdfPCell(PdfPTable table, PdfPCell style) { 203 super(0, 0, 0, 0); 204 borderWidth = 0.5f; 205 border = BOX; 206 column.setLeading(0, 1); 207 this.table = table; 208 table.setWidthPercentage(100); 209 table.setExtendLastRow(true); 210 column.addElement(table); 211 if (style != null) { 212 cloneNonPositionParameters(style); 213 verticalAlignment = style.verticalAlignment; 214 paddingLeft = style.paddingLeft; 215 paddingRight = style.paddingRight; 216 paddingTop = style.paddingTop; 217 paddingBottom = style.paddingBottom; 218 colspan = style.colspan; 219 rowspan = style.rowspan; 220 cellEvent = style.cellEvent; 221 useDescender = style.useDescender; 222 useBorderPadding = style.useBorderPadding; 223 rotation = style.rotation; 224 } 225 else 226 setPadding(0); 227 } 228 229 /** 230 * Constructs a deep copy of a <CODE>PdfPCell</CODE>. 231 * 232 * @param cell the <CODE>PdfPCell</CODE> to duplicate 233 */ 234 public PdfPCell(PdfPCell cell) { 235 super(cell.llx, cell.lly, cell.urx, cell.ury); 236 cloneNonPositionParameters(cell); 237 verticalAlignment = cell.verticalAlignment; 238 paddingLeft = cell.paddingLeft; 239 paddingRight = cell.paddingRight; 240 paddingTop = cell.paddingTop; 241 paddingBottom = cell.paddingBottom; 242 phrase = cell.phrase; 243 fixedHeight = cell.fixedHeight; 244 minimumHeight = cell.minimumHeight; 245 noWrap = cell.noWrap; 246 colspan = cell.colspan; 247 rowspan = cell.rowspan; 248 if (cell.table != null) 249 table = new PdfPTable(cell.table); 250 image = Image.getInstance(cell.image); 251 cellEvent = cell.cellEvent; 252 useDescender = cell.useDescender; 253 column = ColumnText.duplicate(cell.column); 254 useBorderPadding = cell.useBorderPadding; 255 rotation = cell.rotation; 256 } 257 258 /** 259 * Adds an iText element to the cell. 260 * 261 * @param element 262 */ 263 public void addElement(Element element) { 264 if (table != null) { 265 table = null; 266 column.setText(null); 267 } 268 column.addElement(element); 269 } 270 271 /** 272 * Gets the <CODE>Phrase</CODE> from this cell. 273 * 274 * @return the <CODE>Phrase</CODE> 275 */ 276 public Phrase getPhrase() { 277 return phrase; 278 } 279 280 /** 281 * Sets the <CODE>Phrase</CODE> for this cell. 282 * 283 * @param phrase the <CODE>Phrase</CODE> 284 */ 285 public void setPhrase(Phrase phrase) { 286 table = null; 287 image = null; 288 column.setText(this.phrase = phrase); 289 } 290 291 /** 292 * Gets the horizontal alignment for the cell. 293 * 294 * @return the horizontal alignment for the cell 295 */ 296 public int getHorizontalAlignment() { 297 return column.getAlignment(); 298 } 299 300 /** 301 * Sets the horizontal alignment for the cell. It could be 302 * <CODE>Element.ALIGN_CENTER</CODE> for example. 303 * 304 * @param horizontalAlignment The horizontal alignment 305 */ 306 public void setHorizontalAlignment(int horizontalAlignment) { 307 column.setAlignment(horizontalAlignment); 308 } 309 310 /** 311 * Gets the vertical alignment for the cell. 312 * 313 * @return the vertical alignment for the cell 314 */ 315 public int getVerticalAlignment() { 316 return verticalAlignment; 317 } 318 319 /** 320 * Sets the vertical alignment for the cell. It could be 321 * <CODE>Element.ALIGN_MIDDLE</CODE> for example. 322 * 323 * @param verticalAlignment The vertical alignment 324 */ 325 public void setVerticalAlignment(int verticalAlignment) { 326 if (table != null) 327 table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP); 328 this.verticalAlignment = verticalAlignment; 329 } 330 331 /** 332 * Gets the effective left padding. 333 * This will include the left border width if 334 * {@link #isUseBorderPadding()} is true. 335 * 336 * @return effective value of property paddingLeft. 337 */ 338 public float getEffectivePaddingLeft() { 339 if (isUseBorderPadding()) { 340 float border = getBorderWidthLeft() / (isUseVariableBorders() ? 1f : 2f); 341 return paddingLeft + border; 342 } 343 return paddingLeft; 344 } 345 346 /** 347 * @return Value of property paddingLeft. 348 */ 349 public float getPaddingLeft() { 350 return paddingLeft; 351 } 352 353 /** 354 * Setter for property paddingLeft. 355 * 356 * @param paddingLeft New value of property paddingLeft. 357 */ 358 public void setPaddingLeft(float paddingLeft) { 359 this.paddingLeft = paddingLeft; 360 } 361 362 /** 363 * Gets the effective right padding. This will include 364 * the right border width if {@link #isUseBorderPadding()} is true. 365 * 366 * @return effective value of property paddingRight. 367 */ 368 public float getEffectivePaddingRight() { 369 if (isUseBorderPadding()) { 370 float border = getBorderWidthRight() / (isUseVariableBorders() ? 1f : 2f); 371 return paddingRight + border; 372 } 373 return paddingRight; 374 } 375 376 /** 377 * Getter for property paddingRight. 378 * 379 * @return Value of property paddingRight. 380 */ 381 public float getPaddingRight() { 382 return paddingRight; 383 } 384 385 /** 386 * Setter for property paddingRight. 387 * 388 * @param paddingRight New value of property paddingRight. 389 */ 390 public void setPaddingRight(float paddingRight) { 391 this.paddingRight = paddingRight; 392 } 393 394 /** 395 * Gets the effective top padding. This will include 396 * the top border width if {@link #isUseBorderPadding()} is true. 397 * 398 * @return effective value of property paddingTop. 399 */ 400 public float getEffectivePaddingTop() { 401 if (isUseBorderPadding()) { 402 float border = getBorderWidthTop()/(isUseVariableBorders()?1f:2f); 403 return paddingTop + border; 404 } 405 return paddingTop; 406 } 407 408 /** 409 * Getter for property paddingTop. 410 * 411 * @return Value of property paddingTop. 412 */ 413 public float getPaddingTop() { 414 return paddingTop; 415 } 416 417 /** 418 * Setter for property paddingTop. 419 * 420 * @param paddingTop New value of property paddingTop. 421 */ 422 public void setPaddingTop(float paddingTop) { 423 this.paddingTop = paddingTop; 424 } 425 426 /** 427 * Gets the effective bottom padding. 428 * This will include the bottom border width if 429 * {@link #isUseBorderPadding()} is true. 430 * 431 * @return effective value of property paddingBottom. 432 */ 433 public float getEffectivePaddingBottom() { 434 if (isUseBorderPadding()) { 435 float border = getBorderWidthBottom()/(isUseVariableBorders()?1f:2f); 436 return paddingBottom + border; 437 } 438 return paddingBottom; 439 } 440 441 /** 442 * Getter for property paddingBottom. 443 * 444 * @return Value of property paddingBottom. 445 */ 446 public float getPaddingBottom() { 447 return paddingBottom; 448 } 449 450 /** 451 * Setter for property paddingBottom. 452 * 453 * @param paddingBottom New value of property paddingBottom. 454 */ 455 public void setPaddingBottom(float paddingBottom) { 456 this.paddingBottom = paddingBottom; 457 } 458 459 /** 460 * Sets the padding of the contents in the cell (space between content and border). 461 * 462 * @param padding 463 */ 464 public void setPadding(float padding) { 465 paddingBottom = padding; 466 paddingTop = padding; 467 paddingLeft = padding; 468 paddingRight = padding; 469 } 470 471 /** 472 * If true, then effective padding will include border widths 473 * 474 * @return true if effective padding includes border widths 475 */ 476 public boolean isUseBorderPadding() { 477 return useBorderPadding; 478 } 479 480 /** 481 * Adjusts effective padding to include border widths. 482 * 483 * @param use adjust effective padding if true 484 */ 485 public void setUseBorderPadding(boolean use) { 486 useBorderPadding = use; 487 } 488 489 /** 490 * Sets the leading fixed and variable. 491 * The resultant leading will be: 492 * fixedLeading+multipliedLeading*maxFontSize 493 * where maxFontSize is the size of the biggest font in the line. 494 * 495 * @param fixedLeading the fixed leading 496 * @param multipliedLeading the variable leading 497 */ 498 public void setLeading(float fixedLeading, float multipliedLeading) { 499 column.setLeading(fixedLeading, multipliedLeading); 500 } 501 502 /** 503 * Gets the fixed leading. 504 * 505 * @return the leading 506 */ 507 public float getLeading() { 508 return column.getLeading(); 509 } 510 511 /** 512 * Gets the variable leading. 513 * 514 * @return the leading 515 */ 516 public float getMultipliedLeading() { 517 return column.getMultipliedLeading(); 518 } 519 520 /** 521 * Sets the first paragraph line indent. 522 * 523 * @param indent the indent 524 */ 525 public void setIndent(float indent) { 526 column.setIndent(indent); 527 } 528 529 /** 530 * Gets the first paragraph line indent. 531 * 532 * @return the indent 533 */ 534 public float getIndent() { 535 return column.getIndent(); 536 } 537 538 /** 539 * Gets the extra space between paragraphs. 540 * 541 * @return the extra space between paragraphs 542 */ 543 public float getExtraParagraphSpace() { 544 return column.getExtraParagraphSpace(); 545 } 546 547 /** 548 * Sets the extra space between paragraphs. 549 * 550 * @param extraParagraphSpace the extra space between paragraphs 551 */ 552 public void setExtraParagraphSpace(float extraParagraphSpace) { 553 column.setExtraParagraphSpace(extraParagraphSpace); 554 } 555 556 /** 557 * Set a fixed height for the cell. 558 * This will automatically unset minimumHeight, if set. 559 * 560 * @param fixedHeight New value of property fixedHeight. 561 */ 562 public void setFixedHeight(float fixedHeight) { 563 this.fixedHeight = fixedHeight; 564 minimumHeight = 0; 565 } 566 567 /** 568 * Get the fixed height of the cell. 569 * 570 * @return Value of property fixedHeight. 571 */ 572 public float getFixedHeight() { 573 return fixedHeight; 574 } 575 576 /** 577 * Tells you whether the cell has a fixed height. 578 * 579 * @return true is a fixed height was set. 580 * @since 2.1.5 581 */ 582 public boolean hasFixedHeight() { 583 return getFixedHeight() > 0; 584 } 585 586 /** 587 * Set a minimum height for the cell. 588 * This will automatically unset fixedHeight, if set. 589 * 590 * @param minimumHeight New value of property minimumHeight. 591 */ 592 public void setMinimumHeight(float minimumHeight) { 593 this.minimumHeight = minimumHeight; 594 fixedHeight = 0; 595 } 596 597 /** 598 * Get the minimum height of the cell. 599 * 600 * @return Value of property minimumHeight. 601 */ 602 public float getMinimumHeight() { 603 return minimumHeight; 604 } 605 606 /** 607 * Tells you whether the cell has a minimum height. 608 * 609 * @return true if a minimum height was set. 610 * @since 2.1.5 611 */ 612 public boolean hasMinimumHeight() { 613 return getMinimumHeight() > 0; 614 } 615 616 /** 617 * Getter for property noWrap. 618 * 619 * @return Value of property noWrap. 620 */ 621 public boolean isNoWrap() { 622 return noWrap; 623 } 624 625 /** 626 * Setter for property noWrap. 627 * 628 * @param noWrap New value of property noWrap. 629 */ 630 public void setNoWrap(boolean noWrap) { 631 this.noWrap = noWrap; 632 } 633 634 /** 635 * Getter for property table. 636 * 637 * @return Value of property table. 638 * @since 2.x 639 */ 640 public PdfPTable getTable() { 641 return table; 642 } 643 644 void setTable(PdfPTable table) { 645 this.table = table; 646 column.setText(null); 647 image = null; 648 if (table != null) { 649 table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP); 650 column.addElement(table); 651 table.setWidthPercentage(100); 652 } 653 } 654 655 /** 656 * Getter for property colspan. 657 * 658 * @return Value of property colspan. 659 */ 660 public int getColspan() { 661 return colspan; 662 } 663 664 /** 665 * Setter for property colspan. 666 * 667 * @param colspan New value of property colspan. 668 */ 669 public void setColspan(int colspan) { 670 this.colspan = colspan; 671 } 672 673 /** 674 * Getter for property rowspan. 675 * 676 * @return Value of property rowspan. 677 * @since 2.1.6 678 */ 679 public int getRowspan() { 680 return rowspan; 681 } 682 683 /** 684 * Setter for property rowspan. 685 * 686 * @param rowspan New value of property rowspan. 687 * @since 2.1.6 688 */ 689 public void setRowspan(int rowspan) { 690 this.rowspan = rowspan; 691 } 692 693 /** 694 * Sets the following paragraph lines indent. 695 * 696 * @param indent the indent 697 */ 698 public void setFollowingIndent(float indent) { 699 column.setFollowingIndent(indent); 700 } 701 702 /** 703 * Gets the following paragraph lines indent. 704 * 705 * @return the indent 706 */ 707 public float getFollowingIndent() { 708 return column.getFollowingIndent(); 709 } 710 711 /** 712 * Sets the right paragraph lines indent. 713 * 714 * @param indent the indent 715 */ 716 public void setRightIndent(float indent) { 717 column.setRightIndent(indent); 718 } 719 720 /** 721 * Gets the right paragraph lines indent. 722 * 723 * @return the indent 724 */ 725 public float getRightIndent() { 726 return column.getRightIndent(); 727 } 728 729 /** 730 * Gets the space/character extra spacing ratio for fully justified text. 731 * 732 * @return the space/character extra spacing ratio 733 */ 734 public float getSpaceCharRatio() { 735 return column.getSpaceCharRatio(); 736 } 737 738 /** Sets the ratio between the extra word spacing and the 739 * extra character spacing when the text is fully justified. 740 * Extra word spacing will grow <CODE>spaceCharRatio</CODE> times more 741 * than extra character spacing. 742 * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> then the 743 * extra character spacing will be zero. 744 * 745 * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing 746 */ 747 public void setSpaceCharRatio(float spaceCharRatio) { 748 column.setSpaceCharRatio(spaceCharRatio); 749 } 750 751 /** 752 * Sets the run direction of the text content in the cell. 753 * May be either of: 754 * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, 755 * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. 756 * @param runDirection 757 */ 758 public void setRunDirection(int runDirection) { 759 column.setRunDirection(runDirection); 760 } 761 762 /** 763 * Gets the run direction of the text content in the cell 764 * 765 * @return One of the following values: 766 * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, 767 * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. 768 */ 769 public int getRunDirection() { 770 return column.getRunDirection(); 771 } 772 773 /** 774 * Getter for property image. 775 * 776 * @return Value of property image. 777 */ 778 public Image getImage() { 779 return image; 780 } 781 782 /** 783 * Setter for property image. 784 * 785 * @param image New value of property image. 786 */ 787 public void setImage(Image image) { 788 column.setText(null); 789 table = null; 790 this.image = image; 791 } 792 793 /** 794 * Gets the cell event for this cell. 795 * 796 * @return the cell event 797 */ 798 public PdfPCellEvent getCellEvent() { 799 return cellEvent; 800 } 801 802 /** 803 * Sets the cell event for this cell. 804 * 805 * @param cellEvent the cell event 806 */ 807 public void setCellEvent(PdfPCellEvent cellEvent) { 808 if (cellEvent == null) 809 this.cellEvent = null; 810 else if (this.cellEvent == null) 811 this.cellEvent = cellEvent; 812 else if (this.cellEvent instanceof PdfPCellEventForwarder) 813 ((PdfPCellEventForwarder)this.cellEvent).addCellEvent(cellEvent); 814 else { 815 PdfPCellEventForwarder forward = new PdfPCellEventForwarder(); 816 forward.addCellEvent(this.cellEvent); 817 forward.addCellEvent(cellEvent); 818 this.cellEvent = forward; 819 } 820 } 821 822 /** 823 * Gets the arabic shaping options. 824 * 825 * @return the arabic shaping options 826 */ 827 public int getArabicOptions() { 828 return column.getArabicOptions(); 829 } 830 831 /** 832 * Sets the arabic shaping options. 833 * The option can be AR_NOVOWEL, AR_COMPOSEDTASHKEEL and AR_LIG. 834 * 835 * @param arabicOptions the arabic shaping options 836 */ 837 public void setArabicOptions(int arabicOptions) { 838 column.setArabicOptions(arabicOptions); 839 } 840 841 /** 842 * Gets state of first line height based on max ascender 843 * 844 * @return true if an ascender is to be used. 845 */ 846 public boolean isUseAscender() { 847 return column.isUseAscender(); 848 } 849 850 /** 851 * Enables/ Disables adjustment of first line height based on max ascender. 852 * 853 * @param useAscender adjust height if true 854 */ 855 public void setUseAscender(boolean useAscender) { 856 column.setUseAscender(useAscender); 857 } 858 859 860 /** 861 * Getter for property useDescender. 862 * 863 * @return Value of property useDescender. 864 */ 865 public boolean isUseDescender() { 866 return useDescender; 867 } 868 869 /** 870 * Setter for property useDescender. 871 * 872 * @param useDescender New value of property useDescender. 873 */ 874 public void setUseDescender(boolean useDescender) { 875 this.useDescender = useDescender; 876 } 877 878 /** 879 * Gets the ColumnText with the content of the cell. 880 * 881 * @return a columntext object 882 */ 883 public ColumnText getColumn() { 884 return column; 885 } 886 887 /** 888 * Returns the list of composite elements of the column. 889 * 890 * @return a List object. 891 * @since 2.1.1 892 */ 893 public List<Element> getCompositeElements() { 894 return getColumn().compositeElements; 895 } 896 897 /** 898 * Sets the columntext in the cell. 899 * 900 * @param column 901 */ 902 public void setColumn(ColumnText column) { 903 this.column = column; 904 } 905 906 /** 907 * Gets the rotation of the cell. 908 * 909 * @return the rotation of the cell. 910 */ 911 @Override 912 public int getRotation() { 913 return rotation; 914 } 915 916 /** 917 * Sets the rotation of the cell. 918 * Possible values are 0, 90, 180 and 270. 919 * 920 * @param rotation the rotation of the cell 921 */ 922 public void setRotation(int rotation) { 923 rotation %= 360; 924 if (rotation < 0) 925 rotation += 360; 926 if (rotation % 90 != 0) 927 throw new IllegalArgumentException(MessageLocalization.getComposedMessage("rotation.must.be.a.multiple.of.90")); 928 this.rotation = rotation; 929 } 930 931 /** 932 * Returns the height of the cell. 933 * @return the height of the cell 934 * @since 3.0.0 935 */ 936 public float getMaxHeight() { 937 boolean pivoted = getRotation() == 90 || getRotation() == 270; 938 Image img = getImage(); 939 if (img != null) { 940 img.scalePercent(100); 941 float refWidth = pivoted ? img.getScaledHeight() : img.getScaledWidth(); 942 float scale = (getRight() - getEffectivePaddingRight() 943 - getEffectivePaddingLeft() - getLeft()) / refWidth; 944 img.scalePercent(scale * 100); 945 float refHeight = pivoted ? img.getScaledWidth() : img.getScaledHeight(); 946 setBottom(getTop() - getEffectivePaddingTop() - getEffectivePaddingBottom() - refHeight); 947 } 948 else { 949 if (pivoted && hasFixedHeight()) 950 setBottom(getTop() - getFixedHeight()); 951 else { 952 ColumnText ct = ColumnText.duplicate(getColumn()); 953 float right, top, left, bottom; 954 if (pivoted) { 955 right = PdfPRow.RIGHT_LIMIT; 956 top = getRight() - getEffectivePaddingRight(); 957 left = 0; 958 bottom = getLeft() + getEffectivePaddingLeft(); 959 } 960 else { 961 right = isNoWrap() ? PdfPRow.RIGHT_LIMIT : getRight() - getEffectivePaddingRight(); 962 top = getTop() - getEffectivePaddingTop(); 963 left = getLeft() + getEffectivePaddingLeft(); 964 bottom = hasFixedHeight() ? getTop() + getEffectivePaddingBottom() - getFixedHeight() : PdfPRow.BOTTOM_LIMIT; 965 } 966 PdfPRow.setColumn(ct, left, bottom, right, top); 967 try { 968 ct.go(true); 969 } catch (DocumentException e) { 970 throw new ExceptionConverter(e); 971 } 972 if (pivoted) 973 setBottom(getTop() - getEffectivePaddingTop() - getEffectivePaddingBottom() - ct.getFilledWidth()); 974 else { 975 float yLine = ct.getYLine(); 976 if (isUseDescender()) 977 yLine += ct.getDescender(); 978 setBottom(yLine - getEffectivePaddingBottom()); 979 } 980 } 981 } 982 float height = getHeight(); 983 if (hasFixedHeight()) 984 height = getFixedHeight(); 985 else if (hasMinimumHeight() && height < getMinimumHeight()) 986 height = getMinimumHeight(); 987 return height; 988 } 989}