123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- using System;
- using System.Drawing;
- using System.ComponentModel;
- using FastReport.Utils;
- using FastReport.Table;
- namespace FastReport
- {
- /// <summary>
- /// Represents a text object which draws each symbol of text in its own cell.
- /// </summary>
- /// <remarks>
- /// <para/>The text may be aligned to left or right side, or centered. Use the <see cref="HorzAlign"/>
- /// property to do this. The "justify" align is not supported now, as well as vertical alignment.
- /// <para/>The cell size is defined in the <see cref="CellWidth"/> and <see cref="CellHeight"/> properties.
- /// These properties are 0 by default, in this case the size of cell is calculated automatically based
- /// on the object's <b>Font</b>.
- /// <para/>To define a spacing (gap) between cells, use the <see cref="HorzSpacing"/> and
- /// <see cref="VertSpacing"/> properties.
- /// </remarks>
- public partial class CellularTextObject : TextObject
- {
- #region Fields
- private float cellWidth;
- private float cellHeight;
- private float horzSpacing;
- private float vertSpacing;
- #endregion
- #region Properties
- /// <summary>
- /// Gets or sets the width of cell, in pixels.
- /// </summary>
- /// <remarks>
- /// If zero width and/or height specified, the object will calculate the cell size
- /// automatically based on its font.
- /// </remarks>
- [Category("Appearance")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float CellWidth
- {
- get { return cellWidth; }
- set { cellWidth = value; }
- }
- /// <summary>
- /// Gets or sets the height of cell, in pixels.
- /// </summary>
- /// <remarks>
- /// If zero width and/or height specified, the object will calculate the cell size
- /// automatically based on its font.
- /// </remarks>
- [Category("Appearance")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float CellHeight
- {
- get { return cellHeight; }
- set { cellHeight = value; }
- }
- /// <summary>
- /// Gets or sets the horizontal spacing between cells, in pixels.
- /// </summary>
- [Category("Appearance")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float HorzSpacing
- {
- get { return horzSpacing; }
- set { horzSpacing = value; }
- }
- /// <summary>
- /// Gets or sets the vertical spacing between cells, in pixels.
- /// </summary>
- [Category("Appearance")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float VertSpacing
- {
- get { return vertSpacing; }
- set { vertSpacing = value; }
- }
- #endregion
- #region Private Methods
- // use the TableObject to represent the contents. It's easier to export it later.
- private TableObject GetTable(bool autoRows)
- {
- TableObject table = new TableObject();
- table.SetPrinting(IsPrinting);
- table.SetReport(Report);
- float cellWidth = CellWidth;
- float cellHeight = CellHeight;
- // calculate cellWidth, cellHeight automatically
- if (cellWidth == 0 || cellHeight == 0)
- {
- float fontHeight = Font.GetHeight() * 96f / DrawUtils.ScreenDpi;
- cellWidth = GetCellWidthInternal(fontHeight);
- cellHeight = cellWidth;
- }
- int colCount = (int)((Width + HorzSpacing + 1) / (cellWidth + HorzSpacing));
- if (colCount == 0)
- colCount = 1;
- int rowCount = (int)((Height + VertSpacing + 1) / (cellHeight + VertSpacing));
- if (rowCount == 0 || autoRows)
- rowCount = 1;
- table.ColumnCount = colCount;
- table.RowCount = rowCount;
- // process the text
- int row = 0;
- int lineBegin = 0;
- int lastSpace = 0;
- string text = Text.Replace("\r\n", "\n");
- for (int i = 0; i < text.Length; i++)
- {
- bool isCRLF = text[i] == '\n';
- if (text[i] == ' ' || isCRLF)
- lastSpace = i;
- if (i - lineBegin + 1 > colCount || isCRLF)
- {
- if (WordWrap && lastSpace > lineBegin)
- {
- AddText(table, row, text.Substring(lineBegin, lastSpace - lineBegin));
- lineBegin = lastSpace + 1;
- }
- else if (i - lineBegin > 0)
- {
- AddText(table, row, text.Substring(lineBegin, i - lineBegin));
- lineBegin = i;
- }
- else
- lineBegin = i + 1;
- lastSpace = lineBegin;
- row++;
- if (autoRows && row >= rowCount)
- {
- rowCount++;
- table.RowCount++;
- }
- }
- }
- // finish the last line
- if (lineBegin < text.Length)
- AddText(table, row, text.Substring(lineBegin, text.Length - lineBegin));
- // set up cells appearance
- for (int i = 0; i < colCount; i++)
- {
- for (int j = 0; j < rowCount; j++)
- {
- TableCell cell = table[i, j];
- cell.Border = Border.Clone();
- cell.Fill = Fill.Clone();
- cell.Font = Font;
- cell.TextFill = TextFill.Clone();
- cell.HorzAlign = HorzAlign.Center;
- cell.VertAlign = VertAlign.Center;
- }
- }
- // set cell's width and height
- for (int i = 0; i < colCount; i++)
- {
- table.Columns[i].Width = cellWidth;
- }
- for (int i = 0; i < rowCount; i++)
- {
- table.Rows[i].Height = cellHeight;
- }
- // insert spacing between cells
- if (HorzSpacing > 0)
- {
- for (int i = 0; i < colCount - 1; i++)
- {
- TableColumn newColumn = new TableColumn();
- newColumn.Width = HorzSpacing;
- table.Columns.Insert(i * 2 + 1, newColumn);
- }
- }
- if (VertSpacing > 0)
- {
- for (int i = 0; i < rowCount - 1; i++)
- {
- TableRow newRow = new TableRow();
- newRow.Height = VertSpacing;
- table.Rows.Insert(i * 2 + 1, newRow);
- }
- }
- table.Left = AbsLeft;
- table.Top = AbsTop;
- table.Width = table.Columns[table.ColumnCount - 1].Right;
- table.Height = table.Rows[table.RowCount - 1].Bottom;
- return table;
- }
- private void AddText(TableObject table, int row, string text)
- {
- if (row >= table.RowCount)
- return;
- text = text.TrimEnd(' ');
- if (text.Length > table.ColumnCount)
- text = text.Substring(0, table.ColumnCount);
- int offset = 0;
- if (HorzAlign == HorzAlign.Right)
- offset = table.ColumnCount - text.Length;
- else if (HorzAlign == HorzAlign.Center)
- offset = (table.ColumnCount - text.Length) / 2;
- for (int i = 0; i < text.Length; i++)
- {
- table[i + offset, row].Text = text[i].ToString();
- }
- }
- #endregion
- #region Public Methods
- /// <inheritdoc/>
- public override void Assign(Base source)
- {
- base.Assign(source);
- CellularTextObject src = source as CellularTextObject;
- CellWidth = src.CellWidth;
- CellHeight = src.CellHeight;
- HorzSpacing = src.HorzSpacing;
- VertSpacing = src.VertSpacing;
- }
- /// <inheritdoc/>
- public override void Serialize(FRWriter writer)
- {
- CellularTextObject c = writer.DiffObject as CellularTextObject;
- base.Serialize(writer);
- if (FloatDiff(CellWidth, c.CellWidth))
- writer.WriteFloat("CellWidth", CellWidth);
- if (FloatDiff(CellHeight, c.CellHeight))
- writer.WriteFloat("CellHeight", CellHeight);
- if (FloatDiff(HorzSpacing, c.HorzSpacing))
- writer.WriteFloat("HorzSpacing", HorzSpacing);
- if (FloatDiff(VertSpacing, c.VertSpacing))
- writer.WriteFloat("VertSpacing", VertSpacing);
- }
- /// <inheritdoc/>
- public override void Draw(FRPaintEventArgs e)
- {
- using (TableObject table = GetTable())
- {
- table.Draw(e);
- }
- }
- public TableObject GetTable()
- {
- return GetTable(false);
- }
- #endregion
- #region Report Engine
- /// <inheritdoc/>
- public override float CalcHeight()
- {
- using (TableObject table = GetTable(true))
- {
- return table.Height;
- }
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="CellularTextObject"/> class with the default settings.
- /// </summary>
- public CellularTextObject()
- {
- CanBreak = false;
- Border.Lines = BorderLines.All;
- }
- }
- }
|