1537 lines
57 KiB
C#

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
{
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; }
}
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;
for (int r = 0; r < RowTop.Length - 1; r++)
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;
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
#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<vlnCell> // RHM20150429 - Table Scrunch
{
#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
#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);
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;
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);
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. 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.
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);
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);
else
hMax = Math.Max(hMax, hContent - (cr.r2 - cr.r1) * _SixLinesPerInch);
if (hContent > h)
{ // RHM20150429 - Table Scrunch
//if (ShowDetails) Console.WriteLine("Less {0},{1},{2},{3},{4},{5}", r, c, posBefore, posAfter, 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);
MyTable.HContents[cr.r2] = hMax+2;
}
Add(new vlnCell(cr.r1, cr.c1, cr.r2, cr.c2, MyTable, myPara,hContent));
}
}
}
}
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);
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));
}
}
// 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;
}
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 VEWCN SUR_WTC
// tables would print. There were a number of tables, for example in STN NB-106/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 = str.Replace(@"\~", @"\u160?").Replace(@" \ulnone", @"\u160?\ulnone");
else
_StatRTB.Text = str;
_StatRTB.SelectAll();
_StatRTB.SelectionColor = PrintOverride.OverrideTextColor(System.Drawing.Color.Black);
str = _StatRTB.Rtf;
return str;
}
public static iTextSharp.text.Paragraph RtfToParagraph(string rtf, iTextSharp.text.Font mySymFont)
{
IRtfDocument rtfDoc = RtfInterpreterTool.BuildDoc(rtf);
Rtf2iTextSharp rtf2IText = new Rtf2iTextSharp(rtfDoc);
rtf2IText.DefaultFont = mySymFont;
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 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);
}
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;
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;
}
myColumnText1.SetSimpleColumn(1 + left + x, top - y - h , left + x + w - 2, 1 + top - y - hAdjust - adjustTextLocation); // 2 == Default Padding
if (ShowDetails) 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, MyPara.Content.Substring(0, Math.Min(20, MyPara.Content.Length)));
MyPara.MultipliedLeading *= _MyPageHelper.YMultiplier;
vlnCells.FixHyphens(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
myColumnText1.Go();
float posAfter = myColumnText1.YLine; // RHM20150429 - Table Scrunch
if(ShowDetails)Console.WriteLine("ToPDF posBefore,posAfter,difference={0},{1},{2},{3}",
posBefore, posAfter, posBefore - posAfter,w);
myColumnText.Canvas.RestoreState();
}
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
}
}