1 /*
2  * $Id: PdfPCell.java 3992 2009-06-19 12:05:06Z blowagie $
3  *
4  * Copyright 2001, 2002 Paulo Soares
5  *
6  * The contents of this file are subject to the Mozilla Public License Version 1.1
7  * (the "License"); you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the License.
13  *
14  * The Original Code is 'iText, a free JAVA-PDF library'.
15  *
16  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18  * All Rights Reserved.
19  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source code
23  * where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above.  If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the MPL as stated above or under the terms of the GNU
37  * Library General Public License as published by the Free Software Foundation;
38  * either version 2 of the License, or any later version.
39  *
40  * This library is distributed in the hope that it will be useful, but WITHOUT
41  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43  * details.
44  *
45  * If you didn't download this code from the following link, you should check if
46  * you aren't using an obsolete version:
47  * http://www.lowagie.com/iText/
48  */

49
50 package com.lowagie.text.pdf;
51
52 import java.util.List;
53
54 import com.lowagie.text.Chunk;
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.Phrase;
60 import com.lowagie.text.Rectangle;
61 import com.lowagie.text.pdf.events.PdfPCellEventForwarder;
62
63 /**
64  * A cell in a PdfPTable.
65  */

66
67 public class PdfPCell extends Rectangle{
68     
69     private ColumnText column = new ColumnText(null);
70     
71     /** Vertical alignment of the cell. */
72     private int verticalAlignment = Element.ALIGN_TOP;
73     
74     /** Left padding of the cell. */
75     private float paddingLeft = 2;
76     
77     /** Right padding of the cell. */
78     private float paddingRight = 2;
79     
80     /** Top padding of the cell. */
81     private float paddingTop = 2;
82     
83     /** Bottom padding of the cell. */
84     private float paddingBottom = 2;
85     
86     /** Fixed height of the cell. */
87     private float fixedHeight = 0;
88     
89     /** Minimum height of the cell. */
90     private float minimumHeight;
91     
92     /** Holds value of property noWrap. */
93     private boolean noWrap = false;
94     
95     /** Holds value of property table. */
96     private PdfPTable table;
97
98     /** Holds value of property colspan. */
99     private int colspan = 1;
100
101     /**
102      * Holds value of property rowspan.
103      * @since    2.1.6
104      */

105     private int rowspan = 1;
106     
107     /** Holds value of property image. */
108     private Image image;
109     
110     /** Holds value of property cellEvent. */
111     private PdfPCellEvent cellEvent;
112
113     /** Holds value of property useDescender. */
114     private boolean useDescender;
115
116     /** Increases padding to include border if true */
117     private boolean useBorderPadding = false;
118
119     /** The text in the cell. */
120     protected Phrase phrase;
121
122     /**
123      * The rotation of the cell. Possible values are
124      * 0, 90, 180 and 270.
125      */

126     private int rotation;
127
128     /**
129      * Constructs an empty <CODE>PdfPCell</CODE>.
130      * The default padding is 2.
131      */

132     public PdfPCell() {
133         super(0, 0, 0, 0);
134         borderWidth = 0.5f;
135         border = BOX;
136         column.setLeading(0, 1);
137     }
138
139     /**
140      * Constructs a <CODE>PdfPCell</CODE> with a <CODE>Phrase</CODE>.
141      * The default padding is 2.
142      * 
143      * @param phrase the text
144      */

145     public PdfPCell(Phrase phrase) {
146         super(0, 0, 0, 0);
147         borderWidth = 0.5f;
148         border = BOX;
149         column.addText(this.phrase = phrase);
150         column.setLeading(0, 1);
151     }
152     
153     /**
154      * Constructs a <CODE>PdfPCell</CODE> with an <CODE>Image</CODE>.
155      * The default padding is 0.
156      * 
157      * @param image the <CODE>Image</CODE>
158      */

159     public PdfPCell(Image image) {
160         this(image, false);
161     }
162     
163     /**
164      * Constructs a <CODE>PdfPCell</CODE> with an <CODE>Image</CODE>.
165      * The default padding is 0.25 for a border width of 0.5.
166      * 
167      * @param image the <CODE>Image</CODE>
168      * @param fit <CODE>true</CODE> to fit the image to the cell
169      */

170     public PdfPCell(Image image, boolean fit) {
171         super(0, 0, 0, 0);
172         borderWidth = 0.5f;
173         border = BOX;
174         if (fit) {
175             this.image = image;
176             column.setLeading(0, 1);
177             setPadding(borderWidth / 2);
178         }
179         else {
180             column.addText(this.phrase = new Phrase(new Chunk(image, 0, 0)));
181             column.setLeading(0, 1);
182             setPadding(0);
183         }
184     }
185     
186     /**
187      * Constructs a <CODE>PdfPCell</CODE> with a <CODE>PdfPtable</CODE>.
188      * This constructor allows nested tables.
189      * The default padding is 0.
190      * 
191      * @param table The <CODE>PdfPTable</CODE>
192      */

193     public PdfPCell(PdfPTable table) {
194         this(table, null);
195     }
196     
197     /**
198      * Constructs a <CODE>PdfPCell</CODE> with a <CODE>PdfPtable</CODE>.
199      * This constructor allows nested tables.
200      * 
201      * @param table The <CODE>PdfPTable</CODE>
202      * @param style    The style to apply to the cell (you could use getDefaultCell())
203      * @since 2.1.0
204      */

205     public PdfPCell(PdfPTable table, PdfPCell style) {
206         super(0, 0, 0, 0);
207         borderWidth = 0.5f;
208         border = BOX;
209         column.setLeading(0, 1);
210         this.table = table;
211         table.setWidthPercentage(100);
212         table.setExtendLastRow(true);
213         column.addElement(table);
214         if (style != null) {
215             cloneNonPositionParameters(style);
216             verticalAlignment = style.verticalAlignment;
217             paddingLeft = style.paddingLeft;
218             paddingRight = style.paddingRight;
219             paddingTop = style.paddingTop;
220             paddingBottom = style.paddingBottom;
221             colspan = style.colspan;
222             rowspan = style.rowspan;
223             cellEvent = style.cellEvent;
224             useDescender = style.useDescender;
225             useBorderPadding = style.useBorderPadding;
226             rotation = style.rotation;
227         }
228         else
229             setPadding(0);
230     }
231     
232     /**
233      * Constructs a deep copy of a <CODE>PdfPCell</CODE>.
234      * 
235      * @param cell the <CODE>PdfPCell</CODE> to duplicate
236      */

237     public PdfPCell(PdfPCell cell) {
238         super(cell.llx, cell.lly, cell.urx, cell.ury);
239         cloneNonPositionParameters(cell);
240         verticalAlignment = cell.verticalAlignment;
241         paddingLeft = cell.paddingLeft;
242         paddingRight = cell.paddingRight;
243         paddingTop = cell.paddingTop;
244         paddingBottom = cell.paddingBottom;
245         phrase = cell.phrase;
246         fixedHeight = cell.fixedHeight;
247         minimumHeight = cell.minimumHeight;
248         noWrap = cell.noWrap;
249         colspan = cell.colspan;
250         rowspan = cell.rowspan;
251         if (cell.table != null)
252             table = new PdfPTable(cell.table);
253         image = Image.getInstance(cell.image);
254         cellEvent = cell.cellEvent;
255         useDescender = cell.useDescender;
256         column = ColumnText.duplicate(cell.column);
257         useBorderPadding = cell.useBorderPadding;
258         rotation = cell.rotation;
259     }
260     
261     /**
262      * Adds an iText element to the cell.
263      * 
264      * @param element
265      */

266     public void addElement(Element element) {
267         if (table != null) {
268             table = null;
269             column.setText(null);
270         }
271         column.addElement(element);
272     }
273     
274     /**
275      * Gets the <CODE>Phrase</CODE> from this cell.
276      * 
277      * @return the <CODE>Phrase</CODE>
278      */

279     public Phrase getPhrase() {
280         return phrase;
281     }
282     
283     /**
284      * Sets the <CODE>Phrase</CODE> for this cell.
285      * 
286      * @param phrase the <CODE>Phrase</CODE>
287      */

288     public void setPhrase(Phrase phrase) {
289         table = null;
290         image = null;
291         column.setText(this.phrase = phrase);
292     }
293     
294     /**
295      * Gets the horizontal alignment for the cell.
296      * 
297      * @return the horizontal alignment for the cell
298      */

299     public int getHorizontalAlignment() {
300         return column.getAlignment();
301     }
302     
303     /**
304      * Sets the horizontal alignment for the cell. It could be
305      * <CODE>Element.ALIGN_CENTER</CODE> for example.
306      * 
307      * @param horizontalAlignment The horizontal alignment
308      */

309     public void setHorizontalAlignment(int horizontalAlignment) {
310         column.setAlignment(horizontalAlignment);
311     }
312     
313     /**
314      * Gets the vertical alignment for the cell.
315      * 
316      * @return the vertical alignment for the cell
317      */

318     public int getVerticalAlignment() {
319         return verticalAlignment;
320     }
321     
322     /**
323      * Sets the vertical alignment for the cell. It could be
324      * <CODE>Element.ALIGN_MIDDLE</CODE> for example.
325      * 
326      * @param verticalAlignment The vertical alignment
327      */

328     public void setVerticalAlignment(int verticalAlignment) {
329         if (table != null)
330             table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP);
331         this.verticalAlignment = verticalAlignment;
332     }
333     
334     /**
335      * Gets the effective left padding.
336      * This will include the left border width if
337      * {@link #isUseBorderPadding()} is true.
338      * 
339      * @return effective value of property paddingLeft.
340      */

