001: /*
002: * $Id: RtfRow.java 2776 2007-05-23 20:01:40Z hallm $
003: * $Name$
004: *
005: * Copyright 2001, 2002, 2003, 2004, 2005 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: */
050:
051: package com.lowagie.text.rtf.table;
052:
053: import java.io.ByteArrayOutputStream;
054: import java.io.IOException;
055: import java.io.OutputStream;
056: import java.util.ArrayList;
057:
058: import com.lowagie.text.Cell;
059: import com.lowagie.text.Element;
060: import com.lowagie.text.Row;
061: import com.lowagie.text.rtf.RtfElement;
062: import com.lowagie.text.rtf.document.RtfDocument;
063:
064: /**
065: * The RtfRow wraps one Row for a RtfTable.
066: * INTERNAL USE ONLY
067: *
068: * @version $Id: RtfRow.java 2776 2007-05-23 20:01:40Z hallm $
069: * @author Mark Hall (mhall@edu.uni-klu.ac.at)
070: * @author Steffen Stundzig
071: * @author Lorenz Maierhofer
072: * @author Thomas Bickel (tmb99@inode.at)
073: */
074: public class RtfRow extends RtfElement {
075:
076: /**
077: * Constant for the RtfRow beginning
078: */
079: private static final byte[] ROW_BEGIN = "\\trowd".getBytes();
080: /**
081: * Constant for the RtfRow width style
082: */
083: private static final byte[] ROW_WIDTH_STYLE = "\\trftsWidth3"
084: .getBytes();
085: /**
086: * Constant for the RtfRow width
087: */
088: private static final byte[] ROW_WIDTH = "\\trwWidth".getBytes();
089: /**
090: * Constant to specify that this RtfRow are not to be broken across pages
091: */
092: private static final byte[] ROW_KEEP_TOGETHER = "\\trkeep"
093: .getBytes();
094: /**
095: * Constant to specify that this is a header RtfRow
096: */
097: private static final byte[] ROW_HEADER_ROW = "\\trhdr".getBytes();
098: /**
099: * Constant for left alignment of this RtfRow
100: */
101: private static final byte[] ROW_ALIGN_LEFT = "\\trql".getBytes();
102: /**
103: * Constant for right alignment of this RtfRow
104: */
105: private static final byte[] ROW_ALIGN_RIGHT = "\\trqr".getBytes();
106: /**
107: * Constant for center alignment of this RtfRow
108: */
109: private static final byte[] ROW_ALIGN_CENTER = "\\trqc".getBytes();
110: /**
111: * Constant for justified alignment of this RtfRow
112: */
113: private static final byte[] ROW_ALIGN_JUSTIFIED = "\\trqj"
114: .getBytes();
115: /**
116: * Constant for the graph style of this RtfRow
117: */
118: private static final byte[] ROW_GRAPH = "\\trgaph10".getBytes();
119: /**
120: * Constant for the cell left spacing
121: */
122: private static final byte[] ROW_CELL_SPACING_LEFT = "\\trspdl"
123: .getBytes();
124: /**
125: * Constant for the cell top spacing
126: */
127: private static final byte[] ROW_CELL_SPACING_TOP = "\\trspdt"
128: .getBytes();
129: /**
130: * Constant for the cell right spacing
131: */
132: private static final byte[] ROW_CELL_SPACING_RIGHT = "\\trspdr"
133: .getBytes();
134: /**
135: * Constant for the cell bottom spacing
136: */
137: private static final byte[] ROW_CELL_SPACING_BOTTOM = "\\trspdb"
138: .getBytes();
139: /**
140: * Constant for the cell left spacing style
141: */
142: private static final byte[] ROW_CELL_SPACING_LEFT_STYLE = "\\trspdfl3"
143: .getBytes();
144: /**
145: * Constant for the cell top spacing style
146: */
147: private static final byte[] ROW_CELL_SPACING_TOP_STYLE = "\\trspdft3"
148: .getBytes();
149: /**
150: * Constant for the cell right spacing style
151: */
152: private static final byte[] ROW_CELL_SPACING_RIGHT_STYLE = "\\trspdfr3"
153: .getBytes();
154: /**
155: * Constant for the cell bottom spacing style
156: */
157: private static final byte[] ROW_CELL_SPACING_BOTTOM_STYLE = "\\trspdfb3"
158: .getBytes();
159: /**
160: * Constant for the cell left padding
161: */
162: private static final byte[] ROW_CELL_PADDING_LEFT = "\\trpaddl"
163: .getBytes();
164: /**
165: * Constant for the cell right padding
166: */
167: private static final byte[] ROW_CELL_PADDING_RIGHT = "\\trpaddr"
168: .getBytes();
169: /**
170: * Constant for the cell left padding style
171: */
172: private static final byte[] ROW_CELL_PADDING_LEFT_STYLE = "\\trpaddfl3"
173: .getBytes();
174: /**
175: * Constant for the cell right padding style
176: */
177: private static final byte[] ROW_CELL_PADDING_RIGHT_STYLE = "\\trpaddfr3"
178: .getBytes();
179: /**
180: * Constant for the end of a row
181: */
182: private static final byte[] ROW_END = "\\row".getBytes();
183:
184: /**
185: * The RtfTable this RtfRow belongs to
186: */
187: private RtfTable parentTable = null;
188: /**
189: * The cells of this RtfRow
190: */
191: private ArrayList cells = null;
192: /**
193: * The width of this row
194: */
195: private int width = 0;
196: /**
197: * The row number
198: */
199: private int rowNumber = 0;
200:
201: /**
202: * Constructs a RtfRow for a Row.
203: *
204: * @param doc The RtfDocument this RtfRow belongs to
205: * @param rtfTable The RtfTable this RtfRow belongs to
206: * @param row The Row this RtfRow is based on
207: * @param rowNumber The number of this row
208: */
209: protected RtfRow(RtfDocument doc, RtfTable rtfTable, Row row,
210: int rowNumber) {
211: super (doc);
212: this .parentTable = rtfTable;
213: this .rowNumber = rowNumber;
214: importRow(row);
215: }
216:
217: /**
218: * Imports a Row and copies all settings
219: *
220: * @param row The Row to import
221: */
222: private void importRow(Row row) {
223: this .cells = new ArrayList();
224: this .width = this .document.getDocumentHeader().getPageSetting()
225: .getPageWidth()
226: - this .document.getDocumentHeader().getPageSetting()
227: .getMarginLeft()
228: - this .document.getDocumentHeader().getPageSetting()
229: .getMarginRight();
230: this .width = (int) (this .width
231: * this .parentTable.getTableWidthPercent() / 100);
232:
233: int cellRight = 0;
234: int cellWidth = 0;
235: for (int i = 0; i < row.getColumns(); i++) {
236: cellWidth = (int) (this .width
237: * this .parentTable.getProportionalWidths()[i] / 100);
238: cellRight = cellRight + cellWidth;
239:
240: Cell cell = (Cell) row.getCell(i);
241: RtfCell rtfCell = new RtfCell(this .document, this , cell);
242: rtfCell.setCellRight(cellRight);
243: rtfCell.setCellWidth(cellWidth);
244: this .cells.add(rtfCell);
245: }
246: }
247:
248: /**
249: * Performs a second pass over all cells to handle cell row/column spanning.
250: */
251: protected void handleCellSpanning() {
252: RtfCell deletedCell = new RtfCell(true);
253: for (int i = 0; i < this .cells.size(); i++) {
254: RtfCell rtfCell = (RtfCell) this .cells.get(i);
255: if (rtfCell.getColspan() > 1) {
256: int cSpan = rtfCell.getColspan();
257: for (int j = i + 1; j < i + cSpan; j++) {
258: if (j < this .cells.size()) {
259: RtfCell rtfCellMerge = (RtfCell) this .cells
260: .get(j);
261: rtfCell.setCellRight(rtfCell.getCellRight()
262: + rtfCellMerge.getCellWidth());
263: rtfCell.setCellWidth(rtfCell.getCellWidth()
264: + rtfCellMerge.getCellWidth());
265: this .cells.set(j, deletedCell);
266: }
267: }
268: }
269: if (rtfCell.getRowspan() > 1) {
270: ArrayList rows = this .parentTable.getRows();
271: for (int j = 1; j < rtfCell.getRowspan(); j++) {
272: RtfRow mergeRow = (RtfRow) rows.get(this .rowNumber
273: + j);
274: if (this .rowNumber + j < rows.size()) {
275: RtfCell rtfCellMerge = (RtfCell) mergeRow
276: .getCells().get(i);
277: rtfCellMerge.setCellMergeChild(rtfCell);
278: }
279: if (rtfCell.getColspan() > 1) {
280: int cSpan = rtfCell.getColspan();
281: for (int k = i + 1; k < i + cSpan; k++) {
282: if (k < mergeRow.getCells().size()) {
283: mergeRow.getCells().set(k, deletedCell);
284: }
285: }
286: }
287: }
288: }
289: }
290: }
291:
292: /**
293: * Cleans the deleted RtfCells from the total RtfCells.
294: */
295: protected void cleanRow() {
296: int i = 0;
297: while (i < this .cells.size()) {
298: if (((RtfCell) this .cells.get(i)).isDeleted()) {
299: this .cells.remove(i);
300: } else {
301: i++;
302: }
303: }
304: }
305:
306: /**
307: * Writes the row definition/settings.
308: *
309: * @return A byte array with the row definitions/settings.
310: * @deprecated replaced by {@link #writeRowDefinitions(OutputStream)}
311: */
312: private byte[] writeRowDefinitions() {
313: ByteArrayOutputStream result = new ByteArrayOutputStream();
314: try {
315: writeRowDefinitions(result);
316: } catch (IOException ioe) {
317: ioe.printStackTrace();
318: }
319: return result.toByteArray();
320: }
321:
322: /**
323: * Writes the row definition/settings.
324: */
325: private void writeRowDefinitions(final OutputStream result)
326: throws IOException {
327: result.write(ROW_BEGIN);
328: result.write('\n');
329: result.write(ROW_WIDTH_STYLE);
330: result.write(ROW_WIDTH);
331: result.write(intToByteArray(this .width));
332: if (this .parentTable.getCellsFitToPage()) {
333: result.write(ROW_KEEP_TOGETHER);
334: }
335: if (this .rowNumber <= this .parentTable.getHeaderRows()) {
336: result.write(ROW_HEADER_ROW);
337: }
338: switch (this .parentTable.getAlignment()) {
339: case Element.ALIGN_LEFT:
340: result.write(ROW_ALIGN_LEFT);
341: break;
342: case Element.ALIGN_RIGHT:
343: result.write(ROW_ALIGN_RIGHT);
344: break;
345: case Element.ALIGN_CENTER:
346: result.write(ROW_ALIGN_CENTER);
347: break;
348: case Element.ALIGN_JUSTIFIED:
349: case Element.ALIGN_JUSTIFIED_ALL:
350: result.write(ROW_ALIGN_JUSTIFIED);
351: break;
352: }
353: result.write(ROW_GRAPH);
354:
355: //.result.write(this.parentTable.getBorders().write());
356: this .parentTable.getBorders().writeContent(result);
357:
358: if (this .parentTable.getCellSpacing() > 0) {
359: result.write(ROW_CELL_SPACING_LEFT);
360: result.write(intToByteArray((int) (this .parentTable
361: .getCellSpacing() / 2)));
362: result.write(ROW_CELL_SPACING_LEFT_STYLE);
363: result.write(ROW_CELL_SPACING_TOP);
364: result.write(intToByteArray((int) (this .parentTable
365: .getCellSpacing() / 2)));
366: result.write(ROW_CELL_SPACING_TOP_STYLE);
367: result.write(ROW_CELL_SPACING_RIGHT);
368: result.write(intToByteArray((int) (this .parentTable
369: .getCellSpacing() / 2)));
370: result.write(ROW_CELL_SPACING_RIGHT_STYLE);
371: result.write(ROW_CELL_SPACING_BOTTOM);
372: result.write(intToByteArray((int) (this .parentTable
373: .getCellSpacing() / 2)));
374: result.write(ROW_CELL_SPACING_BOTTOM_STYLE);
375: }
376:
377: result.write(ROW_CELL_PADDING_LEFT);
378: result.write(intToByteArray((int) (this .parentTable
379: .getCellPadding() / 2)));
380: result.write(ROW_CELL_PADDING_RIGHT);
381: result.write(intToByteArray((int) (this .parentTable
382: .getCellPadding() / 2)));
383: result.write(ROW_CELL_PADDING_LEFT_STYLE);
384: result.write(ROW_CELL_PADDING_RIGHT_STYLE);
385:
386: result.write('\n');
387:
388: for (int i = 0; i < this .cells.size(); i++) {
389: RtfCell rtfCell = (RtfCell) this .cells.get(i);
390: //result.write(rtfCell.writeDefinition());
391: rtfCell.writeDefinition(result);
392: }
393: }
394:
395: /**
396: * Writes the content of this RtfRow
397: *
398: * @return A byte array with the content of this RtfRow
399: * @deprecated replaced by {@link #writeContent(OutputStream)}
400: */
401: public byte[] write() {
402: ByteArrayOutputStream result = new ByteArrayOutputStream();
403: try {
404: writeContent(result);
405: } catch (IOException ioe) {
406: ioe.printStackTrace();
407: }
408: return result.toByteArray();
409: }
410:
411: /**
412: * Writes the content of this RtfRow
413: */
414: public void writeContent(final OutputStream result)
415: throws IOException {
416: //.result.write(writeRowDefinitions());
417: writeRowDefinitions(result);
418:
419: for (int i = 0; i < this .cells.size(); i++) {
420: RtfCell rtfCell = (RtfCell) this .cells.get(i);
421: //.result.write(rtfCell.write());
422: rtfCell.writeContent(result);
423: }
424:
425: result.write(DELIMITER);
426:
427: if (this .document.getDocumentSettings()
428: .isOutputTableRowDefinitionAfter()) {
429: //.result.write(writeRowDefinitions());
430: writeRowDefinitions(result);
431: }
432:
433: result.write(ROW_END);
434: result.write("\n".getBytes());
435: }
436:
437: /**
438: * Gets the parent RtfTable of this RtfRow
439: *
440: * @return The parent RtfTable of this RtfRow
441: */
442: protected RtfTable getParentTable() {
443: return this .parentTable;
444: }
445:
446: /**
447: * Gets the cells of this RtfRow
448: *
449: * @return The cells of this RtfRow
450: */
451: protected ArrayList getCells() {
452: return this.cells;
453: }
454: }
|