001: /**
002: * $Id: RtfRow.java 2748 2007-05-12 15:11:48Z blowagie $
003: * $Name$
004: *
005: * Copyright 2001, 2002 by Mark Hall
006: *
007: * The contents of this file are subject to the Mozilla Public License Version 1.1
008: * (the "License"); you may not use this file except in compliance with the License.
009: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the License.
014: *
015: * The Original Code is 'iText, a free JAVA-PDF library'.
016: *
017: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
018: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
019: * All Rights Reserved.
020: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
021: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
022: *
023: * Contributor(s): all the names of the contributors are added in the source code
024: * where applicable.
025: *
026: * Alternatively, the contents of this file may be used under the terms of the
027: * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
028: * provisions of LGPL are applicable instead of those above. If you wish to
029: * allow use of your version of this file only under the terms of the LGPL
030: * License and not to allow others to use your version of this file under
031: * the MPL, indicate your decision by deleting the provisions above and
032: * replace them with the notice and other provisions required by the LGPL.
033: * If you do not delete the provisions above, a recipient may use your version
034: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
035: *
036: * This library is free software; you can redistribute it and/or modify it
037: * under the terms of the MPL as stated above or under the terms of the GNU
038: * Library General Public License as published by the Free Software Foundation;
039: * either version 2 of the License, or any later version.
040: *
041: * This library is distributed in the hope that it will be useful, but WITHOUT
042: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
043: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
044: * details.
045: *
046: * If you didn't download this code from the following link, you should check if
047: * you aren't using an obsolete version:
048: * http://www.lowagie.com/iText/
049: */package com.lowagie.text.rtf;
050:
051: import java.awt.Color;
052: import java.io.ByteArrayOutputStream;
053: import java.io.IOException;
054: import java.util.ArrayList;
055: import java.util.Iterator;
056:
057: import com.lowagie.text.Cell;
058: import com.lowagie.text.DocumentException;
059: import com.lowagie.text.Element;
060: import com.lowagie.text.Rectangle;
061: import com.lowagie.text.Row;
062: import com.lowagie.text.Table;
063:
064: /**
065: * A Helper Class for the <CODE>RtfWriter</CODE>.
066: * <P>
067: * Do not use it directly
068: *
069: * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2.
070: *
071: * Parts of this Class were contributed by Steffen Stundzig. Many thanks for the
072: * improvements.
073: * Code added by c
074: * @deprecated Please move to the RtfWriter2 and associated classes.
075: */
076: public class RtfRow {
077: /** Table border solid */
078: public static final byte[] tableBorder = "brdrs".getBytes();
079: /** Table border width */
080: public static final byte[] tableBorderWidth = "brdrw".getBytes();
081: /** Table border color */
082: public static final byte[] tableBorderColor = "brdrcf".getBytes();
083:
084: /** Table row defaults */
085: private static final byte[] rowBegin = "trowd".getBytes();
086: /** End of table row */
087: private static final byte[] rowEnd = "row".getBytes();
088: /** Table row autofit */
089: private static final byte[] rowAutofit = "trautofit1".getBytes();
090: private static final byte[] graphLeft = "trgaph".getBytes();
091: /** Row border left */
092: private static final byte[] rowBorderLeft = "trbrdrl".getBytes();
093: /** Row border right */
094: private static final byte[] rowBorderRight = "trbrdrr".getBytes();
095: /** Row border top */
096: private static final byte[] rowBorderTop = "trbrdrt".getBytes();
097: /** Row border bottom */
098: private static final byte[] rowBorderBottom = "trbrdrb".getBytes();
099: /** Row border horiz inline */
100: private static final byte[] rowBorderInlineHorizontal = "trbrdrh"
101: .getBytes();
102: /** Row border bottom */
103: private static final byte[] rowBorderInlineVertical = "trbrdrv"
104: .getBytes();
105: /** Default cell spacing left */
106: private static final byte[] rowSpacingLeft = "trspdl".getBytes();
107: /** Default cell spacing right */
108: private static final byte[] rowSpacingRight = "trspdr".getBytes();
109: /** Default cell spacing top */
110: private static final byte[] rowSpacingTop = "trspdt".getBytes();
111: /** Default cell spacing bottom */
112: private static final byte[] rowSpacingBottom = "trspdb".getBytes();
113: /** Default cell spacing format left */
114: private static final byte[] rowSpacingLeftStyle = "trspdfl3"
115: .getBytes();
116: /** Default cell spacing format right */
117: private static final byte[] rowSpacingRightStyle = "trspdfr3"
118: .getBytes();
119: /** Default cell spacing format top */
120: private static final byte[] rowSpacingTopStyle = "trspdft3"
121: .getBytes();
122: /** Default cell spacing format bottom */
123: private static final byte[] rowSpacingBottomStyle = "trspdfb3"
124: .getBytes();
125: /** Default cell padding left */
126: private static final byte[] rowPaddingLeft = "trpaddl".getBytes();
127: /** Default cell padding right */
128: private static final byte[] rowPaddingRight = "trpaddr".getBytes();
129: /** Default cell padding format left */
130: private static final byte[] rowPaddingLeftStyle = "trpaddfl3"
131: .getBytes();
132: /** Default cell padding format right */
133: private static final byte[] rowPaddingRightStyle = "trpaddfr3"
134: .getBytes();
135: /** Row width format */
136: private static final byte[] rowWidthStyle = "trftsWidth3"
137: .getBytes();
138: /** Row width */
139: private static final byte[] rowWidth = "trwWidth".getBytes();
140: /**
141: * Table row header. This row should appear at the top of every
142: * page the current table appears on.
143: */
144: private static final byte[] rowHeader = "trhdr".getBytes();
145: /**
146: * Table row keep together. This row cannot be split by a page break.
147: * This property is assumed to be off unless the control word is
148: * present.
149: */
150: private static final byte[] rowKeep = "trkeep".getBytes();
151: /** Table alignment left */
152: private static final byte[] rowAlignLeft = "trql".getBytes();
153: /** Table alignment center */
154: private static final byte[] rowAlignCenter = "trqc".getBytes();
155: /** Table alignment right */
156: private static final byte[] rowAlignRight = "trqr".getBytes();
157:
158: /** List of <code>RtfCell</code>s in this <code>RtfRow</code> */
159: private ArrayList cells = new ArrayList();
160: /** The <code>RtfWriter</code> to which this <code>RtfRow</code> belongs */
161: private RtfWriter writer = null;
162: /** The <coce>RtfTable</code> to which this <code>RtfRow</code> belongs */
163: private RtfTable mainTable = null;
164:
165: /** The width of this <code>RtfRow</code> (in percent) */
166: private int width = 100;
167: /** The default cellpadding of <code>RtfCells</code> in this
168: * <code>RtfRow</code> */
169: private int cellpadding = 115;
170: /** The default cellspacing of <code>RtfCells</code> in this
171: * <code>RtfRow</code> */
172: private int cellspacing = 14;
173: /** The borders of this <code>RtfRow</code> */
174: private int borders = 0;
175: /** The border color of this <code>RtfRow</code> */
176: private java.awt.Color borderColor = null;
177: /** The border width of this <code>RtfRow</code> */
178: private float borderWidth = 0;
179:
180: /** Original Row */
181: private Row origRow = null;
182:
183: /**
184: * Create a new <code>RtfRow</code>.
185: *
186: * @param writer The <code>RtfWriter</code> that this <code>RtfRow</code> belongs to
187: * @param mainTable The <code>RtfTable</code> that created this
188: * <code>RtfRow</code>
189: */
190: public RtfRow(RtfWriter writer, RtfTable mainTable) {
191: super ();
192: this .writer = writer;
193: this .mainTable = mainTable;
194: }
195:
196: /**
197: * Pregenerate the <code>RtfCell</code>s in this <code>RtfRow</code>.
198: *
199: * @param columns The number of <code>RtfCell</code>s to be generated.
200: */
201: public void pregenerateRows(int columns) {
202: for (int i = 0; i < columns; i++) {
203: RtfCell rtfCell = new RtfCell(writer, mainTable);
204: cells.add(rtfCell);
205: }
206: }
207:
208: /**
209: * Import a <code>Row</code>.
210: * <P>
211: * All the parameters are taken from the <code>RtfTable</code> which contains
212: * this <code>RtfRow</code> and they do exactely what they say
213: * @param row
214: * @param propWidths in percent
215: * @param tableWidth in percent
216: * @param pageWidth
217: * @param cellpadding
218: * @param cellspacing
219: * @param borders
220: * @param borderColor
221: * @param borderWidth
222: * @param y
223: * @return true if importing the row succeeded
224: */
225: public boolean importRow(Row row, float[] propWidths,
226: int tableWidth, int pageWidth, int cellpadding,
227: int cellspacing, int borders, java.awt.Color borderColor,
228: float borderWidth, int y) {
229: // the width of this row is the absolute witdh, calculated from the
230: // proportional with of the table and the total width of the page
231: this .origRow = row;
232: this .width = pageWidth * tableWidth / 100;
233: this .cellpadding = cellpadding;
234: this .cellspacing = cellspacing;
235: this .borders = borders;
236: this .borderColor = borderColor;
237: this .borderWidth = borderWidth;
238:
239: if (this .borderWidth > 2)
240: this .borderWidth = 2;
241:
242: int cellLeft = 0;
243: for (int i = 0; i < row.getColumns(); i++) {
244: Element cell = (Element) row.getCell(i);
245:
246: // cellWidth is an absolute argument
247: // it's based on the absolute of this row and the proportional
248: // width of this column
249: int cellWidth = (int) (width * propWidths[i] / 100);
250: if (cell != null) {
251: if (cell.type() == Element.CELL) {
252: RtfCell rtfCell = (RtfCell) cells.get(i);
253: cellLeft = rtfCell.importCell((Cell) cell,
254: cellLeft, cellWidth, i, y, cellpadding);
255: }
256: } else {
257: RtfCell rtfCell = (RtfCell) cells.get(i);
258: cellLeft = rtfCell.importCell(null, cellLeft,
259: cellWidth, i, y, cellpadding);
260: }
261: }
262:
263: // recalculate the cell right border and the cumulative width
264: // on col spanning cells.
265: // col + row spanning cells are also handled by this loop, because the real cell of
266: // the upper left corner in such an col, row matrix is copied as first cell
267: // in each row in this matrix
268: int columns = row.getColumns();
269: for (int i = 0; i < columns; i++) {
270: RtfCell firstCell = (RtfCell) cells.get(i);
271: Cell cell = firstCell.getStore();
272: int cols = 0;
273: if (cell != null) {
274: cols = cell.getColspan();
275: }
276: if (cols > 1) {
277: RtfCell lastCell = (RtfCell) cells.get(i + cols - 1);
278: firstCell.setCellRight(lastCell.getCellRight());
279: int width = firstCell.getCellWidth();
280: for (int j = i + 1; j < i + cols; j++) {
281: RtfCell cCell = (RtfCell) cells.get(j);
282: width += cCell.getCellWidth();
283: }
284: firstCell.setCellWidth(width);
285: i += cols - 1;
286: }
287: }
288: return true;
289: }
290:
291: /**
292: * Write the <code>RtfRow</code> to the specified <code>OutputStream</code>.
293: *
294: * @param os The <code>OutputStream</code> to which this <code>RtfRow</code>
295: * should be written to.
296: * @param rowNum The <code>index</code> of this row in the containing table.
297: * @param table The <code>Table</code> which contains the original <code>Row</code>.
298: * @return true if writing the row succeeded
299: * @throws DocumentException
300: * @throws IOException
301: */
302: public boolean writeRow(ByteArrayOutputStream os, int rowNum,
303: Table table) throws DocumentException, IOException {
304: os.write(RtfWriter.escape);
305: os.write(rowBegin);
306: os.write((byte) '\n');
307: os.write(RtfWriter.escape);
308: os.write(rowWidthStyle);
309: os.write(RtfWriter.escape);
310: os.write(rowWidth);
311: writeInt(os, width);
312: // os.write(RtfWriter.escape);
313: // os.write(rowAutofit);
314: if (mainTable.getOriginalTable().isCellsFitPage()) {
315: os.write(RtfWriter.escape);
316: os.write(rowKeep);
317: }
318: // check if this row is a header row
319: if (rowNum < table.getLastHeaderRow() + 1) {
320: os.write(RtfWriter.escape);
321: os.write(rowHeader);
322: }
323: os.write(RtfWriter.escape);
324: switch (this .origRow.getHorizontalAlignment()) {
325: case Element.ALIGN_LEFT:
326: os.write(rowAlignLeft);
327: break;
328: case Element.ALIGN_CENTER:
329: os.write(rowAlignCenter);
330: break;
331: case Element.ALIGN_RIGHT:
332: os.write(rowAlignRight);
333: break;
334: default:
335: os.write(rowAlignLeft);
336: break;
337: }
338: os.write(RtfWriter.escape);
339: os.write(graphLeft);
340: writeInt(os, 10);
341: if (((borders & Rectangle.LEFT) == Rectangle.LEFT)
342: && (borderWidth > 0)) {
343: writeBorder(os, rowBorderLeft);
344: }
345: if (((borders & Rectangle.TOP) == Rectangle.TOP)
346: && (borderWidth > 0)) {
347: writeBorder(os, rowBorderTop);
348: }
349: if (((borders & Rectangle.BOTTOM) == Rectangle.BOTTOM)
350: && (borderWidth > 0)) {
351: writeBorder(os, rowBorderBottom);
352: }
353: if (((borders & Rectangle.RIGHT) == Rectangle.RIGHT)
354: && (borderWidth > 0)) {
355: writeBorder(os, rowBorderRight);
356: }
357: if (((borders & Rectangle.BOX) == Rectangle.BOX)
358: && (borderWidth > 0)) {
359: writeBorder(os, rowBorderInlineHorizontal);
360: writeBorder(os, rowBorderInlineVertical);
361: }
362:
363: if (cellspacing > 0) {
364: os.write(RtfWriter.escape);
365: os.write(rowSpacingLeft);
366: writeInt(os, cellspacing / 2);
367: os.write(RtfWriter.escape);
368: os.write(rowSpacingLeftStyle);
369: os.write(RtfWriter.escape);
370: os.write(rowSpacingTop);
371: writeInt(os, cellspacing / 2);
372: os.write(RtfWriter.escape);
373: os.write(rowSpacingTopStyle);
374: os.write(RtfWriter.escape);
375: os.write(rowSpacingBottom);
376: writeInt(os, cellspacing / 2);
377: os.write(RtfWriter.escape);
378: os.write(rowSpacingBottomStyle);
379: os.write(RtfWriter.escape);
380: os.write(rowSpacingRight);
381: writeInt(os, cellspacing / 2);
382: os.write(RtfWriter.escape);
383: os.write(rowSpacingRightStyle);
384: }
385: os.write(RtfWriter.escape);
386: os.write(rowPaddingLeft);
387: writeInt(os, cellpadding / 2);
388: os.write(RtfWriter.escape);
389: os.write(rowPaddingRight);
390: writeInt(os, cellpadding / 2);
391: os.write(RtfWriter.escape);
392: os.write(rowPaddingLeftStyle);
393: os.write(RtfWriter.escape);
394: os.write(rowPaddingRightStyle);
395: os.write((byte) '\n');
396:
397: Iterator cellIterator = cells.iterator();
398: while (cellIterator.hasNext()) {
399: RtfCell cell = (RtfCell) cellIterator.next();
400: cell.writeCellSettings(os);
401: }
402:
403: os.write(RtfWriter.escape);
404: os.write("intbl".getBytes());
405:
406: cellIterator = cells.iterator();
407: while (cellIterator.hasNext()) {
408: RtfCell cell = (RtfCell) cellIterator.next();
409: cell.writeCellContent(os);
410: }
411: os.write(RtfWriter.delimiter);
412: os.write(RtfWriter.escape);
413: os.write(rowEnd);
414: return true;
415: }
416:
417: private void writeBorder(ByteArrayOutputStream os, byte[] borderType)
418: throws IOException {
419: // horizontal and vertical, top, left, bottom, right
420: os.write(RtfWriter.escape);
421: os.write(borderType);
422: // line style
423: os.write(RtfWriter.escape);
424: os.write(RtfRow.tableBorder);
425: // borderwidth
426: os.write(RtfWriter.escape);
427: os.write(RtfRow.tableBorderWidth);
428: writeInt(os, (int) (borderWidth * RtfWriter.TWIPSFACTOR));
429: // border color
430: os.write(RtfWriter.escape);
431: os.write(RtfRow.tableBorderColor);
432: if (borderColor == null) {
433: writeInt(os, writer.addColor(new Color(0, 0, 0)));
434: } else {
435: writeInt(os, writer.addColor(borderColor));
436: }
437: os.write((byte) '\n');
438: }
439:
440: /**
441: * <code>RtfTable</code>s call this method from their own setMerge() to
442: * specify that a certain other cell is to be merged with it.
443: *
444: * @param x The column position of the cell to be merged
445: * @param mergeType The merge type specifies the kind of merge to be applied
446: * (MERGE_HORIZ_PREV, MERGE_VERT_PREV, MERGE_BOTH_PREV)
447: * @param mergeCell The <code>RtfCell</code> that the cell at x and y is to
448: * be merged with
449: */
450: public void setMerge(int x, int mergeType, RtfCell mergeCell) {
451: RtfCell cell = (RtfCell) cells.get(x);
452: cell.setMerge(mergeType, mergeCell);
453: }
454:
455: /*
456: * Write an Integer to the Outputstream.
457: *
458: * @param out The <code>OutputStream</code> to be written to.
459: * @param i The int to be written.
460: */
461: private void writeInt(ByteArrayOutputStream out, int i)
462: throws IOException {
463: out.write(Integer.toString(i).getBytes());
464: }
465: }
|