341     public float getEffectivePaddingLeft() {
342         if (isUseBorderPadding()) {
343             float border = getBorderWidthLeft() / (isUseVariableBorders() ? 1f : 2f);
344             return paddingLeft + border;
345         }
346         return paddingLeft;
347     }
348     
349     /**
350      * @return Value of property paddingLeft.
351      */

352     public float getPaddingLeft() {
353         return paddingLeft;
354     }
355
356     /**
357      * Setter for property paddingLeft.
358      * 
359      * @param paddingLeft New value of property paddingLeft.
360      */

361     public void setPaddingLeft(float paddingLeft) {
362         this.paddingLeft = paddingLeft;
363     }
364     
365     /**
366      * Gets the effective right padding.  This will include
367      * the right border width if {@link #isUseBorderPadding()} is true.
368      * 
369      * @return effective value of property paddingRight.
370      */

371     public float getEffectivePaddingRight() {
372         if (isUseBorderPadding()) {
373             float border = getBorderWidthRight() / (isUseVariableBorders() ? 1f : 2f);
374             return paddingRight + border;
375         }
376         return paddingRight;
377     }
378     
379     /**
380      * Getter for property paddingRight.
381      * 
382      * @return Value of property paddingRight.
383      */

384     public float getPaddingRight() {
385         return paddingRight;
386     }
387
388     /**
389      * Setter for property paddingRight.
390      * 
391      * @param paddingRight New value of property paddingRight.
392      */

