/** * $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 * @deprecated Please move to the RtfWriter2 and associated classes. */ public class RtfCell { /** Constants for merging Cells */ /** A possible value for merging */ private static final int MERGE_HORIZ_FIRST = 1; /** A possible value for merging */ private static final int MERGE_VERT_FIRST = 2; /** A possible value for merging */ private static final int MERGE_BOTH_FIRST = 3; /** A possible value for merging */ private static final int MERGE_HORIZ_PREV = 4; /** A possible value for merging */ private static final int MERGE_VERT_PREV = 5; /** A possible value for merging */ private static final int MERGE_BOTH_PREV = 6; /** * RTF Tags */ /** First cell to merge with - Horizontal */ private static final byte[] cellMergeFirst = "clmgf".getBytes(); /** First cell to merge with - Vertical */ private static final byte[] cellVMergeFirst = "clvmgf".getBytes(); /** Merge cell with previous horizontal cell */ private static final byte[] cellMergePrev = "clmrg".getBytes(); /** Merge cell with previous vertical cell */ private static final byte[] cellVMergePrev = "clvmrg".getBytes(); /** Cell content vertical alignment bottom */ private static final byte[] cellVerticalAlignBottom = "clvertalb".getBytes(); /** Cell content vertical alignment center */ private static final byte[] cellVerticalAlignCenter = "clvertalc".getBytes(); /** Cell content vertical alignment top */ private static final byte[] cellVerticalAlignTop = "clvertalt".getBytes(); /** Cell border left */ private static final byte[] cellBorderLeft = "clbrdrl".getBytes(); /** Cell border right */ private static final byte[] cellBorderRight = "clbrdrr".getBytes(); /** Cell border top */ private static final byte[] cellBorderTop = "clbrdrt".getBytes(); /** Cell border bottom */ private static final byte[] cellBorderBottom = "clbrdrb".getBytes(); /** Cell background color */ private static final byte[] cellBackgroundColor = "clcbpat".getBytes(); /** Cell width format */ private static final byte[] cellWidthStyle = "clftsWidth3".getBytes(); /** Cell width */ private static final byte[] cellWidthTag = "clwWidth".getBytes(); /** Cell right border position */ private static final byte[] cellRightBorder = "cellx".getBytes(); /** Cell is part of table */ protected static final byte[] cellInTable = "intbl".getBytes(); /** End of cell */ private static final byte[] cellEnd = "cell".getBytes(); /** padding top */ private static final byte[] cellPaddingTop = "clpadt".getBytes(); /** padding top unit */ private static final byte[] cellPaddingTopUnit = "clpadft3".getBytes(); /** padding bottom */ private static final byte[] cellPaddingBottom = "clpadb".getBytes(); /** padding bottom unit */ private static final byte[] cellPaddingBottomUnit = "clpadfb3".getBytes(); /** padding left */ private static final byte[] cellPaddingLeft = "clpadl".getBytes(); /** padding left unit */ private static final byte[] cellPaddingLeftUnit = "clpadfl3".getBytes(); /** padding right */ private static final byte[] cellPaddingRight = "clpadr".getBytes(); /** padding right unit */ private static final byte[] cellPaddingRightUnit = "clpadfr3".getBytes(); /** 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. *

* @param cell The 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()); } }