using System; using System.Collections; using System.util; using iTextSharp.text.html; using iTextSharp.text.pdf; using iTextSharp.text.factories; /* * $Id: Cell.cs,v 1.17 2008/05/13 11:25:08 psoares33 Exp $ * * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * 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/ */ namespace iTextSharp.text { /// /// A Cell is a Rectangle containing other Elements. /// /// /// A Cell is a Rectangle containing other /// Elements. ///

/// A Cell must be added to a Table. /// The Table will place the Cell in /// a Row. /// /// /// /// Table table = new Table(3); /// table.SetBorderWidth(1); /// table.SetBorderColor(new Color(0, 0, 255)); /// table.SetCellpadding(5); /// table.SetCellspacing(5); /// Cell cell = new Cell("header"); /// cell.SetHeader(true); /// cell.SetColspan(3); /// table.AddCell(cell); /// cell = new Cell("example cell with colspan 1 and rowspan 2"); /// cell.SetRowspan(2); /// cell.SetBorderColor(new Color(255, 0, 0)); /// table.AddCell(cell); /// table.AddCell("1.1"); /// table.AddCell("2.1"); /// table.AddCell("1.2"); /// table.AddCell("2.2"); /// /// /// /// /// /// public class Cell : Rectangle, ITextElementArray { // static membervariable public static Cell DummyCell { get { Cell cell = new Cell(true); cell.Colspan = 3; cell.Border = NO_BORDER; return cell; } } // membervariables ///

This is the ArrayList of Elements. protected ArrayList arrayList = null; /// This is the horizontal Element. protected int horizontalAlignment = Element.ALIGN_UNDEFINED; /// This is the vertical Element. protected int verticalAlignment = Element.ALIGN_UNDEFINED; /// This is the vertical Element. protected float width; protected bool percentage = false; /// This is the colspan. protected int colspan = 1; /// This is the rowspan. protected int rowspan = 1; /// This is the leading. float leading = float.NaN; /// Is this Cell a header? protected bool header; /// /// Indicates that the largest ascender height should be used to determine the /// height of the first line. Note that this only has an effect when rendered /// to PDF. Setting this to true can help with vertical alignment problems. /// protected bool useAscender = false; /// /// Indicates that the largest descender height should be added to the height of /// the last line (so characters like y don't dip into the border). Note that /// this only has an effect when rendered to PDF. /// protected bool useDescender = false; /// /// Adjusts the cell contents to compensate for border widths. Note that /// this only has an effect when rendered to PDF. /// protected bool useBorderPadding; /// Will the element have to be wrapped? protected bool noWrap; // constructors /** * Constructs an empty Cell. */ /// /// Constructs an empty Cell. /// /// /// Has five overloads. /// public Cell() : base(0, 0, 0, 0) { // creates a Rectangle with BY DEFAULT a border of 0.5 this.Border = UNDEFINED; this.BorderWidth = 0.5F; // initializes the arraylist and adds an element arrayList = new ArrayList(); } /// /// Constructs an empty Cell (for internal use only). /// /// a dummy value public Cell(bool dummy) : this() { arrayList.Add(new Paragraph(0)); } /// /// Constructs a Cell with a certain content. /// /// /// The string will be converted into a Paragraph. /// /// a string public Cell(string content) : this() { AddElement(new Paragraph(content)); } /// /// Constructs a Cell with a certain Element. /// /// /// if the element is a ListItem, Row or /// Cell, an exception will be thrown. /// /// the element public Cell(IElement element) : this() { if (element is Phrase) { Leading = ((Phrase)element).Leading; } AddElement(element); } // implementation of the Element-methods /// /// Processes the element by adding it (or the different parts) to an /// IElementListener. /// /// an IElementListener /// true if the element was processed successfully public override bool Process(IElementListener listener) { try { return listener.Add(this); } catch (DocumentException) { return false; } } /// /// Gets the type of the text element. /// /// a type public override int Type { get { return Element.CELL; } } /// /// Gets all the chunks in this element. /// /// an ArrayList public override ArrayList Chunks { get { ArrayList tmp = new ArrayList(); foreach (IElement ele in arrayList) { tmp.AddRange(ele.Chunks); } return tmp; } } // methods to set the membervariables /** * Adds an element to this Cell. *

* Remark: you can't add ListItems, Rows, Cells, * JPEGs, GIFs or PNGs to a Cell. * * @param element The Element to add * @throws BadElementException if the method was called with a ListItem, Row or Cell */ ///

/// Adds an element to this Cell. /// /// /// You can't add ListItems, Rows, Cells, /// JPEGs, GIFs or PNGs to a Cell. /// /// the Element to add public void AddElement(IElement element) { if (IsTable()) { Table table = (Table) arrayList[0]; Cell tmp = new Cell(element); tmp.Border = NO_BORDER; tmp.Colspan = table.Columns; table.AddCell(tmp); return; } switch (element.Type) { case Element.LISTITEM: case Element.ROW: case Element.CELL: throw new BadElementException("You can't add listitems, rows or cells to a cell."); case Element.JPEG: case Element.IMGRAW: case Element.IMGTEMPLATE: arrayList.Add(element); break; case Element.LIST: if (float.IsNaN(this.Leading)) { leading = ((List) element).TotalLeading; } if (((List) element).IsEmpty()) return; arrayList.Add(element); return; case Element.ANCHOR: case Element.PARAGRAPH: case Element.PHRASE: if (float.IsNaN(leading)) { leading = ((Phrase) element).Leading; } if (((Phrase) element).IsEmpty()) return; arrayList.Add(element); return; case Element.CHUNK: if (((Chunk) element).IsEmpty()) return; arrayList.Add(element); return; case Element.TABLE: Table table = new Table(3); float[] widths = new float[3]; widths[1] = ((Table)element).Width; switch (((Table)element).Alignment) { case Element.ALIGN_LEFT: widths[0] = 0f; widths[2] = 100f - widths[1]; break; case Element.ALIGN_CENTER: widths[0] = (100f - widths[1]) / 2f; widths[2] = widths[0]; break; case Element.ALIGN_RIGHT: widths[0] = 100f - widths[1]; widths[2] = 0f; break; } table.Widths = widths; Cell tmp; if (arrayList.Count == 0) { table.AddCell(Cell.DummyCell); } else { tmp = new Cell(); tmp.Border = NO_BORDER; tmp.Colspan = 3; foreach (IElement ele in arrayList) { tmp.Add(ele); } table.AddCell(tmp); } tmp = new Cell(); tmp.Border = NO_BORDER; table.AddCell(tmp); table.InsertTable((Table)element); tmp = new Cell(); tmp.Border = NO_BORDER; table.AddCell(tmp); table.AddCell(Cell.DummyCell); Clear(); arrayList.Add(table); return; default: arrayList.Add(element); break; } } /// /// Add an Object to this cell. /// /// the object to add /// always true public bool Add(Object o) { try { this.AddElement((IElement) o); return true; } catch (BadElementException bee) { throw new Exception(bee.Message); } catch { throw new Exception("You can only add objects that implement the Element interface."); } } /// /// Sets the alignment of this cell. /// /// the new alignment as a string public void SetHorizontalAlignment(string alignment) { if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_CENTER)) { this.HorizontalAlignment = Element.ALIGN_CENTER; return; } if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_RIGHT)) { this.HorizontalAlignment = Element.ALIGN_RIGHT; return; } if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_JUSTIFIED)) { this.HorizontalAlignment = Element.ALIGN_JUSTIFIED; return; } if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_JUSTIFIED_ALL)) { this.HorizontalAlignment = Element.ALIGN_JUSTIFIED_ALL; return; } this.HorizontalAlignment = Element.ALIGN_LEFT; } /// /// Sets the alignment of this paragraph. /// /// the new alignment as a string public void SetVerticalAlignment(string alignment) { if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_MIDDLE)) { this.VerticalAlignment = Element.ALIGN_MIDDLE; return; } if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_BOTTOM)) { this.VerticalAlignment = Element.ALIGN_BOTTOM; return; } if (Util.EqualsIgnoreCase(alignment, ElementTags.ALIGN_BASELINE)) { this.VerticalAlignment = Element.ALIGN_BASELINE; return; } this.VerticalAlignment = Element.ALIGN_TOP; } /// /// Sets the width. /// /// the new value public override float Width { set { width = value; } get { return width; } } /** * Sets the width. * It can be an absolute value "100" or a percentage "20%" * * @param value the new value */ public void SetWidth(String value) { if (value.EndsWith("%")) { value = value.Substring(0, value.Length - 1); percentage = true; } width = int.Parse(value); } /** * Gets the width as a String. * * @return a value */ public String GetWidthAsString() { String w = width.ToString(System.Globalization.CultureInfo.InvariantCulture); if (w.EndsWith(".0")) w = w.Substring(0, w.Length - 2); if (percentage) w += "%"; return w; } // methods to retrieve information /// /// Gets the number of Elements in the Cell. /// /// a size public int Size { get { return arrayList.Count; } } /// /// Checks if the Cell is empty. /// /// false if there are non-empty Elements in the Cell. public bool IsEmpty() { switch (this.Size) { case 0: return true; case 1: IElement element = (IElement)arrayList[0]; switch (element.Type) { case Element.CHUNK: return ((Chunk) element).IsEmpty(); case Element.ANCHOR: case Element.PHRASE: case Element.PARAGRAPH: return ((Phrase) element).IsEmpty(); case Element.LIST: return ((List) element).IsEmpty(); } return false; default: return false; } } /// /// Makes sure there is at least 1 object in the Cell. /// Otherwise it might not be shown in the table. /// internal void Fill() { if (this.Size == 0) arrayList.Add(new Paragraph(0)); } /// /// Checks if the Cell is empty. /// /// false if there are non-empty Elements in the Cell. public bool IsTable() { return (this.Size == 1) && (((IElement)arrayList[0]).Type == Element.TABLE); } /// /// Gets Elements. /// /// an ArrayList public ArrayList Elements { get { return arrayList; } } /// /// Gets/Sets the horizontal Element. /// /// a value public int HorizontalAlignment { get { return horizontalAlignment; } set { horizontalAlignment = value; } } /// /// Gets/sets the vertical Element. /// /// a value public int VerticalAlignment { get { return verticalAlignment; } set { verticalAlignment = value; } } /** * Gets the colspan. * * @return a value */ /// /// Gets/sets the colspan. /// /// a value public int Colspan { get { return colspan; } set { colspan = value; } } /// /// Gets/sets the rowspan. /// /// a value public int Rowspan { get { return rowspan; } set { rowspan = value; } } /// /// Gets/sets the leading. /// /// a value public float Leading { get { if (float.IsNaN(leading)) { return 16; } return leading; } set { leading = value; } } /// /// Gets/sets header /// /// a value public bool Header { get { return header; } set { header = value; } } /** * Get nowrap. * * @return a value */ /// /// Get/set nowrap. /// /// a value public bool NoWrap { get { return (maxLines == 1); } set { maxLines = 1; } } /// /// Clears all the Elements of this Cell. /// public void Clear() { arrayList.Clear(); } /// /// This property throws an Exception. /// /// none public override float Top { get { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } set { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } } /// /// This property throws an Exception. /// /// none public override float Bottom { get { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } set { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } } /// /// This property throws an Exception. /// /// none public override float Left { get { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } set { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } } /// /// This property throws an Exception. /// /// none public override float Right { get { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } set { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } } /// /// This method throws an Exception. /// /// new value /// none public float GetTop(int margin) { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } /// /// This method throws an Exception. /// /// new value /// none public float GetBottom(int margin) { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } /// /// This method throws an Exception. /// /// new value /// none public float GetLeft(int margin) { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } /// /// This method throws an Exception. /// /// new value /// none public float GetRight(int margin) { throw new Exception("Dimensions of a Cell can't be calculated. See the FAQ."); } /// /// Checks if a given tag corresponds with this object. /// /// the given tag /// true if the tag corresponds public static bool IsTag(string tag) { return ElementTags.CELL.Equals(tag); } ///Does this Cell force a group change? protected bool groupChange = true; /// /// Does this Cell force a group change? /// public bool GroupChange { get { return groupChange; } set { groupChange = value; } } /// /// get/set maxLines value /// public int MaxLines { get { return maxLines; } set { maxLines = value; } } /// /// Maximum number of lines allowed in the cell. /// The default value of this property is not to limit the maximum number of lines /// (contributed by dperezcar@fcc.es) /// protected int maxLines = int.MaxValue; /// /// get/set showTruncation value /// public string ShowTruncation { get { return showTruncation; } set { showTruncation = value; } } /// /// If a truncation happens due to the {@link #maxLines} property, then this text will /// be added to indicate a truncation has happened. /// Default value is null, and means avoiding marking the truncation. /// A useful value of this property could be e.g. "..." /// (contributed by dperezcar@fcc.es) /// private string showTruncation; /// /// get/set useAscender value /// public bool UseAscender { get { return useAscender; } set { useAscender = value; } } /// /// get/set useDescender value /// public bool UseDescender { get { return useDescender; } set { useDescender = value; } } /// /// get/set useBorderPadding value /// public bool UseBorderPadding { get { return useBorderPadding; } set { useBorderPadding = value; } } /** * Creates a PdfPCell based on this Cell object. * @return a PdfPCell * @throws BadElementException */ public PdfPCell CreatePdfPCell() { if (rowspan > 1) throw new BadElementException("PdfPCells can't have a rowspan > 1"); if (IsTable()) return new PdfPCell(((Table)arrayList[0]).CreatePdfPTable()); PdfPCell cell = new PdfPCell(); cell.VerticalAlignment = verticalAlignment; cell.HorizontalAlignment = horizontalAlignment; cell.Colspan = colspan; cell.UseBorderPadding = useBorderPadding; cell.UseDescender = useDescender; cell.SetLeading(Leading, 0); cell.CloneNonPositionParameters(this); cell.NoWrap = noWrap; foreach (IElement i in Elements) { if (i.Type == Element.PHRASE || i.Type == Element.PARAGRAPH) { Paragraph p = new Paragraph((Phrase)i); p.Alignment = horizontalAlignment; cell.AddElement(p); } else cell.AddElement(i); } return cell; } } }