393     public void setPaddingRight(float paddingRight) {
394         this.paddingRight = paddingRight;
395     }
396     
397     /** 
398      * Gets the effective top padding.  This will include
399      * the top border width if {@link #isUseBorderPadding()} is true.
400      * 
401      * @return effective value of property paddingTop.
402      */

403     public float getEffectivePaddingTop() {
404         if (isUseBorderPadding()) {
405             float border = getBorderWidthTop()/(isUseVariableBorders()?1f:2f);
406             return paddingTop + border;
407         }
408         return paddingTop;
409     }
410     
411     /**
412      * Getter for property paddingTop.
413      * 
414      * @return Value of property paddingTop.
415      */

416     public float getPaddingTop() {
417         return paddingTop;
418     }
419
420     /**
421      * Setter for property paddingTop.
422      * 
423      * @param paddingTop New value of property paddingTop.
424      */

425     public void setPaddingTop(float paddingTop) {
426         this.paddingTop = paddingTop;
427     }
428     
429     /**
430      * Gets the effective bottom padding.
431      * This will include  the bottom border width if
432      * {@link #isUseBorderPadding()} is true.
433      * 
434      * @return effective value of property paddingBottom.
435      */

436     public float getEffectivePaddingBottom() {
437         if (isUseBorderPadding()) {
438             float border = getBorderWidthBottom()/(isUseVariableBorders()?1f:2f);
439             return paddingBottom + border;
440         }
441         return paddingBottom;
442     }
443     
444     /**
445      * Getter for property paddingBottom.
446      * 
447      * @return Value of property paddingBottom.
448      */

