using System; using System.Collections.Generic; using System.Text; using C1.Win.C1FlexGrid; using System.IO; using Itenso.Rtf; using Itenso.Rtf.Parser; using Itenso.Rtf.Interpreter; using Itenso.Rtf.Support; using Volian.Print.Library; using Volian.Controls.Library; using iTextSharp.text.pdf; namespace Volian.Print.Library { public class vlnTable { #region Properties private float[] _RowTop; public float[] RowTop { get { return _RowTop; } set { _RowTop = value; } } private float[] _ColLeft; public float[] ColLeft { get { return _ColLeft; } set { _ColLeft = value; } } private VlnFlexGrid _MyFlexGrid; public VlnFlexGrid MyFlexGrid { get { return _MyFlexGrid; } set { _MyFlexGrid = value; } } public VlnBorders MyBorders { get { return _MyFlexGrid.MyBorders; } } private iTextSharp.text.pdf.PdfContentByte _MyContentByte; public iTextSharp.text.pdf.PdfContentByte MyContentByte { get { return _MyContentByte; } set { _MyContentByte = value; } } private vlnCells _MyCells; public vlnCells MyCells { get { return _MyCells; } set { _MyCells = value; } } public float Height { get { return RowTop[MyFlexGrid.Rows.Count]; } } public float Width { get { return ColLeft[MyFlexGrid.Cols.Count]; } } private static float _XOffset = -1; // This moves the borders with respect to the text public static float XOffset { get { return vlnTable._XOffset; } set { vlnTable._XOffset = value; } } private static float _YOffset = 0; // This moves the borders with respect to the text public static float YOffset { get { return vlnTable._YOffset; } set { vlnTable._YOffset = value; } } private static float _LineThicknessForThin = .9F; public static float LineThicknessForThin { get { return vlnTable._LineThicknessForThin; } set { vlnTable._LineThicknessForThin = value; } } private static float _LineThicknessForThick = 1.8F; public static float LineThicknessForThick { get { return vlnTable._LineThicknessForThick; } set { vlnTable._LineThicknessForThick = value; } } private static float _LineThicknessForDouble = .6F; public static float LineThicknessForDouble { get { return vlnTable._LineThicknessForDouble; } set { vlnTable._LineThicknessForDouble = value; } } public static float DoubleLineOffset { get { return (LineThicknessForThick - LineThicknessForDouble) / 2; }//LineThicknessForThick - 2 * LineThicknessForDouble; } } #endregion #region Constructors public vlnTable(VlnFlexGrid myFlexGrid, iTextSharp.text.pdf.PdfContentByte myContentByte) { MyFlexGrid = myFlexGrid; MyContentByte = myContentByte; InitializeSizes(); MyCells = new vlnCells(this, MyFlexGrid, MyContentByte); } #endregion #region Private Methods private void InitializeSizes() { RowTop = new float[MyFlexGrid.Rows.Count + 1]; RowTop[0] = 0; for (int r = 0; r < MyFlexGrid.Rows.Count; r++) RowTop[r + 1] = RowTop[r] + 72 * (MyFlexGrid.Rows[r].Height == -1 ? MyFlexGrid.Rows.DefaultSize : MyFlexGrid.Rows[r].Height) / (float)MyFlexGrid.DPI; ColLeft = new float[MyFlexGrid.Cols.Count + 1]; ColLeft[0] = 0; for (int c = 0; c < MyFlexGrid.Cols.Count; c++) ColLeft[c + 1] = ColLeft[c] + 72 * (MyFlexGrid.Cols[c].Width == -1 ? MyFlexGrid.Cols.DefaultSize : MyFlexGrid.Cols[c].Width) / (float)MyFlexGrid.DPI; } #endregion #region Public Methods public void AdjustRowTop(int row1, int row2, float hNew) { float hAdjust = hNew - (RowTop[row2 + 1] - RowTop[row1]); for (int r = row2; r < MyFlexGrid.Rows.Count; r++) RowTop[r + 1] += hAdjust; } public void ToPdf(iTextSharp.text.pdf.ColumnText myColumnText, float left, float top) { //ZoomGrid(myColumnText, left, top); VlnSvgPageHelper myPageHelper = myColumnText.Canvas.PdfWriter.PageEvent as VlnSvgPageHelper; myPageHelper.AddGap(top, top - Height, left, left + Width); MyCells.ToPdf(myColumnText, left, top); } private void ZoomGrid(iTextSharp.text.pdf.ColumnText myColumnText, float left, float top) { PdfDestination dest = new PdfDestination(PdfDestination.FITR, left - 4, top - Height - 4, left + Width, top + 4); myColumnText.Canvas.SetAction(PdfAction.GotoLocalPage(myColumnText.Canvas.PdfWriter.CurrentPageNumber, dest, myColumnText.Canvas.PdfWriter), left, top - Height, left + Width, top); } #endregion } public class vlnCells : List { #region Properties private VlnFlexGrid _MyFlexGrid; public VlnFlexGrid MyFlexGrid { get { return _MyFlexGrid; } set { _MyFlexGrid = value; } } private vlnTable _MyTable; public vlnTable MyTable { get { return _MyTable; } set { _MyTable = value; } } private iTextSharp.text.pdf.PdfContentByte _MyContentByte; public iTextSharp.text.pdf.PdfContentByte MyContentByte { get { return _MyContentByte; } set { _MyContentByte = value; } } #endregion #region Constructors public vlnCells(vlnTable myTable, VlnFlexGrid myFlexGrid, iTextSharp.text.pdf.PdfContentByte myContentByte) { MyTable = myTable; MyFlexGrid = myFlexGrid; MyContentByte = myContentByte; SetupCells(); } #endregion #region Private Methods private void SetupCells() { // Create a ColumnText to determine the cell heights iTextSharp.text.pdf.ColumnText myColumnText1 = new iTextSharp.text.pdf.ColumnText(MyContentByte); // Walk through for (int r = 0; r < MyFlexGrid.Rows.Count; r++) { for (int c = 0; c < MyFlexGrid.Cols.Count; c++) { CellRange cr = MyFlexGrid.GetMergedRange(r, c); if (cr.r1 == r && cr.c1 == c) { float w = MyTable.ColLeft[cr.c2 + 1] - MyTable.ColLeft[cr.c1]; float h = MyTable.RowTop[cr.r2 + 1] - MyTable.RowTop[cr.r1]; string str = MyFlexGrid.GetCellRTFString(r, c) ?? string.Empty; DisplayText dt = new DisplayText(MyFlexGrid.GetMyItemInfo(), str, false); str = dt.StartText; using (StepRTB myRTB = new StepRTB()) { myRTB.Width = (int)w; myRTB.Font = MyFlexGrid.Font; if (str.StartsWith(@"{\rtf")) myRTB.Rtf = str.Replace(@"\~", @"\u160?"); else myRTB.Text = str; myRTB.SelectAll(); myRTB.SelectionColor = PrintOverride.OverrideTextColor(System.Drawing.Color.Black); str = myRTB.Rtf; } iTextSharp.text.Paragraph myPara = RtfToParagraph(str); myColumnText1.SetSimpleColumn(0, 0, w - 2, MyContentByte.PdfDocument.PageSize.Top); // Padding = 4 // RHM 20120925 - Line spacing should be 6 lines per inch. In order to get a valid value // for TotalLeading you have to set MultipliedLeading first: myPara.MultipliedLeading = 1.0f; // once there is valid value for TotalLeading (from previous line), you can use it to // calculate a MultipliedLeading to give 6 LPI (12 points) myPara.MultipliedLeading = 12.0f / myPara.TotalLeading; myPara.SpacingAfter = 8; // RHM 20120925 - Add a line to properly space text from lines. myColumnText1.AddElement(myPara); //myColumnText1.Canvas.SetColorFill(PrintOverride.OverrideTextColor(System.Drawing.Color.Black)); float posBefore = myColumnText1.YLine; int status = myColumnText1.Go(true); float posAfter = myColumnText1.YLine; float hContent = 4 + posBefore - posAfter; if (hContent > h) MyTable.AdjustRowTop(cr.r1, cr.r2, hContent); Add(new vlnCell(cr.r1, cr.c1, cr.r2, cr.c2, MyTable, myPara, hContent)); } } } } public static iTextSharp.text.Paragraph RtfToParagraph(string rtf) { IRtfDocument rtfDoc = RtfInterpreterTool.BuildDoc(rtf); Rtf2iTextSharp rtf2IText = new Rtf2iTextSharp(rtfDoc); iTextSharp.text.Paragraph para = rtf2IText.Convert(); para.SetLeading(_SixLinesPerInch, 0); return para; } private static float _SixLinesPerInch = 12; // twips #endregion #region Public Methods public void ToPdf(iTextSharp.text.pdf.ColumnText myColumnText, float left, float top) { foreach (vlnCell myCell in this) myCell.ToPdf(myColumnText, left, top); } #endregion } public class vlnCell { #region Properties private vlnTable _MyTable; public vlnTable MyTable { get { return _MyTable; } set { _MyTable = value; } } public VlnBorders MyBorders { get { return _MyTable.MyBorders; } } private int _r1; public int r1 { get { return _r1; } set { _r1 = value; } } private int _c1; public int c1 { get { return _c1; } set { _c1 = value; } } private int _r2; public int r2 { get { return _r2; } set { _r2 = value; } } private int _c2; public int c2 { get { return _c2; } set { _c2 = value; } } private iTextSharp.text.Paragraph _MyPara; public iTextSharp.text.Paragraph MyPara { get { return _MyPara; } set { _MyPara = value; } } private float _HContent; public float HContent { get { return _HContent; } set { _HContent = value; } } #endregion #region Line Pattern Diagram /* The diagram below identifies the various border names for the cell in the center |-AboveLeftSide |-AboveRightSide | | | | | | LeftOfTopSide | TopSide | RightOfTopSide ------------------|-------------------|------------------ | | | | |-LeftSide |-RightSide | | | | LeftOfBottomSide | BottomSide | RightOfBottomSide --------------------------------------|------------------ | | | | | | | | |-BelowLeftSide |-BelowRightSide */ #endregion #region Horizontal Line Patterns private GridLinePattern _TopSide = GridLinePattern.Unknown; public GridLinePattern TopSide { get { if (_TopSide == GridLinePattern.Unknown) _TopSide = MyBorders.HorizontalLines[r1, c1]; return _TopSide; } } private GridLinePattern _BottomSide = GridLinePattern.Unknown; public GridLinePattern BottomSide { get { if (_BottomSide == GridLinePattern.Unknown) _BottomSide = MyBorders.HorizontalLines[r2 + 1, c2]; return _BottomSide; } } private GridLinePattern _RightOfTopSide = GridLinePattern.Unknown; public GridLinePattern RightOfTopSide { get { if (_RightOfTopSide == GridLinePattern.Unknown) { if (c2 == MyTable.MyFlexGrid.Cols.Count - 1) _RightOfTopSide = GridLinePattern.None; else { CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r1, c2 + 1); if (cr.r1 == r1) _RightOfTopSide = MyBorders.HorizontalLines[r1, c2 + 1]; else _RightOfTopSide = GridLinePattern.None; } } return _RightOfTopSide; } } private GridLinePattern _LeftOfTopSide = GridLinePattern.Unknown; public GridLinePattern LeftOfTopSide { get { if (_LeftOfTopSide == GridLinePattern.Unknown) { if (c1 == 0) _LeftOfTopSide = GridLinePattern.None; else { // This property is only used if c1==0 or r1==0: // A merged range for row = 0 will always return an r1=0. CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r1, c1 - 1); if (cr.r1 == r1) _LeftOfTopSide = MyBorders.HorizontalLines[r1, c1 - 1]; else // Since this section of code is only entered when r1==0, this else condition should never happen _LeftOfTopSide = GridLinePattern.None; } } return _LeftOfTopSide; } } private GridLinePattern _RightOfBottomSide = GridLinePattern.Unknown; public GridLinePattern RightOfBottomSide { get { if (_RightOfBottomSide == GridLinePattern.Unknown) // Need to consider Merged Cells { if (c2 == MyTable.MyFlexGrid.Cols.Count - 1) _RightOfBottomSide = GridLinePattern.None; else { CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r2, c2 + 1); if (cr.r2 == r2) _RightOfBottomSide = MyBorders.HorizontalLines[r2 + 1, c2 + 1]; else _RightOfBottomSide = GridLinePattern.None; } } return _RightOfBottomSide; } } private GridLinePattern _LeftOfBottomSide = GridLinePattern.Unknown; public GridLinePattern LeftOfBottomSide { get { if (_LeftOfBottomSide == GridLinePattern.Unknown) // Need to consider Merged Cells { if (c1 == 0) _LeftOfBottomSide = GridLinePattern.None; else { CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r2, c1 - 1); if (cr.r2 == r2) _LeftOfBottomSide = MyBorders.HorizontalLines[r2 + 1, c1 - 1]; else _LeftOfBottomSide = GridLinePattern.None; } } return _LeftOfBottomSide; } } #endregion #region Vertical Line Patterns private GridLinePattern _LeftSide = GridLinePattern.Unknown; public GridLinePattern LeftSide { get { if (_LeftSide == GridLinePattern.Unknown) _LeftSide = MyBorders.VerticalLines[r1, c1]; return _LeftSide; } } private GridLinePattern _RightSide = GridLinePattern.Unknown; public GridLinePattern RightSide { get { if (_RightSide == GridLinePattern.Unknown) _RightSide = MyBorders.VerticalLines[r2, c2 + 1]; return _RightSide; } } private GridLinePattern _BelowRightSide = GridLinePattern.Unknown; public GridLinePattern BelowRightSide { get { if (_BelowRightSide == GridLinePattern.Unknown) { if (r2 == MyTable.MyFlexGrid.Rows.Count - 1) _BelowRightSide = GridLinePattern.None; else { CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r2 + 1, c2); if (cr.c2 == c2) _BelowRightSide = MyBorders.VerticalLines[r2 + 1, c2 + 1]; else _BelowRightSide = GridLinePattern.None; } } return _BelowRightSide; } } private GridLinePattern _AboveRightSide = GridLinePattern.Unknown; public GridLinePattern AboveRightSide { get { if (_AboveRightSide == GridLinePattern.Unknown) { if (r1 == 0) _AboveRightSide = GridLinePattern.None; else { CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r1 - 1, c2); if (cr.c2 == c2) _AboveRightSide = MyBorders.VerticalLines[r1 - 1, c2 + 1]; else _AboveRightSide = GridLinePattern.None; } } return _AboveRightSide; } } private GridLinePattern _BelowLeftSide = GridLinePattern.Unknown; public GridLinePattern BelowLeftSide { get { if (_BelowLeftSide == GridLinePattern.Unknown) { if (r2 == MyTable.MyFlexGrid.Rows.Count - 1) _BelowLeftSide = GridLinePattern.None; else { CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r2 + 1, c1); if (cr.c1 == c1) _BelowLeftSide = MyBorders.VerticalLines[r2 + 1, c1]; else _BelowLeftSide = GridLinePattern.None; } } return _BelowLeftSide; } } private GridLinePattern _AboveLeftSide = GridLinePattern.Unknown; public GridLinePattern AboveLeftSide { get { if (_AboveLeftSide == GridLinePattern.Unknown) { if (r1 == 0) _AboveLeftSide = GridLinePattern.None; else { // This property is only used if c1==0 or r1==0: // A merged range for col = 0 will always return an c1=0. CellRange cr = MyTable.MyFlexGrid.GetMergedRange(r1 - 1, c1); if (cr.c1 == c1) _AboveLeftSide = MyBorders.VerticalLines[r1 - 1, c1]; else // Since this section of code is only entered when c1==0, this else condition should never happen _AboveLeftSide = GridLinePattern.None; } } return _AboveLeftSide; } } #endregion #region Static Properties private static float XOffset { get { return vlnTable.XOffset; } } private static float YOffset { get { return vlnTable.YOffset; } } private static float LineThicknessForThin { get { return vlnTable.LineThicknessForThin; } } private static float LineThicknessForThick { get { return vlnTable.LineThicknessForThick; } } private static float LineThicknessForDouble { get { return vlnTable.LineThicknessForDouble; } } private static float DoubleLineOffset { get { return vlnTable.DoubleLineOffset; } } // adjustments for line intersections: private static float ThickOverDouble { get { return ((2 * DoubleLineOffset) + LineThicknessForDouble - LineThicknessForThick) / 2; } } private static float ThickUnderDouble { get { return DoubleLineOffset + (LineThicknessForThick - LineThicknessForDouble) / 2; } } private static float ThickOverThin { get { return (LineThicknessForThin - LineThicknessForThick) / 2; } } private static float ThinOverThick { get { return (LineThicknessForThick - LineThicknessForThin) / 2; } } private static float ThinUnderDouble { get { return DoubleLineOffset + (LineThicknessForThin - LineThicknessForDouble) / 2; } } private static float ThinOverDouble { get { return (DoubleLineOffset + LineThicknessForThin - LineThicknessForDouble) / 2; } } private static float DoubleUnderThin { get { return (LineThicknessForThin - LineThicknessForDouble) / 2; } } private static float DoubleUnderThick { get { return (LineThicknessForThick - LineThicknessForDouble) / 2; } } #endregion #region Constructors public vlnCell(int r1, int c1, int r2, int c2, vlnTable myTable, iTextSharp.text.Paragraph myPara, float hContent) { this.r1 = r1; this.c1 = c1; this.r2 = r2; this.c2 = c2; MyTable = myTable; MyPara = myPara; HContent = hContent; } #endregion #region Public Methods public override string ToString() { return string.Format("{0}:{1}", r1, c1); } public void ToPdf(iTextSharp.text.pdf.ColumnText myColumnText, float left, float top) { myColumnText.Canvas.SaveState(); VlnSvgPageHelper _MyPageHelper = myColumnText.Canvas.PdfWriter.PageEvent as VlnSvgPageHelper; float mult = _MyPageHelper.YMultiplier; float x = MyTable.ColLeft[c1]; float w = MyTable.ColLeft[c2 + 1] - x; float y = mult * MyTable.RowTop[r1]; float h = mult * MyTable.RowTop[r2 + 1] - y; BordersToPdf(myColumnText, left, top, x, w, y, h ); float hAdjust = VeritcalTextAlignment(h); iTextSharp.text.pdf.ColumnText myColumnText1 = new iTextSharp.text.pdf.ColumnText(myColumnText.Canvas); float adjustTextLocation = mult * 4; // RHM 20120925 Move text down about 1 half line from the border myColumnText1.SetSimpleColumn(1 + left + x, top - y - h , left + x + w, 1 + top - y - hAdjust - adjustTextLocation); // 2 == Default Padding MyPara.MultipliedLeading *= _MyPageHelper.YMultiplier; myColumnText1.AddElement(MyPara); myColumnText1.Go(); myColumnText.Canvas.RestoreState(); } private static float _SixLinesPerInch = 12; // twips #endregion #region Private Text Methods private float VeritcalTextAlignment(float h) { float hAdjust = 0; CellRange cr = MyTable.MyFlexGrid.GetCellRange(r1, c1, r2, c2); if (cr.Style != null) { switch (cr.Style.TextAlign) { case TextAlignEnum.CenterBottom: case TextAlignEnum.GeneralBottom: case TextAlignEnum.LeftBottom: case TextAlignEnum.RightBottom: hAdjust = h - HContent; break; case TextAlignEnum.CenterCenter: case TextAlignEnum.GeneralCenter: case TextAlignEnum.LeftCenter: case TextAlignEnum.RightCenter: hAdjust = (h - HContent) / 2; break; default: break; } } return hAdjust; } #endregion #region Private Border Methods // coordinate system is upside down of screen. 0,0 on screen is top/left. 0,0 on pdf is bottom/left. // i.e. x is same, y is flipped. private void BordersToPdf(iTextSharp.text.pdf.ColumnText myColumnText, float left, float top, float x, float w, float y, float h) { PdfContentByte cb = myColumnText.Canvas; cb.SaveState();// Save state before drawing borders //SetOpacity(cb, .7F); // This line makes the borders transparent for testing float xLeft = left + x + XOffset; float yTop = top - y + YOffset; float xRight = left + x + w + XOffset; float yBottom = top - y - h + YOffset; // ZoomToCell(myColumnText, xLeft, yTop, xRight, yBottom); // Draw Top Side for the first row if (r1 == 0) DrawHorizontalLine(cb, "Top", xLeft, xRight, yTop, TopSide, LeftSide, AboveLeftSide, LeftOfTopSide, AboveRightSide, RightSide, RightOfTopSide); // Draw Left Side for the first column if (c1 == 0) DrawLineVertical(cb, "Left", xLeft, yBottom, yTop, LeftSide, BottomSide, LeftOfBottomSide, BelowLeftSide, LeftOfTopSide, TopSide, AboveLeftSide); // Draw Bottom Side DrawHorizontalLine(cb, "Bottom", xLeft, xRight, yBottom, BottomSide, BelowLeftSide, LeftSide, LeftOfBottomSide, RightSide, BelowRightSide, RightOfBottomSide); // Draw Right Side DrawLineVertical(cb, "Right", xRight, yBottom, yTop, RightSide, RightOfBottomSide, BottomSide, BelowRightSide, TopSide, RightOfTopSide, AboveRightSide); cb.RestoreState(); } private void DrawHorizontalLine(PdfContentByte cb, string side, float xStart, float xEnd, float y, GridLinePattern LinePattern, GridLinePattern startToLeft, GridLinePattern startToRight, GridLinePattern startAhead, GridLinePattern endToLeft, GridLinePattern endToRight, GridLinePattern endAhead) { if (LinePattern != GridLinePattern.None) { float direction = (xStart < xEnd) ? 1 : -1; InitializeLineStyle(cb); SetLineColor(cb, r1, c1, side); if (LinePattern == GridLinePattern.Double) { // Top Line float dStart = -direction * DoubleIntersectionRight(startToLeft, startToRight, startAhead); float dEnd = direction * DoubleIntersectionLeft(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForDouble, xStart + dStart, y + DoubleLineOffset, xEnd + dEnd, y + DoubleLineOffset); // Bottom Line dStart = -direction * DoubleIntersectionLeft(startToLeft, startToRight, startAhead); dEnd = direction * DoubleIntersectionRight(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForDouble, xStart + dStart, y - DoubleLineOffset, xEnd + dEnd, y - DoubleLineOffset); } else if (LinePattern != GridLinePattern.Thick) { SetLinePattern(cb, LinePattern); float dStart = -direction * ThinIntersection(startToLeft, startToRight, startAhead); float dEnd = direction * ThinIntersection(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForThin, xStart + dStart, y, xEnd + dEnd, y); } else { float dStart = -direction * ThickIntersection(startToLeft, startToRight, startAhead); float dEnd = direction * ThickIntersection(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForThick, xStart + dStart, y, xEnd + dEnd, y); } cb.Stroke(); } } private void DrawLineVertical(PdfContentByte cb, string side, float x, float yStart, float yEnd, GridLinePattern LinePattern, GridLinePattern startToLeft, GridLinePattern startToRight, GridLinePattern startAhead, GridLinePattern endToLeft, GridLinePattern endToRight, GridLinePattern endAhead) { if (LinePattern != GridLinePattern.None) { float direction = (yStart < yEnd) ? 1 : -1; InitializeLineStyle(cb); SetLineColor(cb, r1, c1, side); if (LinePattern == GridLinePattern.Double) { //Left Line float dStart = -direction * DoubleIntersectionRight(startToLeft, startToRight, startAhead); float dEnd = direction * DoubleIntersectionLeft(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForDouble, x - DoubleLineOffset, yStart + dStart, x - DoubleLineOffset, yEnd + dEnd); //Right Line dStart = -direction * DoubleIntersectionLeft(startToLeft, startToRight, startAhead); dEnd = direction * DoubleIntersectionRight(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForDouble, x + DoubleLineOffset, yStart + dStart, x + DoubleLineOffset, yEnd + dEnd); } else if (LinePattern != GridLinePattern.Thick) { SetLinePattern(cb, LinePattern); float dStart = -direction * ThinIntersection(startToLeft, startToRight, startAhead); float dEnd = direction * ThinIntersection(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForThin, x, yStart + dStart, x, yEnd + dEnd); } else { float dStart = -direction * ThickIntersection(startToLeft, startToRight, startAhead); float dEnd = direction * ThickIntersection(endToLeft, endToRight, endAhead); DrawLine(cb, LineThicknessForThick, x, yStart + dStart, x, yEnd + dEnd); } cb.Stroke(); } } #endregion #region Intersection Diagram /* driving into an intersection on line being drawn, facing the intersection. Each intersection requires * drawing of each of the four cases: Case 1: Line being drawn right: lineToLeft ^ | Line Being Drawn ----->|---> LineAhead | v lineToRight Case 2: Line being drawn left: lineToRight ^ | LineAhead <-----|<--- Line Being Drawn | v lineToLeft Case 3: Line being drawn up: lineAhead ^ | lineToLeft <-----|----> lineToRight ^ | | Line Being Drawn Case 4: Line being drawn down: Line Begin Drawn | | v lineToRight <-----|----> lineToLeft | | v lineAhead * */ #endregion #region Border Intersection Methods private static float DoubleIntersectionLeft(GridLinePattern lineToLeft, GridLinePattern lineToRight, GridLinePattern lineAhead) { if (lineToLeft == GridLinePattern.Double) return -DoubleLineOffset; if (lineToRight == GridLinePattern.Double || lineAhead == GridLinePattern.Double) return DoubleLineOffset; if (lineToLeft == GridLinePattern.Thick || lineToRight == GridLinePattern.Thick) return DoubleUnderThick; if (VlnBorders.LineWidth(lineToLeft) == 1 || VlnBorders.LineWidth(lineToRight) == 1) return DoubleUnderThin; return 0; } private static float DoubleIntersectionRight(GridLinePattern lineToLeft, GridLinePattern lineToRight, GridLinePattern lineAhead) { if (lineToRight == GridLinePattern.Double) return -DoubleLineOffset; if (lineToLeft == GridLinePattern.Double || lineAhead == GridLinePattern.Double) return DoubleLineOffset; if (lineToLeft == GridLinePattern.Thick || lineToRight == GridLinePattern.Thick) return DoubleUnderThick; if (VlnBorders.LineWidth(lineToLeft) == 1 || VlnBorders.LineWidth(lineToRight) == 1) return DoubleUnderThin; return 0; } private static float ThinIntersection(GridLinePattern lineToLeft, GridLinePattern lineToRight, GridLinePattern lineAhead) { if (lineToLeft == GridLinePattern.Double && lineToRight == GridLinePattern.Double) return -ThinUnderDouble; if (lineToLeft == GridLinePattern.Double || lineToRight == GridLinePattern.Double) { if (lineAhead == GridLinePattern.Double) return -ThinUnderDouble; return ThinOverDouble; } if (lineToLeft == GridLinePattern.Thick || lineToRight == GridLinePattern.Thick) return ThinOverThick; return 0; } private static float ThickIntersection(GridLinePattern lineToLeft, GridLinePattern lineToRight, GridLinePattern lineAhead) { if (lineToLeft == GridLinePattern.Double && lineToRight == GridLinePattern.Double) { if (lineAhead == GridLinePattern.Thick) return ThickOverDouble; return -ThickUnderDouble; } if ( lineToLeft == GridLinePattern.Double || lineToRight == GridLinePattern.Double) { if (lineAhead == GridLinePattern.Double) { if (lineToLeft == GridLinePattern.Thick || lineToRight == GridLinePattern.Thick) return ThickOverDouble; return -ThickUnderDouble; } return ThickOverDouble; } if (VlnBorders.LineWidth(lineToLeft) == 1 && VlnBorders.LineWidth(lineToRight) == 1) return ThickOverThin; return 0; } #endregion #region Basic Border Methods private static void DrawLine(PdfContentByte cb, float lineThickness, float xStart, float yStart, float xEnd, float yEnd) { cb.SetLineWidth(lineThickness); cb.MoveTo(xStart, yStart); cb.LineTo(xEnd, yEnd); } private static void SetLinePattern(PdfContentByte cb, GridLinePattern linePattern) { if (linePattern == GridLinePattern.Dotted) { cb.SetLineDash(0, 2, 0); cb.SetLineCap(PdfContentByte.LINE_CAP_ROUND); } else if (linePattern == GridLinePattern.Dashed) cb.SetLineDash(4, 4, 0); } private static void SetLineColor(PdfContentByte cb, int row, int col, string side) { iTextSharp.text.Color lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Black)); //switch (side) //{ // case "Top": // if (col == 0) lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Blue)); // else lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Cyan)); // break; // case "Left": // if (row == 0) lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Red)); // else lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Magenta)); // break; // case "Bottom": // if (col == 0) lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Green)); // else lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Cyan)); // break; // case "Right": // if (row == 0) lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Orange)); // else lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Magenta)); // break; //} cb.SetColorStroke(lineColor); } private static void InitializeLineStyle(PdfContentByte cb) { cb.SetLineCap(PdfContentByte.LINE_CAP_PROJECTING_SQUARE); // Extend the line by half of it's thickness cb.SetLineDash(0);// Solid Line } #endregion #region Debug Methods private static void SetOpacity(PdfContentByte cb, float opacity) { PdfGState gs = new PdfGState(); gs.StrokeOpacity = opacity; cb.SetGState(gs); } private static void ZoomToCell(iTextSharp.text.pdf.ColumnText myColumnText, float xLeft, float yTop, float xRight, float yBottom) { PdfDestination dest = new PdfDestination(PdfDestination.FITR, xLeft - 4, yBottom , xRight, yTop + 4); myColumnText.Canvas.SetAction(PdfAction.GotoLocalPage(myColumnText.Canvas.PdfWriter.CurrentPageNumber, dest, myColumnText.Canvas.PdfWriter), xLeft, yBottom, xRight, yTop); } #endregion #region Old Border Methods //private void DrawLeftLine(PdfContentByte cb, float xLeft, float yTop, float yBottom) //{ // if (c1 == 0 && LineLeft != GridLinePattern.None) // { // InitializeLineStyle(cb); // SetLineColor(cb, r1, c1, "Left"); // if (LineLeft == GridLinePattern.Double) // { // //Left Line // float dyTop = DoubleIntersectionLeft(LineTopLeft, LineTop, LineLeftAbove); // float dyBottom = -DoubleIntersectionRight(LineBottom, LineBottomLeft, LineLeftBelow); // DrawLine(cb, LineThicknessForDouble, xLeft - DoubleLineOffset, yTop + dyTop, xLeft - DoubleLineOffset, yBottom + dyBottom); // //Right Line // dyTop = DoubleIntersectionRight(LineTopLeft, LineTop, LineLeftAbove); // dyBottom = -DoubleIntersectionLeft(LineBottom, LineBottomLeft, LineLeftBelow); // DrawLine(cb, LineThicknessForDouble, xLeft + DoubleLineOffset, yTop + dyTop, xLeft + DoubleLineOffset, yBottom + dyBottom); // } // else if (LineLeft != GridLinePattern.Thick) // { // SetLinePattern(cb, LineLeft); // float dyTop = ThinIntersection(LineTopLeft, LineTop, LineLeftAbove); // float dyBottom = -ThinIntersection(LineBottom, LineBottomLeft, LineLeftBelow); // DrawLine(cb, LineThicknessForThin, xLeft, yTop + dyTop, xLeft, yBottom + dyBottom); // } // else // { // float dyTop = ThickIntersection(LineTopLeft, LineTop, LineLeftAbove); // float dyBottom = -ThickIntersection(LineBottom, LineBottomLeft, LineLeftBelow); // DrawLine(cb, LineThicknessForThick, xLeft, yTop + dyTop, xLeft, yBottom + dyBottom); // } // cb.Stroke(); // } //} //private void DrawRightLine(PdfContentByte cb, float xRight, float yTop, float yBottom) //{ // if (LineRight != GridLinePattern.None) // { // InitializeLineStyle(cb); // SetLineColor(cb, r1, c1, "Right"); // if (LineRight == GridLinePattern.Double) // { // //Left Line // float dyTop = DoubleIntersectionLeft(LineTop, LineTopRight, LineRightAbove); // float dyBottom = -DoubleIntersectionRight(LineBottomRight, LineBottom, LineRightBelow); // DrawLine(cb, LineThicknessForDouble, xRight - DoubleLineOffset, yTop + dyTop, xRight - DoubleLineOffset, yBottom + dyBottom); // //Right Line // dyTop = DoubleIntersectionRight(LineTop, LineTopRight, LineRightAbove); // dyBottom = -DoubleIntersectionLeft(LineBottomRight, LineBottom, LineRightBelow); // DrawLine(cb, LineThicknessForDouble, xRight + DoubleLineOffset, yTop + dyTop, xRight + DoubleLineOffset, yBottom + dyBottom); // } // else if (LineRight != GridLinePattern.Thick) // { // float dyTop = ThinIntersection(LineTop, LineTopRight, LineRightAbove); // float dyBottom = -ThinIntersection(LineBottomRight, LineBottom, LineRightBelow); // SetLinePattern(cb, LineRight); // DrawLine(cb, LineThicknessForThin, xRight, yTop + dyTop, xRight, yBottom + dyBottom); // } // else // { // float dyTop = ThickIntersection(LineTop, LineTopRight, LineRightAbove); // float dyBottom = -ThickIntersection(LineBottomRight, LineBottom, LineRightBelow); // DrawLine(cb, LineThicknessForThick, xRight, yTop + dyTop, xRight, yBottom + dyBottom); // } // cb.Stroke(); // } //} //private void DrawTopLine(PdfContentByte cb, float xLeft, float xRight, float yTop) //{ // if (r1 == 0 && TopSide != GridLinePattern.None) // { // InitializeLineStyle(cb); // SetLineColor(cb, r1, c1, "Top"); // if (TopSide == GridLinePattern.Double) // { // // Top Line // float dxLeft = -DoubleIntersectionRight(LeftSide, AboveLeftSide, LeftOfTopSide); // float dxRight = DoubleIntersectionLeft(AboveRightSide, RightSide, RightOfTopSide); // DrawLine(cb, LineThicknessForDouble, xLeft + dxLeft, yTop + DoubleLineOffset, xRight + dxRight, yTop + DoubleLineOffset); // // Bottom Line // dxLeft = -DoubleIntersectionLeft(LeftSide, AboveLeftSide, LeftOfTopSide); // dxRight = DoubleIntersectionRight(AboveRightSide, RightSide, RightOfTopSide); // DrawLine(cb, LineThicknessForDouble, xLeft + dxLeft, yTop - DoubleLineOffset, xRight + dxRight, yTop - DoubleLineOffset); // } // else if (TopSide != GridLinePattern.Thick) // { // SetLinePattern(cb, TopSide); // float dxLeft = -ThinIntersection(LeftSide, AboveLeftSide, LeftOfTopSide); // float dxRight = ThinIntersection(AboveRightSide, RightSide, RightOfTopSide); // DrawLine(cb, LineThicknessForThin, xLeft + dxLeft, yTop, xRight + dxRight, yTop); // } // else // { // float dxLeft = -ThickIntersection(LeftSide, AboveLeftSide, LeftOfTopSide); // float dxRight = ThickIntersection(AboveRightSide, RightSide, RightOfTopSide); // if (c1 == 0) // Console.WriteLine("'{0}','{1}','{2}',{3},{4}", LeftSide, AboveLeftSide, LeftOfTopSide, dxLeft, ThickOverThin); // DrawLine(cb, LineThicknessForThick, xLeft + dxLeft, yTop, xRight + dxRight, yTop); // } // cb.Stroke(); // } //} //private void DrawBottomLine(PdfContentByte cb, float xLeft, float xRight, float yBottom) //{ // if (BottomSide != GridLinePattern.None) // { // InitializeLineStyle(cb); // SetLineColor(cb, r1, c1, "Bottom"); // if (BottomSide == GridLinePattern.Double) // { // // Top Line // float dxLeft = -DoubleIntersectionRight(BelowLeftSide, LeftSide, LeftOfBottomSide); // float dxRight = DoubleIntersectionLeft(RightSide, BelowRightSide, RightOfBottomSide); // DrawLine(cb, LineThicknessForDouble, xLeft + dxLeft, yBottom + DoubleLineOffset, xRight + dxRight, yBottom + DoubleLineOffset);// Top Line // // Bottom Line // dxLeft = -DoubleIntersectionLeft(BelowLeftSide, LeftSide, LeftOfBottomSide); // dxRight = DoubleIntersectionRight(RightSide, BelowRightSide, RightOfBottomSide); // DrawLine(cb, LineThicknessForDouble, xLeft + dxLeft, yBottom - DoubleLineOffset, xRight + dxRight, yBottom - DoubleLineOffset);//Bottom Line // } // else if (BottomSide != GridLinePattern.Thick) // Bottom line is thin. Determine if intersecting with double: // { // SetLinePattern(cb, BottomSide); // float dxLeft = -ThinIntersection(BelowLeftSide, LeftSide, LeftOfBottomSide); // float dxRight = ThinIntersection(RightSide, BelowRightSide, RightOfBottomSide); // DrawLine(cb, LineThicknessForThin, xLeft + dxLeft, yBottom, xRight + dxRight, yBottom); // } // else // { // float dxLeft = -ThickIntersection(BelowLeftSide, LeftSide, LeftOfBottomSide); // float dxRight = ThickIntersection(RightSide, BelowRightSide, RightOfBottomSide); // DrawLine(cb, LineThicknessForThick, xLeft + dxLeft, yBottom, xRight + dxRight, yBottom); // } // cb.Stroke(); // } //} #endregion } }