1 /* 2 * $Id$ 3 * 4 * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall 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.rtf.table; 51 52 import java.io.IOException; 53 import java.io.OutputStream; 54 import java.util.ArrayList; 55 56 import com.lowagie.text.Cell; 57 import com.lowagie.text.DocWriter; 58 import com.lowagie.text.Element; 59 import com.lowagie.text.Row; 60 import com.lowagie.text.pdf.PdfPCell; 61 import com.lowagie.text.pdf.PdfPRow; 62 import com.lowagie.text.rtf.RtfElement; 63 import com.lowagie.text.rtf.document.RtfDocument; 64 65 66 /** 67 * The RtfRow wraps one Row for a RtfTable. 68 * INTERNAL USE ONLY 69 * 70 * @version $Id$ 71 * @author Mark Hall (Mark.Hall@mail.room3b.eu) 72 * @author Steffen Stundzig 73 * @author Lorenz Maierhofer 74 * @author Thomas Bickel (tmb99@inode.at) 75 */ 76 public class RtfRow extends RtfElement { 77 78 /** 79 * Constant for the RtfRow beginning 80 */ 81 private static final byte[] ROW_BEGIN = DocWriter.getISOBytes("\\trowd"); 82 /** 83 * Constant for the RtfRow width style 84 */ 85 private static final byte[] ROW_WIDTH_STYLE = DocWriter.getISOBytes("\\trftsWidth3"); 86 /** 87 * Constant for the RtfRow width 88 */ 89 private static final byte[] ROW_WIDTH = DocWriter.getISOBytes("\\trwWidth"); 90 /** 91 * Constant to specify that this RtfRow are not to be broken across pages 92 */ 93 private static final byte[] ROW_KEEP_TOGETHER = DocWriter.getISOBytes("\\trkeep"); 94 /** 95 * Constant to specify that this is a header RtfRow 96 */ 97 private static final byte[] ROW_HEADER_ROW = DocWriter.getISOBytes("\\trhdr"); 98 /** 99 * Constant for left alignment of this RtfRow 100 */ 101 private static final byte[] ROW_ALIGN_LEFT = DocWriter.getISOBytes("\\trql"); 102 /** 103 * Constant for right alignment of this RtfRow 104 */ 105 private static final byte[] ROW_ALIGN_RIGHT = DocWriter.getISOBytes("\\trqr"); 106 /** 107 * Constant for center alignment of this RtfRow 108 */ 109 private static final byte[] ROW_ALIGN_CENTER = DocWriter.getISOBytes("\\trqc"); 110 /** 111 * Constant for justified alignment of this RtfRow 112 */ 113 private static final byte[] ROW_ALIGN_JUSTIFIED = DocWriter.getISOBytes("\\trqj"); 114 /** 115 * Constant for the graph style of this RtfRow 116 */ 117 private static final byte[] ROW_GRAPH = DocWriter.getISOBytes("\\trgaph10"); 118 /** 119 * Constant for the cell left spacing 120 */ 121 private static final byte[] ROW_CELL_SPACING_LEFT = DocWriter.getISOBytes("\\trspdl"); 122 /** 123 * Constant for the cell top spacing 124 */ 125 private static final byte[] ROW_CELL_SPACING_TOP = DocWriter.getISOBytes("\\trspdt"); 126 /** 127 * Constant for the cell right spacing 128 */ 129 private static final byte[] ROW_CELL_SPACING_RIGHT = DocWriter.getISOBytes("\\trspdr"); 130 /** 131 * Constant for the cell bottom spacing 132 */ 133 private static final byte[] ROW_CELL_SPACING_BOTTOM = DocWriter.getISOBytes("\\trspdb"); 134 /** 135 * Constant for the cell left spacing style 136 */ 137 private static final byte[] ROW_CELL_SPACING_LEFT_STYLE = DocWriter.getISOBytes("\\trspdfl3"); 138 /** 139 * Constant for the cell top spacing style 140 */ 141 private static final byte[] ROW_CELL_SPACING_TOP_STYLE = DocWriter.getISOBytes("\\trspdft3"); 142 /** 143 * Constant for the cell right spacing style 144 */ 145 private static final byte[] ROW_CELL_SPACING_RIGHT_STYLE = DocWriter.getISOBytes("\\trspdfr3"); 146 /** 147 * Constant for the cell bottom spacing style 148 */ 149 private static final byte[] ROW_CELL_SPACING_BOTTOM_STYLE = DocWriter.getISOBytes("\\trspdfb3"); 150 /** 151 * Constant for the cell left padding 152 */ 153 private static final byte[] ROW_CELL_PADDING_LEFT = DocWriter.getISOBytes("\\trpaddl"); 154 /** 155 * Constant for the cell right padding 156 */ 157 private static final byte[] ROW_CELL_PADDING_RIGHT = DocWriter.getISOBytes("\\trpaddr"); 158 /** 159 * Constant for the cell left padding style 160 */ 161 private static final byte[] ROW_CELL_PADDING_LEFT_STYLE = DocWriter.getISOBytes("\\trpaddfl3"); 162 /** 163 * Constant for the cell right padding style 164 */ 165 private static final byte[] ROW_CELL_PADDING_RIGHT_STYLE = DocWriter.getISOBytes("\\trpaddfr3"); 166 /** 167 * Constant for the end of a row 168 */ 169 private static final byte[] ROW_END = DocWriter.getISOBytes("\\row"); 170 171 /** 172 * The RtfTable this RtfRow belongs to 173 */ 174 private RtfTable parentTable = null; 175 /** 176 * The cells of this RtfRow 177 */ 178 private ArrayList cells = null; 179 /** 180 * The width of this row 181 */ 182 private int width = 0; 183 /** 184 * The row number 185 */ 186 private int rowNumber = 0; 187 188 /** 189 * Constructs a RtfRow for a Row. 190 * 191 * @param doc The RtfDocument this RtfRow belongs to 192 * @param rtfTable The RtfTable this RtfRow belongs to 193 * @param row The Row this RtfRow is based on 194 * @param rowNumber The number of this row 195 */ RtfRow(RtfDocument doc, RtfTable rtfTable, Row row, int rowNumber)196 protected RtfRow(RtfDocument doc, RtfTable rtfTable, Row row, int rowNumber) { 197 super(doc); 198 this.parentTable = rtfTable; 199 this.rowNumber = rowNumber; 200 importRow(row); 201 } 202 203 /** 204 * Constructs a RtfRow for a Row. 205 * 206 * @param doc The RtfDocument this RtfRow belongs to 207 * @param rtfTable The RtfTable this RtfRow belongs to 208 * @param row The Row this RtfRow is based on 209 * @param rowNumber The number of this row 210 * @since 2.1.3 211 */ RtfRow(RtfDocument doc, RtfTable rtfTable, PdfPRow row, int rowNumber)212 protected RtfRow(RtfDocument doc, RtfTable rtfTable, PdfPRow row, int rowNumber) { 213 super(doc); 214 this.parentTable = rtfTable; 215 this.rowNumber = rowNumber; 216 importRow(row); 217 } 218 219 220 /** 221 * Imports a Row and copies all settings 222 * 223 * @param row The Row to import 224 */ importRow(Row row)225 private void importRow(Row row) { 226 this.cells = new ArrayList(); 227 this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight(); 228 this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100); 229 230 int cellRight = 0; 231 int cellWidth = 0; 232 for(int i = 0; i < row.getColumns(); i++) { 233 cellWidth = (int) (this.width * this.parentTable.getProportionalWidths()[i] / 100); 234 cellRight = cellRight + cellWidth; 235 236 Cell cell = (Cell) row.getCell(i); 237 RtfCell rtfCell = new RtfCell(this.document, this, cell); 238 rtfCell.setCellRight(cellRight); 239 rtfCell.setCellWidth(cellWidth); 240 this.cells.add(rtfCell); 241 } 242 } 243 /** 244 * Imports a PdfPRow and copies all settings 245 * 246 * @param row The PdfPRow to import 247 * @since 2.1.3 248 */ importRow(PdfPRow row)249 private void importRow(PdfPRow row) { 250 this.cells = new ArrayList(); 251 this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight(); 252 this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100); 253 254 int cellRight = 0; 255 int cellWidth = 0; 256 PdfPCell[] cells = row.getCells(); 257 for(int i = 0; i < cells.length; i++) { 258 cellWidth = (int) (this.width * this.parentTable.getProportionalWidths()[i] / 100); 259 cellRight = cellRight + cellWidth; 260 261 PdfPCell cell = cells[i]; 262 RtfCell rtfCell = new RtfCell(this.document, this, cell); 263 rtfCell.setCellRight(cellRight); 264 rtfCell.setCellWidth(cellWidth); 265 this.cells.add(rtfCell); 266 } 267 } 268 /** 269 * Performs a second pass over all cells to handle cell row/column spanning. 270 */ handleCellSpanning()271 protected void handleCellSpanning() { 272 RtfCell deletedCell = new RtfCell(true); 273 for(int i = 0; i < this.cells.size(); i++) { 274 RtfCell rtfCell = (RtfCell) this.cells.get(i); 275 if(rtfCell.getColspan() > 1) { 276 int cSpan = rtfCell.getColspan(); 277 for(int j = i + 1; j < i + cSpan; j++) { 278 if(j < this.cells.size()) { 279 RtfCell rtfCellMerge = (RtfCell) this.cells.get(j); 280 rtfCell.setCellRight(rtfCell.getCellRight() + rtfCellMerge.getCellWidth()); 281 rtfCell.setCellWidth(rtfCell.getCellWidth() + rtfCellMerge.getCellWidth()); 282 this.cells.set(j, deletedCell); 283 } 284 } 285 } 286 if(rtfCell.getRowspan() > 1) { 287 ArrayList rows = this.parentTable.getRows(); 288 for(int j = 1; j < rtfCell.getRowspan(); j++) { 289 RtfRow mergeRow = (RtfRow) rows.get(this.rowNumber + j); 290 if(this.rowNumber + j < rows.size()) { 291 RtfCell rtfCellMerge = (RtfCell) mergeRow.getCells().get(i); 292 rtfCellMerge.setCellMergeChild(rtfCell); 293 } 294 if(rtfCell.getColspan() > 1) { 295 int cSpan = rtfCell.getColspan(); 296 for(int k = i + 1; k < i + cSpan; k++) { 297 if(k < mergeRow.getCells().size()) { 298 mergeRow.getCells().set(k, deletedCell); 299 } 300 } 301 } 302 } 303 } 304 } 305 } 306 307 /** 308 * Cleans the deleted RtfCells from the total RtfCells. 309 */ cleanRow()310 protected void cleanRow() { 311 int i = 0; 312 while(i < this.cells.size()) { 313 if(((RtfCell) this.cells.get(i)).isDeleted()) { 314 this.cells.remove(i); 315 } else { 316 i++; 317 } 318 } 319 } 320 321 /** 322 * Writes the row definition/settings. 323 * 324 * @param result The <code>OutputStream</code> to write the definitions to. 325 */ writeRowDefinition(final OutputStream result)326 private void writeRowDefinition(final OutputStream result) throws IOException { 327 result.write(ROW_BEGIN); 328 this.document.outputDebugLinebreak(result); 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 RtfBorderGroup borders =this.parentTable.getBorders(); 355 if(borders != null) { 356 borders.writeContent(result); 357 } 358 359 if(this.parentTable.getCellSpacing() > 0) { 360 result.write(ROW_CELL_SPACING_LEFT); 361 result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); 362 result.write(ROW_CELL_SPACING_LEFT_STYLE); 363 result.write(ROW_CELL_SPACING_TOP); 364 result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); 365 result.write(ROW_CELL_SPACING_TOP_STYLE); 366 result.write(ROW_CELL_SPACING_RIGHT); 367 result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); 368 result.write(ROW_CELL_SPACING_RIGHT_STYLE); 369 result.write(ROW_CELL_SPACING_BOTTOM); 370 result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); 371 result.write(ROW_CELL_SPACING_BOTTOM_STYLE); 372 } 373 374 result.write(ROW_CELL_PADDING_LEFT); 375 result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2))); 376 result.write(ROW_CELL_PADDING_RIGHT); 377 result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2))); 378 result.write(ROW_CELL_PADDING_LEFT_STYLE); 379 result.write(ROW_CELL_PADDING_RIGHT_STYLE); 380 381 this.document.outputDebugLinebreak(result); 382 383 for(int i = 0; i < this.cells.size(); i++) { 384 RtfCell rtfCell = (RtfCell) this.cells.get(i); 385 rtfCell.writeDefinition(result); 386 } 387 } 388 389 /** 390 * Writes the content of this RtfRow 391 */ writeContent(final OutputStream result)392 public void writeContent(final OutputStream result) throws IOException 393 { 394 writeRowDefinition(result); 395 396 for(int i = 0; i < this.cells.size(); i++) { 397 RtfCell rtfCell = (RtfCell) this.cells.get(i); 398 rtfCell.writeContent(result); 399 } 400 401 result.write(DELIMITER); 402 403 if(this.document.getDocumentSettings().isOutputTableRowDefinitionAfter()) { 404 writeRowDefinition(result); 405 } 406 407 result.write(ROW_END); 408 this.document.outputDebugLinebreak(result); 409 } 410 411 /** 412 * Gets the parent RtfTable of this RtfRow 413 * 414 * @return The parent RtfTable of this RtfRow 415 */ getParentTable()416 protected RtfTable getParentTable() { 417 return this.parentTable; 418 } 419 420 /** 421 * Gets the cells of this RtfRow 422 * 423 * @return The cells of this RtfRow 424 */ getCells()425 protected ArrayList getCells() { 426 return this.cells; 427 } 428 } 429