449     public float getPaddingBottom() {
450         return paddingBottom;
451     }
452
453     /**
454      * Setter for property paddingBottom.
455      * 
456      * @param paddingBottom New value of property paddingBottom.
457      */

458     public void setPaddingBottom(float paddingBottom) {
459         this.paddingBottom = paddingBottom;
460     }
461     
462     /**
463      * Sets the padding of the contents in the cell (space between content and border).
464      * 
465      * @param padding
466      */

467     public void setPadding(float padding) {
468         paddingBottom = padding;
469         paddingTop = padding;
470         paddingLeft = padding;
471         paddingRight = padding;
472     }
473
474     /**
475      * If true, then effective padding will include border widths
476      * 
477      * @return true if effective padding includes border widths
478      */

479     public boolean isUseBorderPadding() {
480         return useBorderPadding;
481     }
482
483     /**
484      * Adjusts effective padding to include border widths.
485      * 
486      * @param use adjust effective padding if true
487      */

488     public void setUseBorderPadding(boolean use) {
489         useBorderPadding = use;
490     }
491
492     /**
493      * Sets the leading fixed and variable. 
494      * The resultant leading will be:
495      * fixedLeading+multipliedLeading*maxFontSize
496      * where maxFontSize is the size of the biggest font in the line.
497      * 
498      * @param fixedLeading the fixed leading
499      * @param multipliedLeading the variable leading
500      */

501     public void setLeading(float fixedLeading, float multipliedLeading) {
502         column.setLeading(fixedLeading, multipliedLeading);
503     }
504     
505     /**
506      * Gets the fixed leading.
507      * 
508      * @return the leading
509      */

510     public float getLeading() {
511         return column.getLeading();
512     }
513     
514     /**
515      * Gets the variable leading.
516      * 
517      * @return the leading
518      */

519     public float getMultipliedLeading() {
520         return column.getMultipliedLeading();
521     }
522     
523     /**
524      * Sets the first paragraph line indent.
525      * 
526      * @param indent the indent
527      */

528     public void setIndent(float indent) {
529         column.setIndent(indent);
530     }
531     
532     /**
533      * Gets the first paragraph line indent.
534      * 
535      * @return the indent
536      */

537     public float getIndent() {
538         return column.getIndent();
539     }
540     
541     /**
542      * Gets the extra space between paragraphs.
543      * 
544      * @return the extra space between paragraphs
545      */

546     public float getExtraParagraphSpace() {
547         return column.getExtraParagraphSpace();
548     }
549     
550     /**
551      * Sets the extra space between paragraphs.
552      * 
553      * @param extraParagraphSpace the extra space between paragraphs
554      */

555     public void setExtraParagraphSpace(float extraParagraphSpace) {
556         column.setExtraParagraphSpace(extraParagraphSpace);
557     }
558     
559     /**
560      * Set a fixed height for the cell.
561      * This will automatically unset minimumHeight, if set.
562      * 
563      * @param fixedHeight New value of property fixedHeight.
564      */

565     public void setFixedHeight(float fixedHeight) {
566         this.fixedHeight = fixedHeight;
567         minimumHeight = 0;
568     }
569     
570     /**
571      * Get the fixed height of the cell.
572      * 
573      * @return Value of property fixedHeight.
574      */

