/**
* $Id: RtfCell.java,v 1.37 2006/02/09 17:25:26 hallm Exp $
* $Name: $
*
* Copyright 2001, 2002 by Mark Hall
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or under the terms of the GNU
* Library General Public License as published by the Free Software Foundation;
* either version 2 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
* details.
*
* If you didn't download this code from the following link, you should check if
* you aren't using an obsolete version:
* http://www.lowagie.com/iText/
*/
package com.lowagie.text.rtf;
import com.lowagie.text.*;
import java.util.Iterator;
import java.io.*;
import java.awt.Color;
/**
* A Helper Class for the RtfWriter
.
*
* Do not use it directly
*
* ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2.
*
* Parts of this Class were contributed by Steffen Stundzig. Many thanks for the
* improvements.
* Updates by Benoit WIART
* @param cell The RtfWriter
to which this RtfCell
belongs. */
private RtfWriter writer = null;
/** The RtfTable
to which this RtfCell
belongs. */
private RtfTable mainTable = null;
/** Cell width */
private int cellWidth = 0;
/** Cell right border position */
private int cellRight = 0;
/** Cell
containing the actual data */
private Cell store = null;
/** Is this an empty cell */
private boolean emptyCell = true;
/** Type of merging to do */
private int mergeType = 0;
/** cell padding, because the table only renders the left and right cell padding
* and not the top and bottom one
*/
private int cellpadding = 0;
/**
* Create a new RtfCell
.
*
* @param writer The RtfWriter
that this RtfCell
belongs to
* @param mainTable The RtfTable
that created the
* RtfRow
that created the RtfCell
:-)
*/
public RtfCell(RtfWriter writer, RtfTable mainTable) {
super();
this.writer = writer;
this.mainTable = mainTable;
}
/**
* Import a Cell
.
* Cell
containing the data for this
* RtfCell
* @param cellLeft The position of the left border
* @param cellWidth The default width of a cell
* @param x The column index of this RtfCell
* @param y The row index of this RtfCell
* @param cellpadding the cellpadding
* @return the position of the right side of the cell
*/
public int importCell(Cell cell, int cellLeft, int cellWidth, int x, int y, int cellpadding) {
this.cellpadding = cellpadding;
// set this value in any case
this.cellWidth = cellWidth;
if (cell == null) {
cellRight = cellLeft + cellWidth;
return cellRight;
}
if (cell.cellWidth() != null && !cell.cellWidth().equals("")) {
this.cellWidth = (int) (Integer.parseInt(cell.cellWidth()) * RtfWriter.TWIPSFACTOR);
}
cellRight = cellLeft + this.cellWidth;
store = cell;
emptyCell = false;
if (cell.colspan() > 1) {
if (cell.rowspan() > 1) {
mergeType = MERGE_BOTH_FIRST;
for (int i = y; i < y + cell.rowspan(); i++) {
if (i > y) mainTable.setMerge(x, i, MERGE_VERT_PREV, this);
for (int j = x + 1; j < x + cell.colspan(); j++) {
mainTable.setMerge(j, i, MERGE_BOTH_PREV, this);
}
}
} else {
mergeType = MERGE_HORIZ_FIRST;
for (int i = x + 1; i < x + cell.colspan(); i++) {
mainTable.setMerge(i, y, MERGE_HORIZ_PREV, this);
}
}
} else if (cell.rowspan() > 1) {
mergeType = MERGE_VERT_FIRST;
for (int i = y + 1; i < y + cell.rowspan(); i++) {
mainTable.setMerge(x, i, MERGE_VERT_PREV, this);
}
}
return cellRight;
}
/**
* Write the properties of the RtfCell
.
*
* @param os The OutputStream
to which to write the properties
* of the RtfCell
to.
* @return true if writing the cell settings succeeded
* @throws DocumentException
*/
public boolean writeCellSettings(ByteArrayOutputStream os) throws DocumentException {
try {
float lWidth, tWidth, rWidth, bWidth;
byte[] lStyle, tStyle, rStyle, bStyle;
if (store instanceof RtfTableCell) {
RtfTableCell c = (RtfTableCell) store;
lWidth = c.leftBorderWidth();
tWidth = c.topBorderWidth();
rWidth = c.rightBorderWidth();
bWidth = c.bottomBorderWidth();
lStyle = RtfTableCell.getStyleControlWord(c.leftBorderStyle());
tStyle = RtfTableCell.getStyleControlWord(c.topBorderStyle());
rStyle = RtfTableCell.getStyleControlWord(c.rightBorderStyle());
bStyle = RtfTableCell.getStyleControlWord(c.bottomBorderStyle());
} else {
lWidth = tWidth = rWidth = bWidth = store.borderWidth();
lStyle = tStyle = rStyle = bStyle = RtfRow.tableBorder;
}
if (mergeType == MERGE_HORIZ_PREV || mergeType == MERGE_BOTH_PREV) {
return true;
}
switch (mergeType) {
case MERGE_VERT_FIRST:
os.write(RtfWriter.escape);
os.write(cellVMergeFirst);
break;
case MERGE_BOTH_FIRST:
os.write(RtfWriter.escape);
os.write(cellVMergeFirst);
break;
case MERGE_HORIZ_PREV:
os.write(RtfWriter.escape);
os.write(cellMergePrev);
break;
case MERGE_VERT_PREV:
os.write(RtfWriter.escape);
os.write(cellVMergePrev);
break;
case MERGE_BOTH_PREV:
os.write(RtfWriter.escape);
os.write(cellMergeFirst);
break;
}
switch (store.verticalAlignment()) {
case Element.ALIGN_BOTTOM:
os.write(RtfWriter.escape);
os.write(cellVerticalAlignBottom);
break;
case Element.ALIGN_CENTER:
case Element.ALIGN_MIDDLE:
os.write(RtfWriter.escape);
os.write(cellVerticalAlignCenter);
break;
case Element.ALIGN_TOP:
os.write(RtfWriter.escape);
os.write(cellVerticalAlignTop);
break;
}
if (((store.border() & Rectangle.LEFT) == Rectangle.LEFT) &&
(lWidth > 0)) {
os.write(RtfWriter.escape);
os.write(cellBorderLeft);
os.write(RtfWriter.escape);
os.write(lStyle);
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderWidth);
writeInt(os, (int) (lWidth * RtfWriter.TWIPSFACTOR));
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderColor);
if (store.borderColor() == null)
writeInt(os, writer.addColor(new
Color(0, 0, 0)));
else
writeInt(os, writer.addColor(store.borderColor()));
os.write((byte) '\n');
}
if (((store.border() & Rectangle.TOP) == Rectangle.TOP) && (tWidth > 0)) {
os.write(RtfWriter.escape);
os.write(cellBorderTop);
os.write(RtfWriter.escape);
os.write(tStyle);
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderWidth);
writeInt(os, (int) (tWidth * RtfWriter.TWIPSFACTOR));
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderColor);
if (store.borderColor() == null)
writeInt(os, writer.addColor(new
Color(0, 0, 0)));
else
writeInt(os, writer.addColor(store.borderColor()));
os.write((byte) '\n');
}
if (((store.border() & Rectangle.BOTTOM) == Rectangle.BOTTOM) &&
(bWidth > 0)) {
os.write(RtfWriter.escape);
os.write(cellBorderBottom);
os.write(RtfWriter.escape);
os.write(bStyle);
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderWidth);
writeInt(os, (int) (bWidth * RtfWriter.TWIPSFACTOR));
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderColor);
if (store.borderColor() == null)
writeInt(os, writer.addColor(new
Color(0, 0, 0)));
else
writeInt(os, writer.addColor(store.borderColor()));
os.write((byte) '\n');
}
if (((store.border() & Rectangle.RIGHT) == Rectangle.RIGHT) &&
(rWidth > 0)) {
os.write(RtfWriter.escape);
os.write(cellBorderRight);
os.write(RtfWriter.escape);
os.write(rStyle);
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderWidth);
writeInt(os, (int) (rWidth * RtfWriter.TWIPSFACTOR));
os.write(RtfWriter.escape);
os.write(RtfRow.tableBorderColor);
if (store.borderColor() == null)
writeInt(os, writer.addColor(new
Color(0, 0, 0)));
else
writeInt(os, writer.addColor(store.borderColor()));
os.write((byte) '\n');
}
os.write(RtfWriter.escape);
os.write(cellBackgroundColor);
if (store.backgroundColor() == null) {
writeInt(os, writer.addColor(new Color(255, 255, 255)));
} else {
writeInt(os, writer.addColor(store.backgroundColor()));
}
os.write((byte) '\n');
os.write(RtfWriter.escape);
os.write(cellWidthStyle);
os.write((byte) '\n');
os.write(RtfWriter.escape);
os.write(cellWidthTag);
writeInt(os, cellWidth);
os.write((byte) '\n');
if (cellpadding > 0) {
// values
os.write(RtfWriter.escape);
os.write(cellPaddingLeft);
writeInt(os, cellpadding / 2);
os.write(RtfWriter.escape);
os.write(cellPaddingTop);
writeInt(os, cellpadding / 2);
os.write(RtfWriter.escape);
os.write(cellPaddingRight);
writeInt(os, cellpadding / 2);
os.write(RtfWriter.escape);
os.write(cellPaddingBottom);
writeInt(os, cellpadding / 2);
// unit
os.write(RtfWriter.escape);
os.write(cellPaddingLeftUnit);
os.write(RtfWriter.escape);
os.write(cellPaddingTopUnit);
os.write(RtfWriter.escape);
os.write(cellPaddingRightUnit);
os.write(RtfWriter.escape);
os.write(cellPaddingBottomUnit);
}
os.write(RtfWriter.escape);
os.write(cellRightBorder);
writeInt(os, cellRight);
} catch (IOException e) {
return false;
}
return true;
}
/**
* Write the content of the RtfCell
.
*
* @param os The OutputStream
to which to write the content of
* the RtfCell
to.
* @return true if writing the cell content succeeded
* @throws DocumentException
*/
public boolean writeCellContent(ByteArrayOutputStream os) throws DocumentException {
try {
if (mergeType == MERGE_HORIZ_PREV || mergeType == MERGE_BOTH_PREV) {
return true;
}
if (!emptyCell) {
Iterator cellIterator = store.getElements();
Paragraph container = null;
while (cellIterator.hasNext()) {
Element element = (Element) cellIterator.next();
// should we wrap it in a paragraph
if(!(element instanceof Paragraph)) {
if(container != null) {
container.add(element);
} else {
container = new Paragraph();
container.setAlignment(store.horizontalAlignment());
container.add(element);
}
} else {
if(container != null) {
writer.addElement(container, os);
container =null;
container =null;
}
// if horizontal alignment is undefined overwrite
// with that of enclosing cell
if (element instanceof Paragraph && ((Paragraph) element).alignment() == Element.ALIGN_UNDEFINED) {
((Paragraph) element).setAlignment(store.horizontalAlignment());
}
writer.addElement(element, os);
if (element.type() == Element.PARAGRAPH && cellIterator.hasNext()) {
os.write(RtfWriter.escape);
os.write(RtfWriter.paragraph);
}
}
}
if(container != null) {
writer.addElement(container, os);
container =null;
}
} else {
os.write(RtfWriter.escape);
os.write(RtfWriter.paragraphDefaults);
os.write(RtfWriter.escape);
os.write(cellInTable);
}
os.write(RtfWriter.escape);
os.write(cellEnd);
} catch (IOException e) {
return false;
}
return true;
}
/**
* Sets the merge type and the RtfCell
with which this
* RtfCell
is to be merged.
*
* @param mergeType The merge type specifies the kind of merge to be applied
* (MERGE_HORIZ_PREV, MERGE_VERT_PREV, MERGE_BOTH_PREV)
* @param mergeCell The RtfCell
that the cell at x and y is to
* be merged with
*/
public void setMerge(int mergeType, RtfCell mergeCell) {
this.mergeType = mergeType;
store = mergeCell.getStore();
}
/**
* Get the Cell
with the actual content.
*
* @return Cell
which is contained in the RtfCell
*/
public Cell getStore() {
return store;
}
/**
* Get the with of this RtfCell
*
* @return Width of the current RtfCell
*/
public int getCellWidth() {
return cellWidth;
}
/**
* sets the width of the cell
* @param value a width
*/
public void setCellWidth(int value) {
cellWidth = value;
}
/**
* Get the position of the right border of this RtfCell
.
* @return position of the right border
*/
public int getCellRight() {
return cellRight;
}
/**
* Sets the right position of the cell
* @param value a cell position
*/
public void setCellRight(int value) {
cellRight = value;
}
/**
* Write an Integer to the Outputstream.
*
* @param out The OutputStream
to be written to.
* @param i The int to be written.
* @throws IOException
*/
private void writeInt(ByteArrayOutputStream out, int i) throws IOException {
out.write(Integer.toString(i).getBytes());
}
}