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; using iTextSharp.text.pdf; using VEPROMS.CSLA.Library; using System.Text.RegularExpressions; namespace Volian.Print.Library { #region Settings // RHM20150429 - Table Scrunch public partial class vlnTable { private string _DebugInfo = null; // RHM20150429 - Table Scrunch public string DebugInfo { get { return _DebugInfo; } set { _DebugInfo = value; } } private int _ItemID = 0; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } private bool _ShowDetails = false; public bool ShowDetails { get { return _ShowDetails; } set { _ShowDetails = value; } } private bool _IsTooBig = false; public bool IsTooBig { get { return _IsTooBig; } set { _IsTooBig = value; } } } public partial class vlnCells { private static float YAdjust_HContent = 4; // 4 private float YAdjust_SpacingAfter { get { return 8-8*MyTable.Adjustment;//0; // 8 } } } public partial class vlnCell { #region Log4Net private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion public bool ShowDetails { get { return MyTable.ShowDetails; } } private static float YAdjust_h = 0; // 0 private float YAdjust_TextLocation { get { return 4 - 4 * MyTable.Adjustment; ;//0; // 4 } } } //public partial class vlnTable //{ // private static float YAdjust_RowTop = 0;//8; // 0 //} //public partial class vlnCells //{ // private static float YAdjust_HContent = 4; // 4 // private static float YAdjust_SpacingAfter = 8;//0; // 8 //} //public partial class vlnCell //{ // private static float YAdjust_h = 0; // 0 // private static float YAdjust_TextLocation = 4;//0; // 4 //} #endregion public partial class vlnTable { #region Properties private float[] _HContents;// RHM20150525 - Table Scrunch public float[] HContents { get { return _HContents; } set { _HContents = value; } } 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; } } private VlnBorders _MyBorders; public VlnBorders MyBorders { get { return _MyBorders; } set { _MyBorders = value; } } 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[RowTop.Length - 1]; } } public float Width { get { return ColLeft[ColLeft.Length - 1]; } } 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; } } private float _TotalContentHeight = 0;// RHM20150525 - Table Scrunc public float TotalContentHeight { get { if (_TotalContentHeight == 0) { foreach (float h in HContents) _TotalContentHeight += h; } return _TotalContentHeight; } } public float SpaceAvailable// RHM20150525 - Table Scrunc { get { return TotalContentHeight ==0 ? 0 : RowTop[RowTop.Length - 1] - TotalContentHeight; } } public float LeadingSpaceAvailable// B2018-085 - Table Scrunch Fix { get { return TotalContentHeight == 0 ? 0 : TotalContentHeight * 1.5F/13.5F; } } private float _TooBig;// RHM20150525 - Table Scrunc public float TooBig { get { return _TooBig; } set { _TooBig = value; //_Adjustment = Math.Min(1F, (_TooBig / (RowTop.Length - 1)) / 12); //if (ShowDetails) Console.WriteLine("TooBig\t{0}\t{1}", value, _Adjustment); //if(ShowDetails) Console.WriteLine("Before RowTop={0}", RowTop[RowTop.Length-1] ); float extra = (_TooBig < SpaceAvailable) ? (SpaceAvailable - _TooBig) / HContents.Length : 0; // B2018-085 Table Scrunch - Adjust Line Spacing float leadingAdjust = 1.0F; if (extra == 0) { // See if we can adjust Leading float newLeading = Math.Max(12.0F, 13.5F - (_TooBig - SpaceAvailable) / LeadingSpaceAvailable); leadingAdjust = newLeading / MyCells.MyLeading; MyCells.MyLeading = newLeading; foreach (vlnCell myCell in MyCells) { myCell.MyPara.SetLeading(MyCells.MyLeading, 0); } } for (int r = 0; r < RowTop.Length - 1; r++) { HContents[r] *= leadingAdjust; RowTop[r + 1] = RowTop[r] + HContents[r] + extra; } //if(ShowDetails) Console.WriteLine("After RowTop={0}", RowTop[RowTop.Length-1] ); } } private float _Adjustment = 0;// RHM20150525 - Table Scrunc public float Adjustment { get { return _Adjustment; } set { _Adjustment = value; } } //private float _YAdjust_RowTop = 0;//8; // 0 public float YAdjust_RowTop { get { return _Adjustment * 12; } } private void DrawRuler(PdfContentByte cb, float x, float yTop, float height)// RHM20150525 - Table Scrunc { VlnSvgPageHelper myPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; if (myPageHelper.DebugLayer != null) { cb.BeginLayer(myPageHelper.DebugLayer); cb.SaveState(); cb.SetLineWidth(.1F); cb.SetColorStroke(new Color(System.Drawing.Color.Orange)); float yBottom = yTop - height; cb.MoveTo(x, yTop); cb.LineTo(x, yBottom); int i = 0; for (float y = yTop; y >= yBottom; y -= 10) { float w = 10; if (i % 10 == 0) w = 30; else if (i % 5 == 0) w = 20; cb.SetLineWidth(w / 30); i++; cb.MoveTo(x + w, y); cb.LineTo(x, y); cb.Stroke(); } i = 0; cb.Stroke(); cb.RestoreState(); cb.EndLayer(); } } private void ShowRowTops(string location)// RHM20150525 - Table Scrunc { if (!ShowDetails) return; StringBuilder sb = new StringBuilder(); for (int i = 0; i < RowTop.Length; i++) sb.Append("\t" + RowTop[i].ToString()); Console.WriteLine(location + "\t" + sb.ToString()); } private void EndSetup()// RHM20150525 - Table Scrunc { if (ShowDetails) ShowRowTops("vlnTable.ctor.2"); if (ShowDetails) Console.WriteLine("^^^^^^vlnTable============{0}===============", ItemID); } private void SetupDebug(VlnFlexGrid myFlexGrid)// RHM20150525 - Table Scrunc { //ShowDetails = myFlexGrid.GetMyItemInfo().InList(38329); //if(ShowDetails) Console.WriteLine("vvvvvvlnTable============{0}===============", ItemID); ItemInfo myItemInfo = myFlexGrid.GetMyItemInfo(); ItemID = myItemInfo.ItemID; Path = myItemInfo.ShortPath; DebugInfo = string.Format("DebugID = {0}, ID={1} Type={2} TypeName='{3}' StepLevel={4} ShortPath={5} Width={6} Left={7} YOffset={8}", 0, myItemInfo.ItemID, myItemInfo.FormatStepType, myItemInfo.FormatStepData == null ? "NoStepData" : myItemInfo.FormatStepData.Type, myItemInfo.StepLevel, myItemInfo.ShortPath, Width, XOffset, YOffset); } #endregion private string _Path; public string Path { get { return _Path; } set { _Path = value; } } #region Constructors public vlnTable(VlnFlexGrid myFlexGrid, iTextSharp.text.pdf.PdfContentByte myContentByte) { MyFlexGrid = myFlexGrid; MyContentByte = myContentByte; InitializeSizes(); SetupDebug(myFlexGrid);// RHM20150525 - Table Scrunc MyCells = new vlnCells(this, MyFlexGrid, MyContentByte); EndSetup();// RHM20150525 - Table Scrunc } #endregion #region Private Methods private void InitializeSizes() { RowTop = new float[MyFlexGrid.Rows.Count + 1]; HContents = new float[MyFlexGrid.Rows.Count];// RHM20150525 - Table Scrunc 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] = 2 + ColLeft[c] + 72 * (MyFlexGrid.Cols[c].Width == -1 // RHM20150429 - Table Scrunch ? 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); if(ShowDetails) Console.WriteLine("vvvvvvToPdf============{0}===============", ItemID);// RHM20150525 - Table Scrunc ShowRowTops("ToPDF1"); PdfContentByte cb = myColumnText.Canvas; // RHM20150429 - Table Scrunch VlnSvgPageHelper myPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; string myLPI = myPageHelper.YMultiplier == 1.0F ? ",6LPI" : ",7LPI"; Rtf2Pdf.DrawPdfDebug(myColumnText.Canvas, left-2, top+1, left + Width, top-myPageHelper.YMultiplier *(Height+1), DebugInfo+", Height= " + (myPageHelper.YMultiplier * Height).ToString() + myLPI, 0); PdfLayer textLayer = myPageHelper == null ? null : myPageHelper.TextLayer; // RHM20150429 - Table Scrunch if (textLayer != null) cb.BeginLayer(textLayer); myPageHelper.AddGap(top, top - Height, left, left + Width); MyCells.ToPdf(myColumnText, left, top); DrawRuler(myColumnText.Canvas, left + Width, top, myPageHelper.YMultiplier * (Height + 1)); // RHM20150429 - Table Scrunch if (textLayer != null) cb.EndLayer(); ShowRowTops("ToPDF2"); if (ShowDetails) Console.WriteLine("^^^^^^ToPdf============{0}===============", ItemID); } 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 partial class vlnCells : List // RHM20150429 - Table Scrunch { #region Log4Net private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion #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; } } public bool ShowDetails// RHM20150525 - Table Scrunc { get { return MyTable.ShowDetails; }} 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(); foreach(vlnCell cell in this) { myTable.MyBorders = VlnBorders.Get(myFlexGrid.MyBorders.ConvertToString()); GridLinePattern glp = cell.AboveLeftSide; glp = cell.AboveRightSide; glp = cell.BelowLeftSide; glp = cell.BelowRightSide; glp = cell.RightOfBottomSide; glp = cell.RightOfTopSide; object ta = cell.TextAlign; } } #endregion private float _MyLeading=13.5F; // B2018-085 AEP and APP worked with 13.5 public float MyLeading { get { return _MyLeading; } set { _MyLeading = value; } } #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++) { float hMax = 12; // RHM20150429 - Table Scrunch for (int c = 0; c < MyFlexGrid.Cols.Count; c++) { CellRange cr = MyFlexGrid.GetMergedRange(r, c); // B2018-033 VCS SAG-6 Steps 3 and 9 and SACRG1 Step 13 // Tables not being scrunched properly // Merged cells should be adjusted based upon the bottom most cell of the range if(MyTable.HContents[r]==0) MyTable.HContents[r] = 12; if (cr.r2 == r && cr.c1 == c)// Use last Row { 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; if (str.Contains(@"\cf")) { str = System.Text.RegularExpressions.Regex.Replace(str, @"\\cf[0-9]\\", @"\"); str = System.Text.RegularExpressions.Regex.Replace(str, @"\\cf[0-9] ", @""); } // the FreeMono font is used for the editor, but VESymbFix is used for printing // The font spefication is embeded in the table text so we need to change the font reference from // FreeMono to VESymbFix before we print the table if (str.ToUpper().Contains("FREEMONO")) str = str.Replace("FreeMono", "VESymbFix"); DisplayText dt = new DisplayText(MyFlexGrid.GetMyItemInfo(), str, false); str = dt.StartText; str = PreProcessRTF(w, str); // If the font is not proportional, pass the symbol font through to RtfToParagraph. It is needed // in underlying code to set the chunk's font if the first character of a cell is a hardspace. Without // this, pdfs were using the Helvetica font, which is a default itextsharp font. ItemInfo ii = MyFlexGrid.GetMyItemInfo(); iTextSharp.text.Font ff = null; if (!ii.FormatStepData.Font.FontIsProportional()) ff = Volian.Svg.Library.VolianPdf.GetFont("VESymbFix", (int)ii.FormatStepData.Font.Size, (int)ii.FormatStepData.Font.WindowsFont.Style); iTextSharp.text.Paragraph myPara = RtfToParagraph(str, ff, r, c); myColumnText1.SetSimpleColumn(0, 0, w-2, MyContentByte.PdfDocument.PageSize.Top); // Padding = 4 if (str.Contains(@"\'05")) { // if there is a hanging indent, the iTextSharp paragraph properties must be set // to print the indent. Replace the indent 'token' with a non-used symbol, this will // create a chunk with that symbol. Then loop through all of the chunks until we find // this symbol, adding up the widths to that point. This width is the value that // needs to be used to set the indent. // Notes: // A hard return will reset the chkW (indent width) back to zero. // We jump out of the processing loop after the first indent token is found and ignor any other ones float chkW = CalculateHangingIndent(str); myPara.IndentationLeft = chkW; myPara.FirstLineIndent = -chkW; } Match match = Regex.Match(str, @"\\fi([-0-9]*) ?\\li([0-9]*)"); if (match.Success) { float fi = float.Parse(match.Groups[1].Value) / 20; // 72 is dots per inch & 96 is standard DPI (120 is KBR's machine) float li = float.Parse(match.Groups[2].Value) / 20; // if there is a hanging indent, the iTextSharp paragraph properties must be set // to print the indent. myPara.IndentationLeft = li; myPara.FirstLineIndent = fi; } // RHM 20120925 - Line spacing should be 6 lines per inch. // B2018-003 Change code to use absolute Leading rather than Multiplied based on Font size myPara.SetLeading(MyLeading, 0); myPara.SpacingAfter = 8; // RHM 20120925 - Add a line to properly space text from lines. if(Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase2)) // RHM20150429 - Table Scrunch myPara.SpacingAfter = 0;// YAdjust_SpacingAfter; // RHM 20120925 - Add a line to properly space text from lines. FixHyphens(myPara, MyTable); FixBackslashes(myPara, MyTable); if (Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase3)) TrimNewlines(myPara); // RHM20150429 - Table Scrunch 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 (Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase4))// RHM20150525 - Table Scrunc { hContent = 0 + posBefore - posAfter;//YAdjust_HContent + posBefore - posAfter; // if (myPara.Chunks.Count > 0 && myPara.Chunks[myPara.Chunks.Count - 1] == "\n") // hContent -= 12; } //if(ShowDetails) Console.WriteLine("{0}\t{1}\t{2}",r,c, hContent/12); if (cr.r1 == cr.r2) hMax = Math.Max(hMax, hContent); // B2018-033 VCS SAG-6 Steps 3 and 9 and SACRG1 Step 13 // Tables not being scrunched properly // Merged cells should be adjusted based upon the bottom most cell of the range else if(cr.r2 == r) // Adjust for Previous rows within merged cells hMax = Math.Max(hMax, hContent- SumContents(cr.r1,cr.r2)); //else // hMax = Math.Max(hMax, hContent - (cr.r2 - cr.r1) * _SixLinesPerInch); if (hContent > h) { // RHM20150429 - Table Scrunch // B2018-003 modified debug to add h //if (ShowDetails) Console.WriteLine("Less {0},{1},{2},{3},{4},{5},{6}", r, c, posBefore, posAfter, h, hContent, hMax); MyTable.AdjustRowTop(cr.r1, cr.r2, hContent); } // RHM20150429 - Table Scrunch if (Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase5)) { //if (ShowDetails) Console.WriteLine("Greater{0},{1},{2},{3},{4},{5}", r, c, posBefore, posAfter, hContent, hMax); //if (c == MyFlexGrid.Cols.Count - 1) //MyTable.AdjustRowTop(cr.r1, cr.r2, hMax + 6); //B2018-033 - Adjuust current row MyTable.HContents[r] = hMax+2; } Add(new vlnCell(cr.r1, cr.c1, cr.r2, cr.c2, MyTable, myPara,hContent)); } } } // This summarizes the Content heights per row //int i=0; //foreach (float h in MyTable.HContents) // Console.WriteLine("{0}\t{1}", ++i, h); } private float SumContents(int first, int last) { float total = 0; for (int i = first; i < last; i++) total += MyTable.HContents[i]; return total; } // B2017-105 if a symbol character was set to a bigger font size, then the positioning of the larger symbol character was printing too high on the line // found with Wolf Creek use of the empty box symbol private float BiggestFontSize(Paragraph myPara) { float fontSize = 12; foreach (Chunk ck in myPara.Chunks) { fontSize = Math.Max(fontSize, ck.Font.Size); if (ck.Font.Size > 12) { ck.SetTextRise(-2f); //_MyLog.WarnFormat("set text rise"); } } return fontSize; } // B2017-233, B2017-234 needed to get the smallest font size to help decide if a vertical adjustment of the text is needed in a table cell private float SmallestFontSize(Paragraph myPara) { float fontSize = 30; foreach (Chunk ck in myPara.Chunks) { fontSize = Math.Min(fontSize, ck.Font.Size); } return fontSize; } private void ShowChunks(System.Collections.ArrayList chunks) // RHM20150429 - Table Scrunch { StringBuilder sb = new StringBuilder(); foreach (Chunk chk in chunks) { sb.Append(BuildChunks(chk.Content)); } //if (ShowDetails) Console.WriteLine("Chunks = '{0}'", sb.ToString()); } private string BuildChunks(string str) { StringBuilder sb = new StringBuilder(); foreach(char c in str) { if (((int)c) < 0x20 || ((int)c) > 0x7F) sb.Append(string.Format("<{0:X4}>",(int)c)); else sb.Append(c); } return "{" + sb.ToString() + "}"; } private void TrimNewlines(Paragraph myPara) { while (myPara.Count > 0 && ParaEndsWithNewLine(myPara)) myPara.RemoveAt(myPara.Count - 1); } private bool ParaEndsWithNewLine(Paragraph myPara) { Chunk chk = myPara[myPara.Count - 1] as Chunk; if (chk == null) return false; if (chk.Content == "\n") return true; return false; } public class VlnSplitCharacter : ISplitCharacter { public bool IsSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { return (cc[current] == ' '); } public bool IsSplitCharacter(char c) { return (c == ' '); } } public static VlnSplitCharacter mySplitter = new VlnSplitCharacter(); internal static void FixHyphens(Paragraph myPara, vlnTable myTable) { // Find chunk with hardhyphen // If a hard hyphen is found, the remove it and add a dash (keyboard minus sign) to the beginning // of the text that follows it. int hype=-1; Font fnt = null; while ((hype = GetHyphen(myPara)) > -1) { fnt = null; if (hype > 0) { Chunk chk1 = (Chunk)myPara[hype - 1]; if (hype > 1 && chk1.Content.Equals("\n")) chk1 = (Chunk)myPara[hype - 2]; fnt = chk1.Font; // use the font of the text that follows the hyphen (dash) } else if (hype < myPara.Count - 1) { Chunk chk2 = (Chunk)myPara[hype + 1]; if (hype != 0 && !chk2.Content.Equals("\n")) fnt = chk2.Font; // use the font of the text that follows the hyphen (dash) } if (fnt == null) { // if there was no text following the hypen, then use the font defined for tables in the plant's format VEPROMS.CSLA.Library.VE_Font vfnt = myTable.MyFlexGrid.GetMyItemInfo().FormatStepData.Font; //System.Drawing.Font ffont = new System.Drawing.Font(vfnt.Family, (float)vfnt.Size); System.Drawing.Font ffont = VE_Font.GetWinSysFont(vfnt.Family, (float)vfnt.Size); fnt = Volian.Svg.Library.VolianPdf.GetFont(ffont); fnt.SetStyle(myPara.Font.Style); fnt.SetColor(myPara.Font.Color.R,myPara.Font.Color.G,myPara.Font.Color.B); } Chunk chk = (Chunk)myPara[hype]; // THIS CODE IS USED FOR DEBUGGING //if (!fnt.Familyname.StartsWith("L")) //{ // Console.WriteLine("font = {0}", makeitpretty(fnt)); // Console.WriteLine("Hype = {0}\r\n{1}",hype, myPara.Content); // if (hype > 0) // { // Chunk chk3 = (Chunk)myPara[hype - 1]; // Console.WriteLine("before '{0}'", chk3.Content); // } // Chunk chk4 = (Chunk)myPara[hype]; // Console.WriteLine("during '{0}'", chk4.Content); // if (hype < myPara.Count -1) // { // Chunk chk5 = (Chunk)myPara[hype + 1]; // Console.WriteLine("after '{0}'", chk5.Content); // } //} string prefix = ""; if (chk.Content == "\u2011" && hype < (myPara.Count - 1)) { myPara.RemoveAt(hype);// Remove standalone hyphen chk = (Chunk)myPara[hype]; prefix = "-"; } myPara.RemoveAt(hype); myPara.Insert(hype, new Chunk(prefix + chk.Content.Replace("\u2011", "-"), fnt)); } } internal static void FixBackslashes(Paragraph myPara, vlnTable myTable) { // Find chunk with backslash B2014-108 backslash in tables // If a backslash symbold is found, the remove it and add a backslash (keyboard char) to the beginning // of the text that follows it. int bckSlsh = -1; Font fnt = null; while ((bckSlsh = GetBackslash(myPara)) > -1) { fnt = null; if (bckSlsh > 0) { Chunk chk1 = (Chunk)myPara[bckSlsh - 1]; if (bckSlsh > 1 && chk1.Content.Equals("\n")) chk1 = (Chunk)myPara[bckSlsh - 2]; fnt = chk1.Font; // use the font of the text that follows the hyphen (dash) } else if (bckSlsh < myPara.Count - 1) { Chunk chk2 = (Chunk)myPara[bckSlsh + 1]; if (bckSlsh != 0 && !chk2.Content.Equals("\n")) fnt = chk2.Font; // use the font of the text that follows the hyphen (dash) } if (fnt == null) { // if there was no text following the hypen, then use the font defined for tables in the plant's format VEPROMS.CSLA.Library.VE_Font vfnt = myTable.MyFlexGrid.GetMyItemInfo().FormatStepData.Font; //System.Drawing.Font ffont = new System.Drawing.Font(vfnt.Family, (float)vfnt.Size); System.Drawing.Font ffont = VE_Font.GetWinSysFont(vfnt.Family, (float)vfnt.Size); fnt = Volian.Svg.Library.VolianPdf.GetFont(ffont); fnt.SetStyle(myPara.Font.Style); fnt.SetColor(myPara.Font.Color.R, myPara.Font.Color.G, myPara.Font.Color.B); } Chunk chk = (Chunk)myPara[bckSlsh]; // THIS CODE IS USED FOR DEBUGGING //if (!fnt.Familyname.StartsWith("L")) //{ // Console.WriteLine("font = {0}", makeitpretty(fnt)); // Console.WriteLine("Hype = {0}\r\n{1}",hype, myPara.Content); // if (hype > 0) // { // Chunk chk3 = (Chunk)myPara[hype - 1]; // Console.WriteLine("before '{0}'", chk3.Content); // } // Chunk chk4 = (Chunk)myPara[hype]; // Console.WriteLine("during '{0}'", chk4.Content); // if (hype < myPara.Count -1) // { // Chunk chk5 = (Chunk)myPara[hype + 1]; // Console.WriteLine("after '{0}'", chk5.Content); // } //} string prefix = ""; if (chk.Content == "\u2572" && bckSlsh < (myPara.Count - 1)) { myPara.RemoveAt(bckSlsh);// Remove standalone hyphen chk = (Chunk)myPara[bckSlsh]; prefix = "\\"; } myPara.RemoveAt(bckSlsh); myPara.Insert(bckSlsh, new Chunk(prefix + chk.Content.Replace("\u2572", "\\"), fnt)); } } // THIS FUNCTION IS USED FOR DEBUGGING private static string makeitpretty(Font fnt) { return string.Format("font {0}, size {1}, style {2}", fnt.Familyname, fnt.Size, fnt.Style); } private static int GetHyphen(Paragraph myPara) { int index=0; foreach (Chunk chk in myPara.Chunks) if (chk.Content.Contains("\u2011")) return index; else index++; return -1; } private static int GetBackslash(Paragraph myPara) { int index=0; foreach (Chunk chk in myPara.Chunks) if (chk.Content.Contains("\u2572")) return index; else index++; return -1; } public static float CalculateHangingIndent(string rtf) { float chkW = 0; // **** This is intened to be a temporary fix for V.C.Summer **** // Two procedures would not print: A-2 SAG in Summer's SAMG set, and SAG-3 in Summer's PWOG DAMG set. // These procedures have tables with hanging indents and use the Letter Gothic Tall font. // It appears that the font information for the hanging indent character is not included in the RTF // for those table cells. // This piece of code checks for the existance of a font definition of \f1 which is need for the \u9999? indent character // If the a font definition of \f1 is not found then the indent character is removed. This will allow the procedure to print // but the text in that table cell will not be indented. - jsj 10/10/2014 //IRtfDocument rtfDoc2 = RtfInterpreterTool.BuildDoc(rtf.Replace(@"\'05", @"\f1 \u9999? \f0 ")); IRtfDocument rtfDoc2 = null; //if (rtf.Contains(@"\f1\fnil\fcharset0 ")) // rtfDoc2 = RtfInterpreterTool.BuildDoc(rtf.Replace(@"\'05", @"\f1 \u9999? \f0 ")); //else //{ // first add the symbol font and then surround the indent as above. rtfDoc2 = RtfInterpreterTool.BuildDoc(rtf.Replace(@"\'05", @"\par\u9999?\par")); //} Rtf2iTextSharp rtf2IText2 = new Rtf2iTextSharp(rtfDoc2); iTextSharp.text.Paragraph para2 = rtf2IText2.Convert(); for (int ic = 0; ic < para2.Chunks.Count; ic++) { Chunk chk = para2.Chunks[ic] as Chunk; if (chk.Content[0] == 9999) break; if (chk.Content.Contains("\u270f")) { int i = chk.Content.IndexOf('\u270F'); int n = chk.Content.Length; chkW += chk.GetWidthPoint() * i / (n - i); break; } if (chk.Content.Contains("\n")) { if (ic < para2.Chunks.Count - 2 && (para2.Chunks[ic + 1] as Chunk).Content.StartsWith("\u270f")) return chkW; chkW = 0; //hard return - reset chkW (indent start) } chkW += chk.GetWidthPoint(); } return chkW; } private static StepRTB _StatRTB = new StepRTB(); private string PreProcessRTF(float w, string str) { _StatRTB.Text = string.Empty; _StatRTB.Width = (int)w; _StatRTB.Font = MyFlexGrid.Font; if (str.StartsWith(@"{\rtf")) { // The 'Replace(@" \ulnone", @"\u160?\ulnone")' was added so that data in VEWCNSUR_MTC // tables would print. There were a number of tables, for example in STN NB-115/8.1.6, // that had a series of spaces underlined and these spaces were not underlined in the // generated pdf. It seems that there is a problem somewhere in the rtb -> itextsharp // level. This fixed the immediate problem. If there is 'b0' (bold off) after the // space before the 'ulnone' the following won't work. Also, this change was not // made in the non-table code. If the problem occurs there, it should be added. _StatRTB.Rtf = Regex.Replace(str.Replace(@"\~", @"\u160?"), @"(? /// Fix RTF so that text uses the Text font rather than the Symbol font. /// /// /// private string FixRTFToPrint(string rtf,int r, int c) { // Only do this if the text contains symbols. // B2019-067 Check for a proportional symbol font such as FreeSerif which is used for proportional fonts. // The Clock, Check Mark, and Heavy X symbols were not printing the correct character (all are replaced with a WingDing font character) if (rtf.Contains("VESymbFix") || rtf.Contains(Volian.Base.Library.vlnFont.ProportionalSymbolFont)) { // bug fix: B2017-117 was getting an out of window handles error when doing a print all for Bryon // add the using statment to free up window handle that is created doing a New RichTextBox() using (System.Windows.Forms.RichTextBox rtb = new System.Windows.Forms.RichTextBox()) { rtb.Rtf = rtf.Replace(@"\u9586?", "").Replace(@"\~",@"\u160?");// rename backslash character and B2018-107 \~ to hard space to avoid RTF confusion string strRTF = rtf; bool changed = false; // C2017-008 - WCN wants the box symbol to look like their checkoff/signoff box // Check for a list of replacement character for symbols in the format file // ReplaceSymbolChars lets you do one or more of the following with a symbol character: // - change the point size // - change the style // - change the font family // - change the symbol character // // below is taken from the BaseAll format file - is currently commentout and there for reference // Wolf Creek (WCN) currently uses this to increase the size of the box symbol // // // // // get the list of symbol replacements FormatData fmtdata = (MyFlexGrid.GetMyItemInfo().ActiveFormat != null) ? MyFlexGrid.GetMyItemInfo().ActiveFormat.PlantFormat.FormatData : FormatInfo.PROMSBaseFormat.FormatData; ReplaceSymbolCharList SymReplaceList = (fmtdata != null && fmtdata.SectData.ReplaceSymbolCharList != null) ? fmtdata.SectData.ReplaceSymbolCharList : null; // Look at one character at a time for (int i = 0; i < rtb.TextLength; i++) { rtb.Select(i, 1); // If the character is a printable character set the font to the text font // B2019-067 also check for a proportional symbol font for example, FreeSerif if (rtb.SelectionLength == 0 && strRTF != null && (rtb.SelectionFont.FontFamily.Name == "VESymbFix" || rtb.SelectionFont.FontFamily.Name == Volian.Base.Library.vlnFont.ProportionalSymbolFont)) { // Add debug information to the error log if the selection length is zero // Changed debug information to make it more useful _MyLog.WarnFormat("\r\n=====>Font Issues in Table ItemID {0} [{1},{2}] I= {3}, TXT = {4}",MyTable.ItemID,r,c, i, rtb.Text.Substring(Math.Max(0, i-10), Math.Min(20,rtb.TextLength -i))); strRTF = null; } // bug fix: B2017-046 - check for selection length of zero to fix index out of bounds error // System.Windows.Forms.RichTextBox is having issues selection text in some cases (ex. Symbol char followed by a RO reference - without a space between them) // B2019-067 also check fora proportional symbol font for example, FreeSerif if (rtb.SelectionLength > 0 && (rtb.SelectionFont.FontFamily.Name == "VESymbFix" || rtb.SelectionFont.FontFamily.Name == Volian.Base.Library.vlnFont.ProportionalSymbolFont) && rtb.SelectedText[0] > ' ' && rtb.SelectedText[0] <= '\xFF') { //use bolding underline italics from local font System.Drawing.Font fnt = rtb.SelectionFont; // follow through in fixing an Out of Window Handles bug, use new function to see if // we can retrieve the font from a dictionary instead a doing a New and using another // window handle B2017-117 //rtb.SelectionFont = new System.Drawing.Font(DefaultFont, fnt.Style); rtb.SelectionFont = VE_Font.GetWinSysFont(DefaultFont, fnt.Style); changed = true; } if ((rtb.SelectionFont.FontFamily.Name == "VESymbFix" || rtb.SelectionFont.FontFamily.Name.StartsWith(Volian.Base.Library.vlnFont.ProportionalSymbolFont)) && rtb.SelectedText.Length > 0) // C2017-036 get best available proportional font for symbols { for (int j = 0; j < SymReplaceList.MaxIndex; j++) { ReplaceChar rc = SymReplaceList[j]; if (rc.Unicode != null && (rc.Family != null || rc.Size != null || rc.Style != null)) { char rc_uchar = Convert.ToChar(Convert.ToInt32(rc.Unicode)); if (rc_uchar == rtb.SelectedText[0]) { //use bolding underline italics from local font System.Drawing.Font fnt = rtb.SelectionFont; //System.Drawing.Font fntw = new System.Drawing.Font((rc.Family != null) ? rc.Family : fnt.FontFamily.Name, (rc.Size != null) ? (float)rc.Size : fnt.Size, (rc.Style != null) ? (System.Drawing.FontStyle)rc.Style : fnt.Style); System.Drawing.Font fntw = VE_Font.GetWinSysFont((rc.Family != null) ? rc.Family : fnt.FontFamily.Name, (rc.Size != null) ? (float)rc.Size : fnt.Size, (rc.Style != null) ? (System.Drawing.FontStyle)rc.Style : fnt.Style); rtb.SelectionFont = fntw; if (rc.Replace != null) { char rc_RplChar = Convert.ToChar(Convert.ToInt32(rc.Replace)); rtb.SelectedText = rc_RplChar.ToString(); } changed = true; break; // break out of foreach loop since we changed the character } } } } } if (changed) return rtb.Rtf.Replace("", @"\u9586?"); } } return rtf; } 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) { // B2020-034 - the topPlacementAdjust is used to position the text vertically in the table cells. int topPlacementAdjust = (myCell.MyPara.Font.Size == 12)? 1 : 3; // for font size of 12 set to one, else set to 3 myCell.ToPdf(myColumnText, left, top, topPlacementAdjust); } } #endregion } public partial class vlnCell // RHM20150429 - Table Scrunch { #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); } // B2018-003 - RHM 20180319 Add public void PdfDebug(iTextSharp.text.pdf.ColumnText myColumnText, float x, float bottom, float right, float y, string debugText, float yDescent) { PdfContentByte cb = myColumnText.Canvas; VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; PdfLayer debugLayer = _MyPageHelper == null ? null : _MyPageHelper.DebugLayer; if (debugLayer == null) return; System.Drawing.Color sysColor = PrintOverride.OverrideDebugColor(System.Drawing.Color.Gray); cb.SaveState(); cb.BeginLayer(debugLayer); cb.SetColorStroke(new Color(sysColor)); cb.SetLineWidth(.1F); cb.MoveTo(x, y - yDescent); cb.LineTo(right, y - yDescent); cb.LineTo(right, bottom - yDescent); cb.LineTo(x, bottom - yDescent); cb.LineTo(x, y - yDescent); for (float yy = y - MyPara.TotalLeading; yy > bottom; yy -= MyPara.TotalLeading) { cb.MoveTo(x, yy - yDescent); cb.LineTo(right, yy - yDescent); } cb.Stroke(); if (debugText != "") { ColumnText ct = new ColumnText(cb); ct.SetSimpleColumn(x, y - yDescent, right, y - yDescent - 50); iTextSharp.text.Font font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 2); Chunk chk = new Chunk(debugText + string.Format(", Top = {0}", y), font); Phrase ph = new Phrase(chk); ct.AddElement(ph); cb.SetColorFill(new Color(sysColor)); ct.Go(); } cb.EndLayer(); cb.RestoreState(); } //RHM 20180319 End of Add public void ToPdf(iTextSharp.text.pdf.ColumnText myColumnText, float left, float top, int topPlacementAdjust) { 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; if (Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase6))// RHM20150525 - Table Scrunc { h = YAdjust_h + mult * MyTable.RowTop[r2 + 1] - y; } BordersToPdf(myColumnText, left, top, x, w, y, h ); float hAdjust = VeritcalTextAlignment(h,_MyPageHelper.YMultiplier); 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 if (Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase7))// RHM20150525 - Table Scrunc { adjustTextLocation = mult * 0; if (mult != 1F) adjustTextLocation=1; } // B2019-093 missing table cell text when printing South Texas FSG-20 step 1 // Added two more to the last parameter of SetSimplColun (it's the ury value - upper y value) // this will have the cell text print a little more toward the top of the cell //myColumnText1.SetSimpleColumn(1 + left + x, top - y - h, left + x + w - 2, 3 + top - y - hAdjust - adjustTextLocation); // 2 == Default Padding // B2019-109 Adjusted width of cell to match edit cell // B2020-034 - use the passed in topPlacementAdjust value which is set based on the font size. myColumnText1.SetSimpleColumn(.5F + left + x, top - y - h, left + x + w - 1.5F, topPlacementAdjust + top - y - hAdjust - adjustTextLocation); // 2 == Default Padding // B2018-003 - RHM 20180319 Change Debug Output string dbg = string.Format("Row={0}, Col={1}, Leading={2}, SpacingBefore={3}", r1, c1, MyPara.TotalLeading * _MyPageHelper.YMultiplier, MyPara.SpacingBefore); // B2018-033 VCS SAG-6 Steps 3 and 9 and SACRG1 Step 13 // Added Header to debug output if (ShowDetails) { if(FirstTime) Console.WriteLine("\"r1\"\t\"c1\"\t\"hAdjust\"\t\"adjustTextLocation\"\t\"y\"\t\"h\"\t\"top\"\t\"1 + top - y - hAdjust - adjustTextLocation\"\t\""+ "_MyPageHelper.YMultiplier\"\t\"Text\""); Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t\"{9}\"" , r1, c1, hAdjust, adjustTextLocation, y, h, top, 1 + top - y - hAdjust - adjustTextLocation, _MyPageHelper.YMultiplier, ShowText(MyPara.Content.Substring(0, Math.Min(20, MyPara.Content.Length)))); } // C2018-004 create meta file for baseline compares Volian.Base.Library.BaselineMetaFile.WriteLine(" R {0} C {1} Y {2} H {3} Top {4} hAdj {5} TxtLocAdj {6}", r1, c1, y, h, 2+top, hAdjust,adjustTextLocation); foreach (Chunk chk1 in MyPara.Chunks) { string ctai = Rtf2Pdf.ChunkTextAttributesInfo(chk1); Volian.Base.Library.BaselineMetaFile.WriteLine("\t{0},{1},{2},{3},\"{4}\"", chk1.Font.Familyname, chk1.Font.Size, chk1.Font.Style, ctai, TextForBaseline.FixText(chk1.Content)); } // B2018-003 - Adjust Leading for 7LPI if necessary MyPara.SetLeading(MyPara.TotalLeading * _MyPageHelper.YMultiplier, 0); vlnCells.FixHyphens(MyPara, MyTable); vlnCells.FixBackslashes(MyPara, MyTable); myColumnText1.AddElement(MyPara); foreach(object obj in MyPara) { if(obj is iTextSharp.text.Image) { iTextSharp.text.Image img = obj as iTextSharp.text.Image; img.SetAbsolutePosition(left,top-h); img.ScaleAbsoluteWidth(w); img.ScaleAbsoluteHeight(h); myColumnText.Canvas.AddImage(img); } } float posBefore = myColumnText1.YLine; // RHM20150429 - Table Scrunch int cellStatus = myColumnText1.Go(); // B2019-109 Add to Error Log if cell too small if (cellStatus != 1) { //System.Windows.Forms.MessageBox.Show("Cell width too narrow \r\n" + MyTable.Path, "Narrow Cell", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); _MyLog.WarnFormat("\r\n=-=-=-= Cell Width too narrow, text is wrapping ItemID={0} Location={1}, Row={2}, Col={3}, Status={4}",MyTable.ItemID, MyTable.Path, r1, c1, cellStatus); } float posAfter = myColumnText1.YLine; // RHM20150429 - Table Scrunch // B2018-033 Removed debug printout //if(ShowDetails)Console.WriteLine("ToPDF posBefore,posAfter,difference={0},{1},{2},{3}", // posBefore, posAfter, posBefore - posAfter,w); // B2018-003 Calculate hh float hh = posBefore - posAfter; PdfDebug(myColumnText1, 1 + left + x, top - y - hh - hAdjust, left + x + w - 2, 3 + top - y - hAdjust - adjustTextLocation, dbg, MyPara.TotalLeading / 5); myColumnText.Canvas.RestoreState(); } // B2018-033 VCS SAG-6 Steps 3 and 9 and SACRG1 Step 13 // Added Header to debug output private static bool _FirstTime = true; public static bool FirstTime { get { bool retval = _FirstTime; _FirstTime = false; return retval; } set { _FirstTime = value; } } // B2018-033 VCS SAG-6 Steps 3 and 9 and SACRG1 Step 13 // Added Header to debug output private string ShowText(string str) { StringBuilder sb = new StringBuilder(); foreach (char c in str) { if(c<32 || c>126) sb.Append(string.Format("[{0:X}]", (int) c)); else sb.Append(c); } return sb.ToString(); } private static float _SixLinesPerInch = 12; // twips public bool IsRangeStyleNull = false; private TextAlignEnum? _TextAlign = null; public TextAlignEnum? TextAlign { get { if (_TextAlign == null) { CellRange cr = MyTable.MyFlexGrid.GetCellRange(r1, c1, r2, c2); if (cr.Style == null) { IsRangeStyleNull = true; return _TextAlign; } else { IsRangeStyleNull = false; _TextAlign = cr.Style.TextAlign; } } return (TextAlignEnum)_TextAlign; } } #endregion #region Private Text Methods private float VeritcalTextAlignment(float h, float mult) { float hAdjust = 0; //CellRange cr = MyTable.MyFlexGrid.GetCellRange(r1, c1, r2, c2); if (!IsRangeStyleNull) { switch (TextAlign) { case TextAlignEnum.CenterBottom: case TextAlignEnum.GeneralBottom: case TextAlignEnum.LeftBottom: case TextAlignEnum.RightBottom: hAdjust = Math.Max(0,h - (mult * HContent) )-1; //Console.WriteLine("\"Bottom\",{0},{1},{2}", h, HContent, hAdjust); break; case TextAlignEnum.CenterCenter: case TextAlignEnum.GeneralCenter: case TextAlignEnum.LeftCenter: case TextAlignEnum.RightCenter: hAdjust = Math.Max(0,(h - (mult * HContent)) / 2)-1; //Console.WriteLine("\"Middle\",{0},{1},{2}", h, HContent, hAdjust); 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 } }