575     public float getFixedHeight() {
576         return fixedHeight;
577     }
578
579     /**
580      * Tells you whether the cell has a fixed height.
581      * 
582      * @return    true is a fixed height was set.
583      * @since 2.1.5
584      */

585     public boolean hasFixedHeight() {
586         return getFixedHeight() > 0;
587     }
588     
589     /**
590      * Set a minimum height for the cell.
591      * This will automatically unset fixedHeight, if set.
592      * 
593      * @param minimumHeight New value of property minimumHeight.
594      */

595     public void setMinimumHeight(float minimumHeight) {
596         this.minimumHeight = minimumHeight;
597         fixedHeight = 0;
598     }
599     
600     /**
601      * Get the minimum height of the cell.
602      *
603      * @return Value of property minimumHeight.
604      */

605     public float getMinimumHeight() {
606         return minimumHeight;
607     }
608
609     /**
610      * Tells you whether the cell has a minimum height.
611      * 
612      * @return    true if a minimum height was set.
613      * @since 2.1.5
614      */

615     public boolean hasMinimumHeight() {
616         return getMinimumHeight() > 0;
617     }
618     
619     /**
620      * Getter for property noWrap.
621      * 
622      * @return Value of property noWrap.
623      */

624     public boolean isNoWrap() {
625         return noWrap;
626     }
627     
628     /**
629      * Setter for property noWrap.
630      * 
631      * @param noWrap New value of property noWrap.
632      */

633     public void setNoWrap(boolean noWrap) {
634         this.noWrap = noWrap;
635     }
636     
637     /**
638      * Getter for property table.
639      * 
640      * @return Value of property table.
641      * @since 2.x
642      */

643     public PdfPTable getTable() {
644         return table;
645     }
646     
647     void setTable(PdfPTable table) {
648         this.table = table;
649         column.setText(null);
650         image = null;
651         if (table != null) {
652             table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP);
653             column.addElement(table);
654             table.setWidthPercentage(100);
655         }
656     }
657
658     /**
659      * Getter for property colspan.
660      * 
661      * @return Value of property colspan.
662      */

663     public int getColspan() {
664         return colspan;
665     }
666     
667     /**
668      * Setter for property colspan.
669      * 
670      * @param colspan New value of property colspan.
671      */

672     public void setColspan(int colspan) {
673         this.colspan = colspan;
674     }
675     
676     /**
677      * Getter for property rowspan.
678      * 
679      * @return Value of property rowspan.
680      * @since    2.1.6
681      */

682     public int getRowspan() {
683         return rowspan;
684     }
685     
686     /**
687      * Setter for property rowspan.
688      * 
689      * @param rowspan New value of property rowspan.
690      * @since    2.1.6
691      */

692     public void setRowspan(int rowspan) {
693         this.rowspan = rowspan;
694     }
695
696     /**
697      * Sets the following paragraph lines indent.
698      * 
699      * @param indent the indent
700      */

701     public void setFollowingIndent(float indent) {
702         column.setFollowingIndent(indent);
703     }
704     
705     /**
706      * Gets the following paragraph lines indent.
707      * 
708      * @return the indent
709      */

710     public float getFollowingIndent() {
711         return column.getFollowingIndent();
712     }
713     
714     /**
715      * Sets the right paragraph lines indent.
716      * 
717      * @param indent the indent
718      */

719     public void setRightIndent(float indent) {
720         column.setRightIndent(indent);
721     }
722     
723     /**
724      * Gets the right paragraph lines indent.
725      * 
726      * @return the indent
727      */

728     public float getRightIndent() {
729         return column.getRightIndent();
730     }
731     
732     /**
733      * Gets the space/character extra spacing ratio for fully justified text.
734      * 
735      * @return the space/character extra spacing ratio
736      */

737     public float getSpaceCharRatio() {
738         return column.getSpaceCharRatio();
739     }
740     
741     /** Sets the ratio between the extra word spacing and the
742      * extra character spacing when the text is fully justified.
743      * Extra word spacing will grow <CODE>spaceCharRatio</CODE> times more
744      * than extra character spacing.
745      * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> then the
746      * extra character spacing will be zero.
747      * 
748      * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing
749      */

