1 /*
2 * $Id: PdfPRow.java 3373 2008-05-12 16:21:24Z xlv $
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.awt.Color;
53
54 import com.lowagie.text.DocumentException;
55 import com.lowagie.text.Element;
56 import com.lowagie.text.ExceptionConverter;
57 import com.lowagie.text.Image;
58 import com.lowagie.text.Rectangle;
59
60 /**
61 * A row in a PdfPTable.
62 *
63 * @author Paulo Soares (psoares@consiste.pt)
64 */
65
66 public class PdfPRow {
67
68 /** the bottom limit (bottom right y) */
69 public static final float BOTTOM_LIMIT = -(1 << 30);
70
71 protected PdfPCell cells[];
72
73 protected float widths[];
74
75 protected float maxHeight = 0;
76
77 protected boolean calculated = false;
78
79 private int[] canvasesPos;
80
81 /**
82 * Constructs a new PdfPRow with the cells in the array that was passed as a parameter.
83 * @param cells
84 */
85 public PdfPRow(PdfPCell cells[]) {
86 this.cells = cells;
87 widths = new float[cells.length];
88 }
89
90 /**
91 * Makes a copy of an existing row.
92 * @param row
93 */
94 public PdfPRow(PdfPRow row) {
95 maxHeight = row.maxHeight;
96 calculated = row.calculated;
97 cells = new PdfPCell[row.cells.length];
98 for (int k = 0; k < cells.length; ++k) {
99 if (row.cells[k] != null)
100 cells[k] = new PdfPCell(row.cells[k]);
101 }
102 widths = new float[cells.length];
103 System.arraycopy(row.widths, 0, widths, 0, cells.length);
104 }
105
106 /**
107 * Sets the widths of the columns in the row.
108 * @param widths
109 * @return true if everything went right
110 */
111 public boolean setWidths(float widths[]) {
112 if (widths.length != cells.length)
113 return false;
114 System.arraycopy(widths, 0, this.widths, 0, cells.length);
115 float total = 0;
116 calculated = false;
117 for (int k = 0; k < widths.length; ++k) {
118 PdfPCell cell = cells[k];
119 cell.setLeft(total);
120 int last = k + cell.getColspan();
121 for (; k < last; ++k)
122 total += widths[k];
123 --k;
124 cell.setRight(total);
125 cell.setTop(0);
126 }
127 return true;
128 }
129
130 /**
131 * Calculates the heights of each cell in the row.
132 * @return the maximum height of the row.
133 */
134 public float calculateHeights() {
135 maxHeight = 0;
136 for (int k = 0; k < cells.length; ++k) {
137 PdfPCell cell = cells[k];
138 if (cell == null)
139 continue;
140 Image img = cell.getImage();
141 if (img != null) {
142 img.scalePercent(100);
143 float refWidth = img.getScaledWidth();
144 if (cell.getRotation() == 90 || cell.getRotation() == 270) {
145 refWidth = img.getScaledHeight();
146 }
147 float scale = (cell.getRight() - cell.getEffectivePaddingRight()
148 - cell.getEffectivePaddingLeft() - cell.getLeft())
149 / refWidth;
150 img.scalePercent(scale * 100);
151 float refHeight = img.getScaledHeight();
152 if (cell.getRotation() == 90 || cell.getRotation() == 270) {
153 refHeight = img.getScaledWidth();
154 }
155 cell.setBottom(cell.getTop() - cell.getEffectivePaddingTop()
156 - cell.getEffectivePaddingBottom()
157 - refHeight);
158 } else {
159 if (cell.getRotation() == 0 || cell.getRotation() == 180) {
160 float rightLimit = cell.isNoWrap() ? 20000 : cell.getRight()
161 - cell.getEffectivePaddingRight();
162 float bry = (cell.getFixedHeight() > 0) ? cell.getTop()
163 - cell.getEffectivePaddingTop()
164 + cell.getEffectivePaddingBottom()
165 - cell.getFixedHeight() : BOTTOM_LIMIT;
166 ColumnText ct = ColumnText.duplicate(cell.getColumn());
167 setColumn(ct,
168 cell.getLeft() + cell.getEffectivePaddingLeft(), bry,
169 rightLimit, cell.getTop() - cell.getEffectivePaddingTop());
170 try {
171 ct.go(true);
172 } catch (DocumentException e) {
173 throw new ExceptionConverter(e);
174 }
175 float yLine = ct.getYLine();
176 if (cell.isUseDescender())
177 yLine += ct.getDescender();
178 cell.setBottom(yLine - cell.getEffectivePaddingBottom());
179 }
180 else {
181 if (cell.getFixedHeight() > 0) {
182 cell.setBottom(cell.getTop() - cell.getFixedHeight());
183 }
184 else {
185 ColumnText ct = ColumnText.duplicate(cell.getColumn());
186 setColumn(ct, 0, cell.getLeft() + cell.getEffectivePaddingLeft(),
187 20000, cell.getRight() - cell.getEffectivePaddingRight());
188 try {
189 ct.go(true);
190 } catch (DocumentException e) {
191 throw new ExceptionConverter(e);
192 }
193 cell.setBottom(cell.getTop() - cell.getEffectivePaddingTop()
194 - cell.getEffectivePaddingBottom() - ct.getFilledWidth());
195 }
196 }
197 }
198 float height = cell.getFixedHeight();
199 if (height <= 0)
200 height = cell.getHeight();
201 if (height < cell.getFixedHeight())
202 height = cell.getFixedHeight();
203 else if (height < cell.getMinimumHeight())
204 height = cell.getMinimumHeight();
205 if (height > maxHeight)
206 maxHeight = height;
207 }
208 calculated = true;
209 return maxHeight;
210 }
211
212 /**
213 * Writes the border and background of one cell in the row.
214 * @param xPos
215 * @param yPos
216 * @param cell
217 * @param canvases
218 */
219 public void writeBorderAndBackground(float xPos, float yPos, PdfPCell cell,
220 PdfContentByte[] canvases) {
221 PdfContentByte lines = canvases[PdfPTable.LINECANVAS];
222 PdfContentByte backgr = canvases[PdfPTable.BACKGROUNDCANVAS];
223 // the coordinates of the border are retrieved
224 float x1 = cell.getLeft() + xPos;
225 float y2 = cell.getTop() + yPos;
226 float x2 = cell.getRight() + xPos;
227 float y1 = y2 - maxHeight;
228
229 // the backgroundcolor is set
230 Color background = cell.getBackgroundColor();
231 if (background != null) {
232 backgr.setColorFill(background);
233 backgr.rectangle(x1, y1, x2 - x1, y2 - y1);
234 backgr.fill();
235 }
236 // if the element hasn't got any borders, nothing is added
237 if (cell.hasBorders()) {
238 if (cell.isUseVariableBorders()) {
239 Rectangle borderRect = new Rectangle(cell.getLeft() + xPos, cell
240 .getTop()
241 - maxHeight + yPos, cell.getRight() + xPos, cell.getTop()
242 + yPos);
243 borderRect.cloneNonPositionParameters(cell);
244 borderRect.setBackgroundColor(null);
245 lines.rectangle(borderRect);
246 } else {
247 // the width is set to the width of the element
248 if (cell.getBorderWidth() != Rectangle.UNDEFINED) {
249 lines.setLineWidth(cell.getBorderWidth());
250 }
251 // the color is set to the color of the element
252 Color color = cell.getBorderColor();
253 if (color != null) {
254 lines.setColorStroke(color);
255 }
256
257 // if the box is a rectangle, it is added as a rectangle
258 if (cell.hasBorder(Rectangle.BOX)) {
259 lines.rectangle(x1, y1, x2 - x1, y2 - y1);
260 }
261 // if the border isn't a rectangle, the different sides are
262 // added apart
263 else {
264 if (cell.hasBorder(Rectangle.RIGHT)) {
265 lines.moveTo(x2, y1);
266 lines.lineTo(x2, y2);
267 }
268 if (cell.hasBorder(Rectangle.LEFT)) {
269 lines.moveTo(x1, y1);
270 lines.lineTo(x1, y2);
271 }
272 if (cell.hasBorder(Rectangle.BOTTOM)) {
273 lines.moveTo(x1, y1);
274 lines.lineTo(x2, y1);
275 }
276 if (cell.hasBorder(Rectangle.TOP)) {
277 lines.moveTo(x1, y2);
278 lines.lineTo(x2, y2);
279 }
280 }
281 lines.stroke();
282 if (color != null) {
283 lines.resetRGBColorStroke();
284 }
285 }
286 }
287 }
288
289 private void saveAndRotateCanvases(PdfContentByte[] canvases, float a, float b, float c, float d, float e, float f) {
290 int last = PdfPTable.TEXTCANVAS + 1;
291 if (canvasesPos == null) {
292 canvasesPos = new int[last * 2];
293 }
294 for (int k = 0; k < last; ++k) {
295 ByteBuffer bb = canvases[k].getInternalBuffer();
296 canvasesPos[k * 2] = bb.size();
297 canvases[k].saveState();
298 canvases[k].concatCTM(a, b, c, d, e, f);
299 canvasesPos[k * 2 + 1] = bb.size();
300 }
301 }
302
303 private void restoreCanvases(PdfContentByte[] canvases) {
304 int last = PdfPTable.TEXTCANVAS + 1;
305 for (int k = 0; k < last; ++k) {
306 ByteBuffer bb = canvases[k].getInternalBuffer();
307 int p1 = bb.size();
308 canvases[k].restoreState();
309 if (p1 == canvasesPos[k * 2 + 1])
310 bb.setSize(canvasesPos[k * 2]);
311 }
312 }
313
314 private float setColumn(ColumnText ct, float llx, float lly, float urx, float ury) {
315 if (llx > urx)
316 urx = llx;
317 if (lly > ury)
318 ury = lly;
319 ct.setSimpleColumn(llx, lly, urx, ury);
320 return ury;
321 }
322
323 /**
324 * Writes a number of cells (not necessarily all cells).
325 * @param colStart
326 * @param colEnd
327 * @param xPos
328 * @param yPos
329 * @param canvases
330 */
331 public void writeCells(int colStart, int colEnd, float xPos, float yPos,
332 PdfContentByte[] canvases) {
333 if (!calculated)
334 calculateHeights();
335 if (colEnd < 0)
336 colEnd = cells.length;
337 colEnd = Math.min(colEnd, cells.length);
338 if (colStart < 0)
339 colStart = 0;
340 if (colStart >= colEnd)
341 return;
342 int newStart;
343 for (newStart = colStart; newStart >= 0; --newStart) {
344 if (cells[newStart] != null)
345 break;
346 xPos -= widths[newStart - 1];
347 }
348 xPos -= cells[newStart].getLeft();
349 for (int k = newStart; k < colEnd; ++k) {
350 PdfPCell cell = cells[k];
351 if (cell == null)
352 continue;
353 writeBorderAndBackground(xPos, yPos, cell, canvases);
354 Image img = cell.getImage();
355 float tly = 0;
356 switch (cell.getVerticalAlignment()) {
357 case Element.ALIGN_BOTTOM:
358 tly = cell.getTop() + yPos - maxHeight + cell.getHeight()
359 - cell.getEffectivePaddingTop();
360 break;
361 case Element.ALIGN_MIDDLE:
362 tly = cell.getTop() + yPos + (cell.getHeight() - maxHeight) / 2
363 - cell.getEffectivePaddingTop();
364 break;
365 default:
366 tly = cell.getTop() + yPos - cell.getEffectivePaddingTop();
367 break;
368 }
369 if (img != null) {
370 if (cell.getRotation() != 0) {
371 img = Image.getInstance(img);
372 img.setRotation(img.getImageRotation() + (float)(cell.getRotation() * Math.PI / 180.0));
373 }
374 boolean vf = false;
375 if (cell.getHeight() > maxHeight) {
376 img.scalePercent(100);
377 float scale = (maxHeight - cell.getEffectivePaddingTop() - cell
378 .getEffectivePaddingBottom())
379 / img.getScaledHeight();
380 img.scalePercent(scale * 100);
381 vf = true;
382 }
383 float left = cell.getLeft() + xPos
384 + cell.getEffectivePaddingLeft();
385 if (vf) {
386 switch (cell.getHorizontalAlignment()) {
387 case Element.ALIGN_CENTER:
388 left = xPos
389 + (cell.getLeft() + cell.getEffectivePaddingLeft()
390 + cell.getRight()
391 - cell.getEffectivePaddingRight() - img
392 .getScaledWidth()) / 2;
393 break;
394 case Element.ALIGN_RIGHT:
395 left = xPos + cell.getRight()
396 - cell.getEffectivePaddingRight()
397 - img.getScaledWidth();
398 break;
399 default:
400 break;
401 }
402 tly = cell.getTop() + yPos - cell.getEffectivePaddingTop();
403 }
404 img.setAbsolutePosition(left, tly - img.getScaledHeight());
405 try {
406 canvases[PdfPTable.TEXTCANVAS].addImage(img);
407 } catch (DocumentException e) {
408 throw new ExceptionConverter(e);
409 }
410 } else {
411 // rotation sponsored by Connection GmbH
412 if (cell.getRotation() == 90 || cell.getRotation() == 270) {
413 float netWidth = maxHeight - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom();
414 float netHeight = cell.getWidth() - cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight();
415 ColumnText ct = ColumnText.duplicate(cell.getColumn());
416 ct.setCanvases(canvases);
417 ct.setSimpleColumn(0, 0, netWidth + 0.001f, -netHeight);
418 try {
419 ct.go(true);
420 } catch (DocumentException e) {
421 throw new ExceptionConverter(e);
422 }
423 float calcHeight = -ct.getYLine();
424 if (netWidth <= 0 || netHeight <= 0)
425 calcHeight = 0;
426 if (calcHeight > 0) {
427 if (cell.isUseDescender())
428 calcHeight -= ct.getDescender();
429 ct = ColumnText.duplicate(cell.getColumn());
430 ct.setCanvases(canvases);
431 ct.setSimpleColumn(0, -0.001f, netWidth + 0.001f, calcHeight);
432 float pivotX;
433 float pivotY;
434 if (cell.getRotation() == 90) {
435 pivotY = cell.getTop() + yPos - maxHeight + cell.getEffectivePaddingBottom();
436 switch (cell.getVerticalAlignment()) {
437 case Element.ALIGN_BOTTOM:
438 pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight();
439 break;
440 case Element.ALIGN_MIDDLE:
441 pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() + calcHeight) / 2;
442 break;
443 default: //top
444 pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft() + calcHeight;
445 break;
446 }
447 saveAndRotateCanvases(canvases, 0,1,-1,0,pivotX,pivotY);
448 }
449 else {
450 pivotY = cell.getTop() + yPos - cell.getEffectivePaddingTop();
451 switch (cell.getVerticalAlignment()) {
452 case Element.ALIGN_BOTTOM:
453 pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft();
454 break;
455 case Element.ALIGN_MIDDLE:
456 pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() - calcHeight) / 2;
457 break;
458 default: //top
459 pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight() - calcHeight;
460 break;
461 }
462 saveAndRotateCanvases(canvases, 0,-1,1,0,pivotX,pivotY);
463 }
464 try {
465 ct.go();
466 } catch (DocumentException e) {
467 throw new ExceptionConverter(e);
468 } finally {
469 restoreCanvases(canvases);
470 }
471 }
472 }
473 else {
474 float fixedHeight = cell.getFixedHeight();
475 float rightLimit = cell.getRight() + xPos
476 - cell.getEffectivePaddingRight();
477 float leftLimit = cell.getLeft() + xPos
478 + cell.getEffectivePaddingLeft();
479 if (cell.isNoWrap()) {
480 switch (cell.getHorizontalAlignment()) {
481 case Element.ALIGN_CENTER:
482 rightLimit += 10000;
483 leftLimit -= 10000;
484 break;
485 case Element.ALIGN_RIGHT:
486 leftLimit -= 20000;
487 break;
488 default:
489 rightLimit += 20000;
490 break;
491 }
492 }
493 ColumnText ct = ColumnText.duplicate(cell.getColumn());
494 ct.setCanvases(canvases);
495 float bry = tly
496 - (maxHeight /* cell.height() */
497 - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom());
498 if (fixedHeight > 0) {
499 if (cell.getHeight() > maxHeight) {
500 tly = cell.getTop() + yPos - cell.getEffectivePaddingTop();
501 bry = cell.getTop() + yPos - maxHeight + cell.getEffectivePaddingBottom();
502 }
503 }
504 if ((tly > bry || ct.zeroHeightElement()) && leftLimit < rightLimit) {
505 ct.setSimpleColumn(leftLimit, bry - 0.001f, rightLimit, tly);
506 if (cell.getRotation() == 180) {
507 float shx = leftLimit + rightLimit;
508 float shy = yPos + yPos - maxHeight + cell.getEffectivePaddingBottom() - cell.getEffectivePaddingTop();
509 saveAndRotateCanvases(canvases, -1,0,0,-1,shx,shy);
510 }
511 try {
512 ct.go();
513 } catch (DocumentException e) {
514 throw new ExceptionConverter(e);
515 } finally {
516 if (cell.getRotation() == 180) {
517 restoreCanvases(canvases);
518 }
519 }
520 }
521 }
522 }
523 PdfPCellEvent evt = cell.getCellEvent();
524 if (evt != null) {
525 Rectangle rect = new Rectangle(cell.getLeft() + xPos, cell.getTop()
526 + yPos - maxHeight, cell.getRight() + xPos, cell.getTop()
527 + yPos);
528 evt.cellLayout(cell, rect, canvases);
529 }
530 }
531 }
532
533 /**
534 * Checks if the dimensions of the columns were calculated.
535 * @return true if the dimensions of the columns were calculated
536 */
537 public boolean isCalculated() {
538 return calculated;
539 }
540
541 /**
542 * Gets the maximum height of the row (i.e. of the 'highest' cell).
543 * @return the maximum height of the row
544 */
545 public float getMaxHeights() {
546 if (calculated)
547 return maxHeight;
548 else
549 return calculateHeights();
550 }
551
552 /**
553 * Changes the maximum height of the row (to make it higher).
554 * (added by Jin-Hsia Yang)
555 * @param maxHeight the new maximum height
556 */
557 public void setMaxHeights(float maxHeight) {
558 this.maxHeight = maxHeight;
559 }
560
561 //end add
562
563 float[] getEventWidth(float xPos) {
564 int n = 0;
565 for (int k = 0; k < cells.length; ++k) {
566 if (cells[k] != null)
567 ++n;
568 }
569 float width[] = new float[n + 1];
570 n = 0;
571 width[n++] = xPos;
572 for (int k = 0; k < cells.length; ++k) {
573 if (cells[k] != null) {
574 width[n] = width[n - 1] + cells[k].getWidth();
575 ++n;
576 }
577 }
578 return width;
579 }
580
581 /**
582 * Splits a row to newHeight. The returned row is the remainder. It will
583 * return null if the newHeight was so small that only an empty row would
584 * result.
585 *
586 * @param newHeight
587 * the new height
588 * @return the remainder row or null if the newHeight was so small that only
589 * an empty row would result
590 */
591 public PdfPRow splitRow(float newHeight) {
592 PdfPCell newCells[] = new PdfPCell[cells.length];
593 float fh[] = new float[cells.length * 2];
594 boolean allEmpty = true;
595 for (int k = 0; k < cells.length; ++k) {
596 PdfPCell cell = cells[k];
597 if (cell == null)
598 continue;
599 fh[k * 2] = cell.getFixedHeight();
600 fh[k * 2 + 1] = cell.getMinimumHeight();
601 Image img = cell.getImage();
602 PdfPCell c2 = new PdfPCell(cell);
603 if (img != null) {
604 if (newHeight > cell.getEffectivePaddingBottom()
605 + cell.getEffectivePaddingTop() + 2) {
606 c2.setPhrase(null);
607 allEmpty = false;
608 }
609 } else {
610 int status;
611 float y;
612 ColumnText ct = ColumnText.duplicate(cell.getColumn());
613 if (cell.getRotation() == 90 || cell.getRotation() == 270) {
614 y = setColumn(ct,
615 cell.getTop() - newHeight + cell.getEffectivePaddingBottom(),
616 cell.getLeft() + cell.getEffectivePaddingLeft(),
617 cell.getTop() - cell.getEffectivePaddingTop(),
618 cell.getRight() - cell.getEffectivePaddingRight());
619 }
620 else {
621 float rightLimit = cell.isNoWrap() ? 20000 : cell.getRight()
622 - cell.getEffectivePaddingRight();
623 float y1 = cell.getTop() - newHeight
624 + cell.getEffectivePaddingBottom();
625 float y2 = cell.getTop() - cell.getEffectivePaddingTop();
626 y = setColumn(ct,
627 cell.getLeft() + cell.getEffectivePaddingLeft(), y1,
628 rightLimit, y2);
629 }
630 try {
631 status = ct.go(true);
632 } catch (DocumentException e) {
633 throw new ExceptionConverter(e);
634 }
635 boolean thisEmpty = (ct.getYLine() == y);
636 if (thisEmpty)
637 ct = ColumnText.duplicate(cell.getColumn());
638 allEmpty = (allEmpty && thisEmpty);
639 if ((status & ColumnText.NO_MORE_TEXT) == 0 || thisEmpty) {
640 c2.setColumn(ct);
641 ct.setFilledWidth(0);
642 } else {
643 c2.setPhrase(null);
644 }
645 }
646 newCells[k] = c2;
647 cell.setFixedHeight(newHeight);
648 }
649 if (allEmpty) {
650 for (int k = 0; k < cells.length; ++k) {
651 PdfPCell cell = cells[k];
652 if (cell == null)
653 continue;
654 float f = fh[k * 2];
655 float m = fh[k * 2 + 1];
656 if (f <= 0)
657 cell.setMinimumHeight(m);
658 else
659 cell.setFixedHeight(f);
660 }
661 return null;
662 }
663 calculateHeights();
664 PdfPRow split = new PdfPRow(newCells);
665 split.widths = (float[]) widths.clone();
666 split.calculateHeights();
667 return split;
668 }
669
670 /**
671 * Returns the array of cells in the row.
672 * Please be extremely careful with this method.
673 * Use the cells as read only objects.
674 * @return an array of cells
675 * @since 2.1.1
676 */
677 public PdfPCell[] getCells() {
678 return cells;
679 }
680 }