750     public void setSpaceCharRatio(float spaceCharRatio) {
751         column.setSpaceCharRatio(spaceCharRatio);
752     }
753     
754     /**
755      * Sets the run direction of the text content in the cell.
756      * May be either of:
757      * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI,
758      * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL.
759      * @param runDirection
760      */

761     public void setRunDirection(int runDirection) {
762         column.setRunDirection(runDirection);
763     }
764     
765     /**
766      * Gets the run direction of the text content in the cell
767      * 
768      * @return One of the following values:
769      * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI,
770      * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL.
771      */

772     public int getRunDirection() {
773         return column.getRunDirection();
774     }
775     
776     /**
777      * Getter for property image.
778      * 
779      * @return Value of property image.
780      */

781     public Image getImage() {
782         return image;
783     }
784     
785     /**
786      * Setter for property image.
787      * 
788      * @param image New value of property image.
789      */

790     public void setImage(Image image) {
791         column.setText(null);
792         table = null;
793         this.image = image;
794     }
795     
796     /**
797      * Gets the cell event for this cell.
798      * 
799      * @return the cell event
800      */

801     public PdfPCellEvent getCellEvent() {
802         return cellEvent;
803     }
804     
805     /**
806      * Sets the cell event for this cell.
807      * 
808      * @param cellEvent the cell event
809      */

810     public void setCellEvent(PdfPCellEvent cellEvent) {
811         if (cellEvent == null)
812             this.cellEvent = null;
813         else if (this.cellEvent == null)
814             this.cellEvent = cellEvent;
815         else if (this.cellEvent instanceof PdfPCellEventForwarder)
816             ((PdfPCellEventForwarder)this.cellEvent).addCellEvent(cellEvent);
817         else {
818             PdfPCellEventForwarder forward = new PdfPCellEventForwarder();
819             forward.addCellEvent(this.cellEvent);
820             forward.addCellEvent(cellEvent);
821             this.cellEvent = forward;
822         }
823     }
824     
825     /**
826      * Gets the arabic shaping options.
827      * 
828      * @return the arabic shaping options
829      */

830     public int getArabicOptions() {
831         return column.getArabicOptions();
832     }
833     
834     /** 
835      * Sets the arabic shaping options.
836      * The option can be AR_NOVOWEL, AR_COMPOSEDTASHKEEL and AR_LIG.
837      * 
838      * @param arabicOptions the arabic shaping options
839      */

840     public void setArabicOptions(int arabicOptions) {
841         column.setArabicOptions(arabicOptions);
842     }
843     
844     /**
845      * Gets state of first line height based on max ascender
846      * 
847      * @return true if an ascender is to be used.
848      */

849     public boolean isUseAscender() {
850         return column.isUseAscender();
851     }
852
853     /**
854      * Enables/ Disables adjustment of first line height based on max ascender.
855      *
856      * @param useAscender adjust height if true
857      */

858     public void setUseAscender(boolean useAscender) {
859         column.setUseAscender(useAscender);
860     }
861
862
863     /**
864      * Getter for property useDescender.
865      * 
866      * @return Value of property useDescender.
867      */

868     public boolean isUseDescender() {
869         return useDescender;
870     }
871
872     /**
873      * Setter for property useDescender.
874      * 
875      * @param useDescender New value of property useDescender.
876      */

877     public void setUseDescender(boolean useDescender) {
878         this.useDescender = useDescender;
879     }
880
881     /**
882      * Gets the ColumnText with the content of the cell.
883      * 
884      * @return a columntext object
885      */

886     public ColumnText getColumn() {
887         return column;
888     }
889     
890     /**
891      * Returns the list of composite elements of the column.
892      *
893      * @return    a List object.
894      * @since    2.1.1
895      */

896     public List getCompositeElements() {
897         return getColumn().compositeElements;
898     }
899     
900     /**
901      * Sets the columntext in the cell.
902      *
903      * @param column
904      */

905     public void setColumn(ColumnText column) {
906         this.column = column;
907     }
908
909     /**
910      * Gets the rotation of the cell.
911      *
912      * @return the rotation of the cell.
913      */

914     public int getRotation() {
915         return rotation;
916     }
917
918     /**
919      * Sets the rotation of the cell. 
920      * Possible values are 0, 90, 180 and 270.
921      *
922      * @param rotation the rotation of the cell
923      */

924     public void setRotation(int rotation) {
925         rotation %= 360;
926         if (rotation < 0)
927             rotation += 360;
928         if ((rotation % 90) != 0)
929             throw new IllegalArgumentException("Rotation must be a multiple of 90.");
930         this.rotation = rotation;
931     }
932     
933     /**
934      * Consumes part of the content of the cell.
935      * @param    height    the hight of the part that has to be consumed
936      * @since    2.1.6
937      */

938     void consumeHeight(float height) {
939         float rightLimit = getRight() - getEffectivePaddingRight();
940         float leftLimit = getLeft() + getEffectivePaddingLeft();
941         float bry = height - getEffectivePaddingTop() - getEffectivePaddingBottom();
942         if (getRotation() != 90 && getRotation() != 270) {
943             column.setSimpleColumn(leftLimit, bry + 0.001f,    rightLimit, 0);
944         }
945         else {
946             column.setSimpleColumn(0, leftLimit, bry + 0.001f, rightLimit);
947         }
948         try {
949             column.go(true);
950         } catch (DocumentException e) {
951             // do nothing
952         }
953     }
954     
955     /**
956      * Returns the height of the cell.
957      * @return    the height of the cell
958      * @since    3.0.0
959      */

960     public float getMaxHeight() {
961         boolean pivoted = (getRotation() == 90 || getRotation() == 270);
962         Image img = getImage();
963         if (img != null) {
964             img.scalePercent(100);
965             float refWidth = pivoted ? img.getScaledHeight() : img.getScaledWidth();
966             float scale = (getRight() - getEffectivePaddingRight()
967                     - getEffectivePaddingLeft() - getLeft()) / refWidth;
968             img.scalePercent(scale * 100);
969             float refHeight = pivoted ? img.getScaledWidth() : img.getScaledHeight();
970             setBottom(getTop() - getEffectivePaddingTop() - getEffectivePaddingBottom() - refHeight);
971         }
972         else {
973             if (pivoted && hasFixedHeight())
974                 setBottom(getTop() - getFixedHeight());
975             else {
976                 ColumnText ct = ColumnText.duplicate(getColumn());
977                 float right, top, left, bottom;
978                 if (pivoted) {
979                     right = PdfPRow.RIGHT_LIMIT;
980                     top = getRight() - getEffectivePaddingRight();
981                     left = 0;
982                     bottom = getLeft() + getEffectivePaddingLeft();
983                 }
984                 else {
985                     right = isNoWrap() ? PdfPRow.RIGHT_LIMIT : getRight() - getEffectivePaddingRight();
986                     top = getTop() - getEffectivePaddingTop();
987                     left = getLeft() + getEffectivePaddingLeft();
988                     bottom = hasFixedHeight() ? top + getEffectivePaddingBottom() - getFixedHeight() : PdfPRow.BOTTOM_LIMIT;
989                 }
990                 PdfPRow.setColumn(ct, left, bottom, right, top);
991                 try {
992                     ct.go(true);
993                 } catch (DocumentException e) {
994                     throw new ExceptionConverter(e);
995                 }
996                 if (pivoted)
997                     setBottom(getTop() - getEffectivePaddingTop() - getEffectivePaddingBottom() - ct.getFilledWidth());
998                 else {
999                     float yLine = ct.getYLine();
1000                     if (isUseDescender())
1001                         yLine += ct.getDescender();
1002                     setBottom(yLine - getEffectivePaddingBottom());
1003                 }
1004             }
1005         }
1006         float height = getHeight();
1007         if (height < getFixedHeight())
1008             height = getFixedHeight();
1009         else if (height < getMinimumHeight())
1010             height = getMinimumHeight();
1011         return height;
1012     }
1013 }