diff --git a/PROMS/Volian.Print.Library/ItemToParagraph.cs b/PROMS/Volian.Print.Library/ItemToParagraph.cs new file mode 100644 index 00000000..f6f985d1 --- /dev/null +++ b/PROMS/Volian.Print.Library/ItemToParagraph.cs @@ -0,0 +1,393 @@ +using System; +using System.Collections.Generic; +using System.Text; +using VEPROMS.CSLA.Library; +//using Volian.Controls.Library; +using iTextSharp.text; +using iTextSharp.text.pdf; +using iTextSharp.text.factories; +using Itenso.Rtf; +using Itenso.Rtf.Parser; +using Itenso.Rtf.Interpreter; +using Itenso.Rtf.Support; +//using Volian.Svg.Library; +using Volian.Controls.Library; + +namespace Volian.Print.Library +{ + public abstract partial class vlnPrintObject + { + public static string GetRtf(string text, VE_Font vFont) + { + StringBuilder rtfSB = new StringBuilder(); + //DisplayText vlntxt = new DisplayText(text.TrimStart(" ".ToCharArray()), vFont, false); + DisplayText vlntxt = new DisplayText(text, vFont, false); + rtfSB.Append(AddFontTable(vlntxt.TextFont.WindowsFont)); + rtfSB.Append(vlntxt.StartText); + rtfSB.Append("}"); + return rtfSB.ToString(); + } + protected static string AddFontTable(System.Drawing.Font font) + { + StringBuilder rtfSB = new StringBuilder(); + StringBuilder sbbeg = new StringBuilder(); + StringBuilder sbend = new StringBuilder(); + if (font.Bold) + { + sbbeg.Append(@"\b"); + sbend.Append(@"\b0"); + } + if (font.Underline) + { + sbbeg.Append(@"\ul"); + sbend.Insert(0, @"\ulnone"); + } + if (font.Italic) + { + sbbeg.Append(@"\i"); + sbend.Insert(0, @"\i0"); + } + rtfSB.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset2 " + font.FontFamily.Name + @";}"); //}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}}"; + if (!FontIsFixed(font)) + rtfSB.Append(@"{\f1\fnil\fcharset0 Arial Unicode MS;}}{\colortbl ;\red255\green0\blue0;}"); + else + rtfSB.Append(@"{\f1\fnil\fcharset0 VESymbFix;}}{\colortbl ;\red255\green0\blue0;}"); + rtfSB.Append("\r\n"); + // use styles to construct rtf commands to insert into next line (where \b, etc is) + rtfSB.Append(@"\viewkind4\uc1\pard\sl-240\slmult0" + sbbeg.ToString() + @"\fs" + Convert.ToInt32(font.SizeInPoints * 2).ToString() + @" "); // \f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}"; + return rtfSB.ToString(); + } + private static bool FontIsFixed(System.Drawing.Font font) + { + iTextSharp.text.Font iFont = Rtf2iTextSharp.GetFont(font); + float fW = iFont.BaseFont.GetWidthPointKerned("W", 12); + float fE = iFont.BaseFont.GetWidthPointKerned("!", 12); + return fW == fE; + } + protected static iTextSharp.text.Paragraph RtfToParagraph(string rtf) + { + IRtfDocument rtfDoc = RtfInterpreterTool.BuildDoc(rtf); + Rtf2iTextSharp rtf2IText = new Rtf2iTextSharp(rtfDoc); + iTextSharp.text.Paragraph para = rtf2IText.Convert(); + para.SetLeading(_SixLinesPerInch, 0); + return para; + } + } + public partial class vlnParagraphs : List + { + public float Add( PdfContentByte cb, ItemInfoList itemInfoList,float xoff,float yoff, float yoffRight, int rnoLevel, int maxRNO, FormatInfo formatInfo) + { + int? bxIndex = null; + foreach (ItemInfo childItemInfo in itemInfoList) + { + int? bxIndx = childItemInfo.FormatStepData.StepLayoutData.STBoxindex; + if (bxIndex != bxIndx) + { + if(bxIndex == null) // First boxed step + yoff += 2 * vlnPrintObject._SixLinesPerInch; + else // Change Box Style + yoff += 2 * vlnPrintObject._SixLinesPerInch; + bxIndex = bxIndx; + } + if (childItemInfo is SectionInfo) formatInfo = (childItemInfo as SectionInfo).LocalFormat ?? formatInfo; + if (rnoLevel < maxRNO && childItemInfo.RNOs != null) yoff = Math.Max(yoff, yoffRight); + vlnParagraph para = new vlnParagraph(Parent, cb, childItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo); + Add(para); + yoff = para.YBottomMost; + } + if (bxIndex != null) // End Box Style + yoff += 2 * vlnPrintObject._SixLinesPerInch; + return yoff; + } + }; + public partial class vlnParagraph : vlnPrintObject + { + private int COL_WID_ADJ = 6; // adjusts for incorrect use of WidSTable when breaking a line (it breaks 6 chars too short) + public vlnParagraph(vlnParagraph parent, PdfContentByte cb, ItemInfo itemInfo, float xoff,float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo) + { + MyParent = parent; + MyContentByte = cb; + MyItemInfo = itemInfo; + XOffset = xoff; + YTopMost = YOffset = yoff; + vlnTab mytab = null; + vlnChangeBar myCB = null; + if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && itemInfo.MyTab.Text != "") + { + //if (itemInfo.IsHigh) + // Console.WriteLine("{0:00},'{1}'", itemInfo.Ordinal, itemInfo.MyTab.Text); + //mytab = new vlnTab(cb, itemInfo.MyTab.Text, itemInfo.MyTab.CleanText.TrimStart(" ".ToCharArray()), XOffset, yoff, itemInfo.MyTab.MyFont); + mytab = new vlnTab(cb, itemInfo.MyTab.Text, itemInfo.MyTab.CleanText, XOffset, yoff, itemInfo.MyTab.MyFont); + PartsLeft.Add(mytab); + } + AdjustWidth(itemInfo, maxRNO, formatInfo, mytab); + AdjustXOffsetForTab(itemInfo, maxRNO, formatInfo, mytab); + if (itemInfo.HasChangeBar()) + { + myCB = DoChangeBar(itemInfo, xoff, yoff, maxRNO, formatInfo, myCB); + PartsRight.Add(myCB); + } + if (itemInfo.Cautions != null) + { + //yoff += 2 * _SixLinesPerInch; + yoff = ChildrenAbove.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); + //yoff += 2 * _SixLinesPerInch; + } + if (itemInfo.Notes != null) + { + //yoff += 2 * _SixLinesPerInch; + yoff = ChildrenAbove.Add(cb, itemInfo.Notes, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); + //yoff += 2 * _SixLinesPerInch; + } + YTop = yoff; + if (itemInfo.MyHeader != null && itemInfo.MyHeader.Text != null && itemInfo.MyHeader.Text != "") + yoff += SetHeader(this, cb, itemInfo, formatInfo); + YOffset = yoff; + AddMacros(itemInfo, mytab); + if (mytab != null) mytab.YOffset = yoff; + if (myCB != null) myCB.YOffset = yoff; + Rtf = GetRtf(itemInfo); + //if (MyItemInfo.ItemID == 117) + //{ + // Rtf = Rtf.Replace("3 psig", @"3\'A0psig"); + // //Console.WriteLine("'{0}'", Rtf); + //} + yoff += Height; + yoff += AdjustForBlankLines(); + float yOffRight = yoff; + float RnoOffset = ToPrint(formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColRTable, maxRNO); + if (rnoLevel < maxRNO && itemInfo.RNOs != null) yOffRight= ChildrenRight.Add(cb, itemInfo.RNOs, XOffset + RnoOffset, YTop, YTop, rnoLevel + 1, maxRNO, formatInfo); + // Need code to determine if the table will overlap the Right Column if it does then + // use YOffRight rather than yoff + if (itemInfo.Tables != null) yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo); + // Need code to determine if the step has an RNO and if so use YOffRight rather than yoff + if (itemInfo.Steps != null) yoff = ChildrenBelow.Add(cb, itemInfo.Steps, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo); + yoff = Math.Max(yoff, yOffRight); + if (itemInfo.Sections != null) yoff = ChildrenBelow.Add(cb, itemInfo.Sections, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); + if (itemInfo.Procedures != null) yoff = ChildrenBelow.Add(cb, itemInfo.Procedures, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); + if (rnoLevel >= maxRNO && itemInfo.RNOs != null) yoff = ChildrenBelow.Add(cb, itemInfo.RNOs, XOffset, yoff, yoff, rnoLevel + 1, maxRNO, formatInfo); + // TODO - use RNOSepAfterAER flag too: + //string tmpRnoSepStr = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.RNOSepString; + //if (itemInfo.IsRNOPart && rnoLevel == 1 && tmpRnoSepStr != null) + //{ + // float xsep = MyHighLevelParagraph.XOffset + RnoOffset; + // vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff, formatInfo.PlantFormat.FormatData.Font); + // PartsBelow.Add(myRnoSep); + // yoff += myRnoSep.Height + (2*_SixLinesPerInch); // RNOSeparator has two lines before it, so account for it + //} + string tmpRnoSepStr = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.RNOSepString; + if (rnoLevel < maxRNO && itemInfo.RNOs != null && tmpRnoSepStr != null) + { + float xsep = MyHighLevelParagraph.XOffset + RnoOffset; + vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff, formatInfo.PlantFormat.FormatData.Font); + PartsBelow.Add(myRnoSep); + //if(!MyItemInfo.IsStepSection) + yoff += myRnoSep.Height + _SixLinesPerInch; + } + YBottomMost = yoff; + } + private float AdjustForBlankLines() + { + int everyNLines = MyItemInfo.FormatStepData == null ? 1 : MyItemInfo.FormatStepData.StepLayoutData.EveryNLines ?? 1; + if(MyItemInfo.Ordinal % everyNLines == 0 || MyItemInfo.NextItem == null)return _SixLinesPerInch; + return 0; + } + private void AddMacros(ItemInfo itemInfo, vlnTab mytab) + { + float y = YOffset; + float x = mytab == null ? XOffset : mytab.XOffset + mytab.TabOffset; + List myMacros = itemInfo.MyMacros; + if (myMacros != null) + { + foreach (Macro myMacro in myMacros) + { + PartsLeft.Add(new vlnMacro(x, y, myMacro.MacroDef)); + } + } + } + // HLP Change bar flags in format file: + // + private vlnChangeBar DoChangeBar(ItemInfo itemInfo, float xoff, float yoff, int maxRNO, FormatInfo formatInfo, vlnChangeBar myCB) + { + // find column for the change bar based on format flags - this is code from 16-bit + // if AbsoluteFixedChangeColumn + // if FixedAERChangeColumn + // if col>ColsS+ColR+COL_WID+ADJ + // FixedChangeColumn + // else + // AERLeftChangeBarLocation() + // else + // FixedChangeColumn + // else + // ChangeBarLocation() + int absFixedAERChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedAERChangeColumn ?? 0; + int fixedChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedChangeColumn ?? 0; + int cols = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS ?? 0; + int colr = ToPrint(formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColRTable, maxRNO); + float col = (formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.AbsoluteFixedChangeColumn) ? + (absFixedAERChgCol>0) ? + (xoff > (cols + colr + COL_WID_ADJ)) ? + fixedChgCol : AERLeftChangeBarLocation(formatInfo) : + fixedChgCol : ChangeBarLocation(xoff, this, formatInfo, maxRNO); + + ProcedureConfig.PrintChangeBar pcb = itemInfo.PrintChangeBar; + ProcedureConfig.PrintChangeBarLoc pcbl = itemInfo.PrintChangeBarLoc; + ProcedureConfig.PrintChangeBarText pcbt = itemInfo.PrintChangeBarText; + string pcbum1 = itemInfo.PrintChangeBarUsrMsg1; + string pcbum2 = itemInfo.PrintChangeBarUsrMsg2; + //myCB = new vlnChangeBar(this, XOffset + Width + 5, yoff); // xoff varies depending on type of change bar + myCB = new vlnChangeBar(this, (float) itemInfo.MyDocStyle.Layout.LeftMargin+(col*_CharsToTwips), yoff); + return myCB; + } + + private int ChangeBarLocation(float c, vlnParagraph paragraph, FormatInfo formatInfo, int maxRNO) + { + int fixChgColumn = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedChangeColumn ?? 0; + int cols = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS ?? 0; + int colr = ToPrint(formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColRTable, maxRNO); + if (fixChgColumn < -10 || fixChgColumn >= 0) + return ((fixChgColumn > 0)? fixChgColumn : + (fixChgColumn == 0) ? (int)c + 1 : + (c > cols + colr + COL_WID_ADJ) ? - fixChgColumn : + AERLeftChangeBarLocation(formatInfo)); + else + return (fixChgColumn + (((c < cols + Width + colr) || TableTest() + || MyItemInfo.IsCaution || MyItemInfo.IsNote) ? 0 : cols+colr)); // || (GetColumnMode() == 0)) ? 0 : cols + colr)); + /* Change bars to left of text -- ColS+WidS+ColR is the end of RNO col*/ + } + /* + ** Centered tables whose width exceeds the end of the RNO column should + ** still have their change bars printed on the left. This procedure checks + ** to make sure the step is a table and that it is not an RNO. + */ + private bool TableTest() + { + return false; + //return ((s->Type == TABLE || s->Type == BORDERLESSTABLE) && + //!(strchr((char *)&s->dbseq[2],RNO_MARKER))); + } + private float GetBottomYoff(float bottomY) + { + foreach (vlnParagraph child in ChildrenBelow) + { + if (child.YOffset > bottomY) bottomY = child.YOffset; + bottomY = child.GetBottomYoff(bottomY); + } + return bottomY; + } + private int AERLeftChangeBarLocation(FormatInfo formatInfo) + { + // use -5 default unless it is format specified + int fixedAERChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedAERChangeColumn ?? 0; + return (fixedAERChgCol!=0) ? + (fixedAERChgCol > 100) ? + (fixedAERChgCol % 100) : -fixedAERChgCol : -5; + } + private StringBuilder _RtfSB = null; + + // return rtf and use for tab and other text + public string GetRtf(ItemInfo itemInfo) + { + _RtfSB = new StringBuilder(); + DisplayText vlntxt = new DisplayText(itemInfo, E_EditPrintMode.Print, E_ViewMode.View, true, E_FieldToEdit.StepText, false); + _RtfSB.Append(AddFontTable(vlntxt.TextFont.WindowsFont)); + _RtfSB.Append(vlntxt.StartText); + _RtfSB.Append("}"); + return _RtfSB.ToString(); + + //if (formatInfo.PlantFormat.FormatData.StepDataList[itemInfo.FormatStepType].Boxed) myParagraph.Parts.Add(new vlnBox(myParagraph)); + //Console.WriteLine("{0} {1} - {2}, {3}", itemInfo.MyTab.CleanText, itemInfo.MyContent.Text, xoff, yoff); + } + private float _XOffsetBox = -24; + public float XOffsetBox + { + get { return _XOffsetBox; } + set { _XOffsetBox = value; } + } + private float SetHeader(vlnParagraph para, PdfContentByte cb, ItemInfo itemInfo, FormatInfo formatInfo) + { + float xoff = (float) itemInfo.MyDocStyle.Layout.LeftMargin; + float hdrWidth = (itemInfo.MyHeader.CleanText == null) ? 0 : itemInfo.MyHeader.CleanText.Length * _CharsToTwips; // convert to twips + int typ = ((int)itemInfo.MyContent.Type) % 10000; + int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex; + if (itemInfo.MyHeader.Justify == System.Drawing.ContentAlignment.MiddleCenter) + { + if (bxIndx != null) + { + Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx]; + if (bx.TabPos > 0) + xoff += (float)bx.TabPos; // xoff starts as left margin + else + { + xoff += (float)((bx.TxtStart + XOffsetBox + (bx.TxtWidth / 2)) - (hdrWidth / 2)); // xoff starts as left margin + } + } + else if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.Separator.Location > 0) + { + // if there is a separator location, use it - 16bit code used the separator location as a divisor: + xoff = XOffset + AdjustToCharPosition((float)((para.Width - hdrWidth) / formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.Separator.Location)); + } + else + xoff = XOffset + (para.Width / 2) + (hdrWidth / 2); // XOffset has left margin included + } + else + xoff = XOffset; // XOffset has left margin included + vlnHeader myHeader = new vlnHeader(this, cb, itemInfo.MyHeader.Text, itemInfo.MyHeader.CleanText.TrimStart(" ".ToCharArray()), xoff, YOffset, itemInfo.MyHeader.MyFont, itemInfo.MyHeader.Justify); + PartsAbove.Add(myHeader); + return myHeader.Height + _SixLinesPerInch; + } + } + public partial class vlnMacro : vlnPrintObject + { + public vlnMacro(float xoffset, float yoffset, string macroDef) + { + YOffset = yoffset; + XOffset = xoffset; + MacroDef = macroDef; + } + } + public partial class vlnTab : vlnPrintObject + { + public vlnTab(PdfContentByte cb, string origTab, string cleanTab, float xoffset, float yoffset, VE_Font vFont) + { + MyContentByte = cb; + YOffset = yoffset; + TabText = cleanTab; + Rtf = GetRtf(origTab, vFont); + XOffset = xoffset - TabWidth; + MyFont = vFont; + } + } + public partial class vlnHeader : vlnPrintObject + { + public vlnHeader(vlnParagraph myParent, PdfContentByte cb, string origStr, string cleanStr, float xoffset, float yoffset, VE_Font vFont, System.Drawing.ContentAlignment ca) + { + MyParent = myParent; + MyContentByte = cb; + YOffset = yoffset; + Width = MyParent.Width; + HeaderText = cleanStr; + Rtf = GetRtf(origStr, vFont); + XOffset = xoffset; + MyFont = vFont; + ContentAlignment = ca; + } + } + public partial class vlnRNOSeparator : vlnPrintObject + { + /* if flag set and separator defined then output separator */ + /*if separator is a control-A use RNOSepLine*/ + public vlnRNOSeparator(vlnParagraph parent, PdfContentByte cb, string sepStr, float xoffset, float yoffset, VE_Font vFont) + { + YOffset = yoffset; + XOffset = xoffset; + _MyParent = parent; + if (sepStr != null) + Rtf = GetRtf(sepStr, vFont); + else + Rtf = "--------------------------"; //TODO - What should this be: is this Ctrl-A? + MyFont = vFont; + Width = sepStr.Length * _CharsToTwips + _WidthAdjust; + } + } +} diff --git a/PROMS/Volian.Print.Library/Rtf2Pdf.cs b/PROMS/Volian.Print.Library/Rtf2Pdf.cs new file mode 100644 index 00000000..d598420a --- /dev/null +++ b/PROMS/Volian.Print.Library/Rtf2Pdf.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Text; +using iTextSharp.text; +using iTextSharp.text.pdf; +using iTextSharp.text.factories; +using Itenso.Rtf; +using Itenso.Rtf.Parser; +using Itenso.Rtf.Interpreter; +//using Itenso.Rtf.Model; +using Itenso.Rtf.Support; +using System.IO; + + +namespace Volian.Print.Library +{ + public class Rtf2Pdf + { + private string _Rtf; + + public string Rtf + { + get { return _Rtf; } + set { _Rtf = value; } + } + private string _FileName; + + public string FileName + { + get { return _FileName; } + set { _FileName = value; } + } + public Rtf2Pdf(string rtf, string fileName) + { + _Rtf = rtf; + _FileName = fileName; + } + public void Process() + { + Document document = new Document(PageSize.LETTER); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(FileName, FileMode.Create)); + document.Open(); + // Open RTF Document + IRtfDocument rtfDoc = RtfInterpreterTool.BuildDoc(Rtf); + Rtf2iTextSharp rtf2IText = new Rtf2iTextSharp(rtfDoc); + Paragraph para = rtf2IText.Convert(); + para.SetLeading(12F, 0); + PdfContentByte cb = writer.DirectContent; + SampleParagraphs(para, cb, 792-36, 252, 36); + para.Add(new Chunk(" (continued)",para.Font)); + SampleParagraphs(para, cb, 792 - 36, 252, 324); + // Close the document + document.Close(); + } + + private static void SampleParagraphs(Paragraph para, PdfContentByte cb, float yTop, float width, float x) + { + while (yTop > 0) + { + float newYTop = TextAt(cb, para, x, yTop - 12F, width, 100); + //Console.WriteLine("{0},{1},{2}", yTop, width, newYTop); + width -= 16; + yTop = newYTop; + } + } + public static float GetParagraphHeight(PdfContentByte cb, Paragraph iParagraph, float width) + { + ColumnText myColumnText = new ColumnText(cb); + myColumnText.SetSimpleColumn(0, 792F, width, 0); // Bottom margin + myColumnText.AddElement(iParagraph); + //myColumnText.UseAscender = true;// Adjusts to the top of the text box. + int status = myColumnText.Go(true); // Check to see if it will fit on the page. + if (ColumnText.HasMoreText(status)) throw(new Exception("Paragraph longer than a page")); + return 792F - myColumnText.YLine; // This gives the height of the Paragraph + } + private static bool _DrawBox = true; + public static bool DrawBox + { + get { return Rtf2Pdf._DrawBox; } + set { Rtf2Pdf._DrawBox = value; } + } + private static System.Drawing.PointF _Offset = new System.Drawing.PointF(0, 0); + public static System.Drawing.PointF Offset + { + get { return Rtf2Pdf._Offset; } + set { Rtf2Pdf._Offset = value; } + } + public static float TextAt(PdfContentByte cb, Paragraph iParagraph, float x, float y, float width, float height) + { + float left = x + Offset.X; + float top = y + Offset.Y; + float right = left + width; + float bottom = top - height; + ColumnText myColumnText = new ColumnText(cb); + //myColumnText.SetSimpleColumn(left, top, left + width, top - height); + myColumnText.SetSimpleColumn(left, top, left + width, 36); // Bottom margin + //myColumnText.YLine -= 10; + //float yOff = pp.Font.BaseFont.GetAscentPoint("Almg", pp.Font.Size); + //myColumnText.YLine = -yOff; + myColumnText.AddElement(iParagraph); + float pos = myColumnText.YLine; + //myColumnText.UseAscender = true;// Adjusts to the top of the text box. + // go processing it and if it fits, nothing to be processed is in mycolumntext. + int status = myColumnText.Go(true); // Check to see if it will fit on the page. + if (ColumnText.HasMoreText(status)) + return 0;// Won't fit return 0; + myColumnText.YLine = pos; // location on page + myColumnText.AddElement(iParagraph); // add in paragraph + myColumnText.Go(false); + //float textHeight = pp.Leading * myColumnText.LinesWritten; + //Console.WriteLine("Calculated Bottom {0}, YLine {1}", top - textHeight, myColumnText.YLine); + //BoxText(cb, System.Drawing.Color.BurlyWood, left, top, left + width, top - height); + //BoxText(canvas, System.Drawing.Color.CadetBlue, left, top, left + width, top - textHeight); + if(DrawBox)BoxText(cb, System.Drawing.Color.CadetBlue, left, top, left + width, myColumnText.YLine); + //Console.WriteLine("Lines = {0}", myColumnText.LinesWritten); + return myColumnText.YLine; + } + private static void BoxText(PdfContentByte cb, System.Drawing.Color sysColor, float left, float top, float right, float bottom) + { + float yAdj = 3; + cb.SaveState(); + cb.SetColorStroke(new Color(sysColor)); + cb.SetLineWidth(.1F); + cb.MoveTo(left, top - yAdj); + cb.LineTo(right, top - yAdj); + cb.LineTo(right, bottom - yAdj); + cb.LineTo(left, bottom - yAdj); + cb.LineTo(left, top - yAdj); + cb.Stroke(); + cb.RestoreState(); + } + + + } +} diff --git a/PROMS/Volian.Print.Library/Rtf2iTextSharp.cs b/PROMS/Volian.Print.Library/Rtf2iTextSharp.cs new file mode 100644 index 00000000..2d1f1395 --- /dev/null +++ b/PROMS/Volian.Print.Library/Rtf2iTextSharp.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.Text; +using iTextSharp.text; +using iTextSharp.text.pdf; +using iTextSharp.text.factories; +using Itenso.Rtf; +using Itenso.Rtf.Parser; +using Itenso.Rtf.Interpreter; +//using Itenso.Rtf.Model; +using Itenso.Rtf.Support; +using Microsoft.Win32; + +namespace Volian.Print.Library +{ + public partial class PrintOverride + { + private static System.Drawing.Color _TextColor = System.Drawing.Color.Empty; + public static System.Drawing.Color TextColor + { + get { return _TextColor; } + set { _TextColor = value; } + } + public static System.Drawing.Color OverrideTextColor(System.Drawing.Color color) + { + if (_TextColor == System.Drawing.Color.Empty) + return color; + return _TextColor; + } + private static System.Drawing.Color _SvgColor = System.Drawing.Color.Empty; + public static System.Drawing.Color SvgColor + { + get { return _SvgColor; } + set { _SvgColor = value; Volian.Svg.Library.Svg.OverrideColor = value; } + } + public static System.Drawing.Color OverrideSvgColor(System.Drawing.Color color) + { + if (_SvgColor == System.Drawing.Color.Empty) + return color; + return _SvgColor; + } + } + public class Rtf2iTextSharp : RtfVisualVisitorBase + { + private IRtfDocument _RtfDoc; + private Paragraph _MyParagraph = new Paragraph(); + private iTextSharp.text.Font _MyFont; + // public Rtf2iTextSharp(IRtfDocument rtfDoc, Document doc, PdfWriter writer) + public Rtf2iTextSharp(IRtfDocument rtfDoc) + { + if (rtfDoc == null) + throw new ArgumentNullException("rtfDoc"); + + _RtfDoc = rtfDoc; + } + public Paragraph Convert() + { + _MyParagraph.Clear(); + _MyFont = null; + foreach (IRtfVisual visual in _RtfDoc.VisualContent) + visual.Visit(this); + //_MyParagraph.SetLeading(0, 1); + return _MyParagraph; + } + // ---------------------------------------------------------------------- + protected override void DoVisitBreak(IRtfVisualBreak visualBreak) + { + switch (visualBreak.BreakKind) + { + case RtfVisualBreakKind.Line: + _MyParagraph.Add(Chunk.NEWLINE); + break; + case RtfVisualBreakKind.Page: + break; + case RtfVisualBreakKind.Paragraph: + _MyParagraph.Add(Chunk.NEWLINE); + break; + case RtfVisualBreakKind.Section: + break; + default: + break; + } + //_MyParagraph.Add(string.Format("<{0}>", visualBreak.BreakKind.ToString())); + } + protected override void DoVisitSpecial(IRtfVisualSpecialChar visualSpecialChar) + { + //_MyParagraph.Add(string.Format("", visualSpecialChar.CharKind.ToString())); + switch (visualSpecialChar.CharKind) + { + case RtfVisualSpecialCharKind.Bullet: + break; + case RtfVisualSpecialCharKind.EmDash: + break; + case RtfVisualSpecialCharKind.EmSpace: + break; + case RtfVisualSpecialCharKind.EnDash: + break; + case RtfVisualSpecialCharKind.EnSpace: + break; + case RtfVisualSpecialCharKind.LeftDoubleQuote: + break; + case RtfVisualSpecialCharKind.LeftSingleQuote: + break; + case RtfVisualSpecialCharKind.NonBreakingHyphen: + break; + case RtfVisualSpecialCharKind.NonBreakingSpace: + _MyParagraph.Add(new Chunk("\u00A0")); + break; + case RtfVisualSpecialCharKind.OptionalHyphen: + break; + case RtfVisualSpecialCharKind.ParagraphNumberBegin: + break; + case RtfVisualSpecialCharKind.ParagraphNumberEnd: + break; + case RtfVisualSpecialCharKind.QmSpace: + break; + case RtfVisualSpecialCharKind.RightDoubleQuote: + break; + case RtfVisualSpecialCharKind.RightSingleQuote: + break; + case RtfVisualSpecialCharKind.Tabulator: + break; + default: + break; + } + } + //public static iTextSharp.text.Font GetFont(string fontName) + //{ + // RegisterFont(fontName); + // //if(fontName.Contains("Sym")) + // return iTextSharp.text.FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); + // //else + // // return iTextSharp.text.FontFactory.GetFont(fontName,BaseFont.CP1252 ,BaseFont.EMBEDDED); + //} + + //public static iTextSharp.text.Font GetFont(string fontName) + //{ + // RegisterFont(fontName); + // return iTextSharp.text.FontFactory.GetFont(fontName); + //} + public static void RegisterFont(string fontName) + { + if (!iTextSharp.text.FontFactory.IsRegistered(fontName)) + { + foreach (string name in FontKey.GetValueNames()) + { + if (name.StartsWith(fontName)) + { + string fontFile = (string)FontKey.GetValue(name); + iTextSharp.text.FontFactory.Register(fontFile.Contains("\\") ? fontFile : FontFolder + "\\" + fontFile); + } + } + } + } + private static RegistryKey _FontKey = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows NT").OpenSubKey("CurrentVersion").OpenSubKey("Fonts"); + public static RegistryKey FontKey + { get { return _FontKey; } } + private static string _FontFolder = (String)Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Explorer").OpenSubKey("Shell Folders").GetValue("Fonts"); + public static string FontFolder + { get { return _FontFolder; } } + private static iTextSharp.text.Font GetFont(string fontName, int size, int style) + { + RegisterFont(fontName); + return iTextSharp.text.FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size / 2, style); + } + public static iTextSharp.text.Font GetFont(System.Drawing.Font font) // fontName, int size, int style) + { + Rtf2iTextSharp.RegisterFont(font.Name); + int style = (font.Bold ? iTextSharp.text.Font.BOLD : 0) + (font.Italic ? iTextSharp.text.Font.ITALIC : 0); + return iTextSharp.text.FontFactory.GetFont(font.Name, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, font.Size, style); + } + protected override void DoVisitText(IRtfVisualText visualText) + { + //Console.WriteLine("'{0}' {1} {2} {3} {4}", ShowSpecialCharacters(visualText.Text), visualText.Kind, visualText.Format.Font.Name, visualText.Format.FontSize, visualText.Format.SuperScript); + if (visualText.Format.IsHidden) return; + iTextSharp.text.Font font = GetFont(visualText.Format.Font.Name, visualText.Format.FontSize, + (visualText.Format.IsBold ? iTextSharp.text.Font.BOLD : 0) + + (visualText.Format.IsItalic ? iTextSharp.text.Font.ITALIC : 0)); + //Console.WriteLine("after font = {0} {1} {2}", font.Familyname, font.Size, font.Style); + //iTextSharp.text.Font font = FontFactory.GetFont(visualText.Format.Font.Name, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, + // visualText.Format.FontSize / 2F);// TODO: Don't know why this is 2.4 rather than 2. + //font.SetStyle((visualText.Format.IsBold ? iTextSharp.text.Font.BOLD : 0) + (visualText.Format.IsItalic ? iTextSharp.text.Font.ITALIC : 0)); + font.Color = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(visualText.Format.ForegroundColor.AsDrawingColor)); + Chunk chk = new Chunk(visualText.Text, font); + if(visualText.Format.BackgroundColor.AsDrawingColor.ToArgb() != System.Drawing.Color.White.ToArgb()) + chk.SetBackground(new iTextSharp.text.Color(visualText.Format.BackgroundColor.AsDrawingColor)); + if (visualText.Format.IsStrikeThrough) + chk.SetUnderline(font.Color, 0, 0.05F, 0, .3F, PdfContentByte.LINE_CAP_ROUND); // Relative Based upon font size + if (visualText.Format.IsUnderline) + chk.SetUnderline(font.Color, 0, 0.05F, 0, -.131F, PdfContentByte.LINE_CAP_ROUND); // Relative Based upon font size + if (visualText.Format.SuperScript > 0) + chk.SetTextRise(.45F * chk.Font.Size); + else if (visualText.Format.SuperScript < 0) + chk.SetTextRise(-.25F * chk.Font.Size); + //else + // chk.SetTextRise(0); + //Console.WriteLine("\"RTF FontSize\",{0},{1}", visualText.Format.FontSize / 2,chk.Font.Size); + + if (_MyFont == null) + { + _MyFont = font; + _MyParagraph.Font = _MyFont; + } + _MyParagraph.Add(chk); + + } + + private string ShowSpecialCharacters(string p) + { + StringBuilder sb = new StringBuilder(); + foreach (char c in p) + { + int i = (int)c; + if (i < 20 || i > 127) + sb.Append(string.Format("<{0:x}>", i)); + else + sb.Append(c); + } + return sb.ToString(); + }// DoVisitText + + + // ---------------------------------------------------------------------- + protected override void DoVisitImage(IRtfVisualImage visualImage) + { + _MyParagraph.Add(new Chunk("")); + //WriteStartElement("rtfVisualImage"); + + //WriteElementString("format", visualImage.Format.ToString()); + //WriteElementString("width", visualImage.Width.ToString()); + //WriteElementString("height", visualImage.Height.ToString()); + //WriteElementString("desiredWidth", visualImage.DesiredWidth.ToString()); + //WriteElementString("desiredHeight", visualImage.DesiredHeight.ToString()); + //WriteElementString("scaleWidthPercent", visualImage.ScaleWidthPercent.ToString()); + //WriteElementString("scaleHeightPercent", visualImage.ScaleHeightPercent.ToString()); + //WriteElementString("alignment", visualImage.Alignment.ToString()); + + //WriteElementString("image", visualImage.ImageDataHex.ToString()); + + //WriteEndElement(); + } // DoVisitImage + + } +} diff --git a/PROMS/Volian.Print.Library/ToPdf.cs b/PROMS/Volian.Print.Library/ToPdf.cs new file mode 100644 index 00000000..844497da --- /dev/null +++ b/PROMS/Volian.Print.Library/ToPdf.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Text; +using iTextSharp.text; +using iTextSharp.text.pdf; +using iTextSharp.text.factories; +using Itenso.Rtf; +using Itenso.Rtf.Parser; +using Itenso.Rtf.Interpreter; +using Itenso.Rtf.Support; + +namespace Volian.Print.Library +{ + public abstract partial class vlnPrintObject + { + public abstract float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin); + } + public partial class vlnPrintObjects : List + { + public float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + foreach (vlnPrintObject part in this) + { + yPageStart = part.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + } + return yPageStart; + } + } + public partial class vlnParagraphs : List + { + public float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + foreach (vlnParagraph child in this) + { + yPageStart = child.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + } + return yPageStart; + } + } + public partial class vlnParagraph : vlnPrintObject + { + public float ParagraphToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + //Console.WriteLine("'{0}',{1},{2},{3},{4},{5},{6},{7},{8}", MyItemInfo.Path.Substring(_Prefix.Length).Trim(), + // cb.PdfWriter.CurrentPageNumber, yStart, YTop, yStart + YTop, yStart + YTop - _LastY, YTopMost, YSize, yPageStart); + //_LastY = yStart + YTop; + // 72 points per inchs. 504 is 7 inches wide. 3 1/2 inches wide: 252, 100); + if (_PartsAbove != null && _PartsAbove.Count > 0) yPageStart = PartsAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + float yLocation = yPageStart - YOffset; + float retval = yLocation; + if (MyItemInfo.IsStepSection) + { + Console.WriteLine("Step Section - {0}", MyItemInfo.Path); + } + else + { + retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100); + if (retval == 0) + { + cb.PdfDocument.NewPage(); + yPageStart = yTopMargin + YTop; + yLocation = yPageStart - YOffset; + Console.WriteLine("Other Paginate"); + retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100); + } + } + //Height = yLocation - retval; + if (_PartsLeft != null && _PartsLeft.Count > 0) yPageStart = PartsLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + if (_PartsRight != null && _PartsRight.Count > 0) yPageStart = PartsRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + if (_PartsBelow != null && _PartsBelow.Count > 0) yPageStart = PartsBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + if (_PartsContainer != null && _PartsContainer.Count > 0) yPageStart = PartsContainer.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + return yPageStart; + } + + + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + float yLocation = yPageStart - YTopMost; + int paginate = Paginate(yLocation, yTopMargin - yBottomMargin); + switch (paginate) + { + case 1: // Break on High Level Step + cb.PdfDocument.NewPage(); + yPageStart = yTopMargin + YTopMost; + break; + case 2: // Break within a Step + cb.PdfDocument.NewPage(); + yPageStart = yTopMargin + YTopMost - 2 * _SixLinesPerInch; + break; + } + yPageStart = ChildrenAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + yPageStart = ChildrenLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + yPageStart = ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + yPageStart = ChildrenRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + yPageStart = ChildrenBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin); + return yPageStart; + } + + private int Paginate(float yLocation, float yPageSize) + { + if (YSize <= yLocation) return 0; // Don't Paginate if there is enough room + if (MyItemInfo.IsRNOPart && MyParent.XOffset < XOffset) return 0; // Don't paginate on an RNO to the right + if (MyItemInfo.IsHigh && YSize < yPageSize) return 1; // Paginate on High Level Steps + if (yLocation > yPageSize / 2) return 0; + return 2; + } + } + public partial class vlnHeader : vlnPrintObject + { + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + float yLocation = yPageStart - YOffset; + Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, HeaderWidth, 100); + return yPageStart; + } + } + + public partial class vlnTab : vlnPrintObject + { + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + float yLocation = yPageStart - YOffset; + Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, TabWidth, 100); + return yPageStart; + } + } + public partial class vlnBox : vlnPrintObject + { + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + return yPageStart; + } + } + public partial class vlnChangeBar : vlnPrintObject + { + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + float yLocation = yPageStart - YOffset; + float yAdj = 3; + cb.SaveState(); + cb.SetColorStroke(Color.GREEN); + cb.SetLineWidth(1); + cb.MoveTo(XOffset, yLocation-yAdj); // combination yStart and YOffset + cb.LineTo(XOffset, yLocation - MyParent.Height-yAdj); + cb.Stroke(); + cb.RestoreState(); + return yPageStart; + } + } + public partial class vlnRNOSeparator : vlnPrintObject + { + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + float yLocation = yPageStart - YOffset; + Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100); + return yPageStart; + } + } + public partial class vlnMacro : vlnPrintObject + { + public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) + { + float yLocation = yPageStart - YOffset; + MyContentByte = cb; + System.Drawing.Color push = PrintOverride.SvgColor; + PrintOverride.SvgColor = PrintOverride.TextColor == System.Drawing.Color.Empty ? System.Drawing.Color.Black : PrintOverride.TextColor ; + if (MyPageHelper != null && MyPageHelper.MySvg != null) + MyPageHelper.MySvg.DrawMacro(MacroDef, XOffset, yLocation, cb); + PrintOverride.SvgColor = push; + return yPageStart; + } + } +} diff --git a/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs b/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs new file mode 100644 index 00000000..47ec92a7 --- /dev/null +++ b/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs @@ -0,0 +1,270 @@ +using System; +using System.Collections.Generic; +using System.Text; +using iTextSharp.text; +using iTextSharp.text.pdf; +using iTextSharp.text.factories; +using Volian.Svg.Library; +using System.Text.RegularExpressions; +using System.Xml; + +namespace Volian.Print.Library +{ + public class VlnSvgPageHelper:SvgPageHelper + { + private VEPROMS.CSLA.Library.SectionInfo _MySection; + public VEPROMS.CSLA.Library.SectionInfo MySection + { + get { return _MySection; } + set + { + _MySection = value; + MySvg = BuildSvg(_MySection); + } + } + private int _CurrentPageOf = 0; + public int CurrentPageOf + { + get { return _CurrentPageOf; } + set { _CurrentPageOf = value; } + } + private string _Rev = string.Empty; + public string Rev + { + get { return _Rev; } + set { _Rev = value; } + } + private string _RevDate = string.Empty; + public string RevDate + { + get { return _RevDate; } + set { _RevDate = value; } + } + public VlnSvgPageHelper(VEPROMS.CSLA.Library.SectionInfo mySection) + { + MySection = mySection; + } + private Volian.Svg.Library.Svg BuildSvg(VEPROMS.CSLA.Library.SectionInfo mySection) + { + VEPROMS.CSLA.Library.FormatInfo activeFormat = mySection.ActiveFormat; + VEPROMS.CSLA.Library.DocStyle docStyle = mySection.MyDocStyle; + Volian.Svg.Library.Svg mySvg = null; + mySvg = SvgSerializer.StringDeserialize(BuildMyText(activeFormat)); + mySvg.ViewBox.Height = 1100; + mySvg.ViewBox.Width = 850; + mySvg.Height = new SvgMeasurement(11, E_MeasurementUnits.IN); + mySvg.Width = new SvgMeasurement(8.5F, E_MeasurementUnits.IN); + mySvg.LeftMargin = (float)docStyle.Layout.LeftMargin; + mySvg.TopMargin = 9.6F; + VEPROMS.CSLA.Library.PageStyle pageStyle = docStyle.pagestyle; + AddPageListItems(mySvg, pageStyle, mySection); + //DocStyle docStyle = GetDocStyle(activeFormat, (section.MyContent.Type ?? 10000)); + mySvg.ProcessText += new SvgProcessTextEvent(mySvg_ProcessText); + return mySvg; + } + private static Regex regexFindToken = new Regex("{[^{}]*}"); + private string mySvg_ProcessText(object sender, SvgProcessTextArgs args) + { + if (!args.MyText.Contains("{")) + return args.MyText; + return regexFindToken.Replace(args.MyText, new MatchEvaluator(ReplacePageListToken)); + } + private string BuildMyText(VEPROMS.CSLA.Library.FormatInfo activeFormat) + { + string sGenMac = activeFormat.GenMac; + if (!sGenMac.Contains("xmlns")) + sGenMac = sGenMac.Replace(".StringSerialize(mySvg); + XmlDocument xDocPrintout = new XmlDocument(); + xDocPrintout.LoadXml(str); + XmlNode xn = xDocPrintout.DocumentElement.ChildNodes[0]; + xn.AppendChild(xDocPrintout.ImportNode(xDocGenMac.DocumentElement, true)); + return xDocPrintout.OuterXml; + } + private string FirstAndLast(string token) + { + // strip the curly braces and return the first and last character + // For example Header1 becomes H1 and Box2 becomes B2 + return token.Substring(1, 1) + token.Substring(token.Length - 2, 1); + } + private static Regex regexJustTokens = new Regex(@"^{([^{}\?]*}{)*[^{}\?]*}$"); + + private void AddPageListItems(Volian.Svg.Library.Svg mySvg, VEPROMS.CSLA.Library.PageStyle pageStyle, VEPROMS.CSLA.Library.SectionInfo section) + { + SvgGroup svgGroup = new SvgGroup(); + foreach (VEPROMS.CSLA.Library.PageItem pageItem in pageStyle.PageItems) + { + if (regexJustTokens.IsMatch(pageItem.Token)) + { + MatchCollection matches = regexFindToken.Matches(pageItem.Token); + foreach (Match match in matches) + { + string token = match.Value; + switch (match.Value) + { + case "{HEADER1}": + case "{HEADER2}": + case "{HEADER3}": + case "{HEADER4}": + case "{HEADER5}": + case "{BOX1}": + case "{BOX2}": + case "{BOX3}": + case "{BOX4}": + case "{BOX5}": + case "{BOX6}": + case "{BOX7}": + case "{BOX8}": + svgGroup.Add(PageItemToSvgUse(pageItem, FirstAndLast(token))); + break; + case "{DRAFTPAGE}": + case "{REFERENCEPAGE}": + case "{MASTERPAGE}": + case "{SAMPLEPAGE}": + //mySvg.SetValidWaterMark(token, _Watermark); // Need logic to limit watermark to tokens. + break; + case "{PROCTITLE}": + SplitTitle(svgGroup, pageItem, section.MyProcedure.DisplayText, (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength); + break; + case "{EOPNUM}": + svgGroup.Add(PageItemToSvgText(pageItem, section.MyProcedure.DisplayNumber)); + break; + case "{SECTIONLEVELTITLE}": + SplitTitle(svgGroup, pageItem, section.DisplayText, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionTitleLength); + svgGroup.Add(PageItemToSvgText(pageItem, section.DisplayText)); + break; + case "{SECTIONLEVELNUMBER}": + svgGroup.Add(PageItemToSvgText(pageItem, section.DisplayNumber)); + break; + default: + Console.WriteLine("Token not processed {0}", token); + break; + } + } + } + else + { + svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token)); + } + } + mySvg.Add(svgGroup); + } + private void SplitTitle(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len) + { + // TODO: need to calculate len in either points or inches and use the font from the pageItem to determine the number of characters + if (len == null || title.Length < len) + { + svgGroup.Add(PageItemToSvgText(pageItem, title)); + return; + } + // Otherwise determine how many line to split the text into + List titleLines = SplitText(title, (int)len); + // Move up 6 Points per line to find the starting point + float yOffset = -6 * (titleLines.Count - 1); + foreach (string line in titleLines) + { + svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset)); + yOffset += 12; + } + } + private List SplitText(string title, int len) + { + List retval = new List(); + int strlen = title.Length; + int start = 0; + while ((strlen - start) > len) + { + int width = FindWidth(title, start, len); + retval.Add(title.Substring(start, width)); + start += width; + while (title[start] == ' ') start++; + } + if (strlen - start > 0) + retval.Add(title.Substring(start, strlen - start)); + return retval; + } + private int FindWidth(string title, int start, int len) + { + for (int ii = start + len; ii > start; ii--) + { + if (title[ii] == ' ') + { + while (title[ii] == ' ') ii--; + if (ii > start) + return 2 + ii - start; + return len; + } + } + return len; + } + private SvgPart PageItemToSvgUse(VEPROMS.CSLA.Library.PageItem pageItem, string templateName) + { + SvgUse svgUse = new SvgUse(); + svgUse.UseID = templateName; + svgUse.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT); + svgUse.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT); + return svgUse; + } + private static SvgText PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text) + { + SvgText svgText = new SvgText(); + svgText.Text = text; + VEPROMS.CSLA.Library.E_Justify justify = pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft; + if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft) + svgText.Justify = SvgJustify.Left; + else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight) + svgText.Justify = SvgJustify.Right; + else + svgText.Justify = SvgJustify.Center; + svgText.Font = pageItem.Font.WindowsFont; + svgText.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT); + svgText.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT); + if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace + return svgText; + } + private SvgPart PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text, float yOffset) + { + SvgText svgText = new SvgText(); + svgText.Text = text; + VEPROMS.CSLA.Library.E_Justify justify = pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft; + if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft) + svgText.Justify = SvgJustify.Left; + else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight) + svgText.Justify = SvgJustify.Right; + else + svgText.Justify = SvgJustify.Center; + svgText.Font = pageItem.Font.WindowsFont; + svgText.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT); + svgText.Y = new SvgMeasurement((float)(yOffset + pageItem.Row ?? 0), E_MeasurementUnits.PT); + if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace + return svgText; + } + private List _MissingTokens = new List(); + protected override string ReplacePageListToken(Match match) + { + switch (match.Value) + { + case "{PAGE}": // Current Page Number + return CurrentPageNumber.ToString(); + case "{OF}": // Total Page Count for this section + return CurrentPageOf.ToString(); + case "{REVDATE}": // Revision Date + return RevDate; + case "{REV}": // Revision Number + return Rev; + } + if (!_MissingTokens.Contains(match.Value)) + { + _MissingTokens.Add(match.Value); + Console.WriteLine("\t\t\t\tcase \"{0}\": // Unhandled Token\r\n\t\t\t\t\treturn \"\";", match.Value); + } + return ""; + } + } +} diff --git a/PROMS/Volian.Print.Library/Volian.Print.Library.csproj b/PROMS/Volian.Print.Library/Volian.Print.Library.csproj new file mode 100644 index 00000000..101c7ba0 --- /dev/null +++ b/PROMS/Volian.Print.Library/Volian.Print.Library.csproj @@ -0,0 +1,87 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {94830C07-6A3A-450E-9674-C9B4293A7726} + Library + Properties + Volian.Print.Library + Volian.Print.Library + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + F:\CSLA\csla20cs-2.1.4-070223\csla20cs\csla20cs\Csla\bin\Debug\Csla.dll + + + False + ..\..\Proms3rdPartyLibraries\itextsharp.dll + + + False + F:\Log4Net\log4net-1.2.10\bin\net\2.0\debug\log4net.dll + + + + + + + + + + + + + + + + + + {2A49B537-AFDB-4541-8683-468F2A0BE0AE} + Interpreter2005 + + + {6FA3F1A8-4E10-459C-A8DC-C40A90D627B0} + Parser2005 + + + {41B2D786-1C03-4C1A-9247-DA9F0D6B06D5} + VEPROMS.CSLA.Library + + + {8556527C-6615-487F-8AF7-22EBC3EF0268} + Volian.Controls.Library + + + {293911B5-C602-483F-A97F-F962EEFB3CAE} + Volian.Svg.Library + + + + + \ No newline at end of file diff --git a/PROMS/Volian.Print.Library/vlnPrintObject.cs b/PROMS/Volian.Print.Library/vlnPrintObject.cs new file mode 100644 index 00000000..eaebc280 --- /dev/null +++ b/PROMS/Volian.Print.Library/vlnPrintObject.cs @@ -0,0 +1,513 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using iTextSharp.text.pdf; +using VEPROMS.CSLA.Library; + +namespace Volian.Print.Library +{ + public abstract partial class vlnPrintObject + { + protected static float _WidthAdjust = 1; // 1 Point - adjusted to match 16-bit line wrapping. For editting it's 3. + protected static float _WidthAdjustBox = 6; + protected static float _CharsToTwips = 6; // assumes 12 char per inch + internal static float _SixLinesPerInch = 12; // twips + protected static float _SevenLinesPerInch = 72F / 7F; + + protected float _XOffset; + public float XOffset + { + get { return _XOffset; } + set { _XOffset = value; } + } + protected float _YOffset; + public float YOffset + { + get { return _YOffset; } + set { _YOffset = value; } + } + protected vlnParagraph _MyParent; + public vlnParagraph MyParent + { + get { return _MyParent; } + set + { + _MyParent = value; + if (_MyParent != null) + { + + } + } + } + private string _Rtf; // may become iTextSharp paragraph + public string Rtf + { + get { return _Rtf; } + set { _Rtf = value; } + } + iTextSharp.text.Paragraph _IParagraph; + public iTextSharp.text.Paragraph IParagraph + { + get + { + if (_IParagraph == null) + { + _IParagraph = RtfToParagraph(Rtf); + } + return _IParagraph; + } + set { _IParagraph = value; } + } + private float _Width; + public float Width + { + get { return _Width; } + set { _Width = value; } + } + private float _Height; + public float Height + { + get + { + if (_Height == 0) + _Height = Rtf2Pdf.GetParagraphHeight(MyContentByte, IParagraph, Width); + return _Height; + } + } + private PdfContentByte _MyContentByte; + public PdfContentByte MyContentByte + { + get { return _MyContentByte; } + set { _MyContentByte = value; } + } + private VlnSvgPageHelper _MyPageHelper; + public VlnSvgPageHelper MyPageHelper + { + get + { + if(_MyPageHelper == null) + _MyPageHelper = MyContentByte.PdfWriter.PageEvent as VlnSvgPageHelper; + return _MyPageHelper; + } + set { _MyPageHelper = value; } + } + public vlnPrintObject() + { + } + /// + /// No conversion necessary: twips -> twips + /// + /// + /// + public static int ToPrint(int value) + { + return value; + } + /// + /// No conversion necessary: int? twips -> int twips + /// + /// + /// + public static int ToPrint(int? value) + { + return ToPrint((int)value); + } + /// + /// No conversion necessary: string twips -> int twips + /// + /// + /// + public static int ToPrint(string value) + { + return ToPrint(Convert.ToInt32(value)); + } + /// + /// No conversion necessary: value from a list in a string, twips -> int twips + /// + /// + /// + public static int ToPrint(string value, int i) + { + string s = value.Split(",".ToCharArray())[i]; + return ToPrint(s); + } + public float AdjustToCharPosition(float position) + { + int iPosition = (int)position; + iPosition = (iPosition / (int)_CharsToTwips) * (int)_CharsToTwips; + return (float)iPosition; + } + } + public partial class vlnPrintObjects : List + { + }; + public enum PartLocation : int + { + None = 0, // Non-printable + Below = 1, // RNO Separator + Above = 2, // Tab Headers, Separator? + Right = 3, // Change Bars + Left = 4, // Tabs, Checkoffs? (maybe part of tab) + Container = 5 // Box + }; + public partial class vlnParagraphs : List + { + private vlnParagraph _Parent; + public vlnParagraph Parent + { + get { return _Parent; } + set { _Parent = value; } + } + public vlnParagraphs(vlnParagraph parent) + { + _Parent = parent; + } + }; + public partial class vlnParagraph : vlnPrintObject + { + private static string _Prefix = ""; + public static string Prefix + { + get { return vlnParagraph._Prefix; } + set { vlnParagraph._Prefix = value; } + } + protected float _YBottomMost; // Bottom of the paragraph including the children + public float YBottomMost + { + get { return _YBottomMost; } + set { _YBottomMost = value; } + } + protected float _YTopMost; // Top of the paragraph including the children + public float YTopMost + { + get { return _YTopMost; } + set { _YTopMost = value; } + } + protected float _YTop; // Top of the paragraph including parts + public float YTop + { + get { return _YTop; } + set { _YTop = value; } + } + public float YSize // How big this paragraph is with all of its children + { + get { return _YBottomMost - _YTopMost; } + } + private ItemInfo _MyItemInfo; + public ItemInfo MyItemInfo + { + get { return _MyItemInfo; } + set { _MyItemInfo = value; } + } + private vlnParagraph _MyHighLevelParagraph; + + public vlnParagraph MyHighLevelParagraph + { + get + { + if (_MyHighLevelParagraph == null) + { + _MyHighLevelParagraph = GetHighLevelParagraph(); + } + return _MyHighLevelParagraph; + } + } + private vlnParagraph GetHighLevelParagraph() + { + if (MyItemInfo.IsHigh) return this; + return MyParent.GetHighLevelParagraph(); + } + // Tab, Separator, ChangeBar, Box, Circle, Checkoff + private vlnPrintObjects _PartsAbove; + public vlnPrintObjects PartsAbove + { + get + { + if (_PartsAbove == null) _PartsAbove = new vlnPrintObjects(); + return _PartsAbove; + } + } + private vlnPrintObjects _PartsBelow; + public vlnPrintObjects PartsBelow + { + get + { + if (_PartsBelow == null) _PartsBelow = new vlnPrintObjects(); + return _PartsBelow; + } + } + private vlnPrintObjects _PartsRight; + public vlnPrintObjects PartsRight + { + get + { + if (_PartsRight == null) _PartsRight = new vlnPrintObjects(); + return _PartsRight; + } + } + private vlnPrintObjects _PartsLeft; + public vlnPrintObjects PartsLeft + { + get + { + if (_PartsLeft == null) _PartsLeft = new vlnPrintObjects(); + return _PartsLeft; + } + } + private vlnPrintObjects _PartsContainer; + public vlnPrintObjects PartsContainer + { + get + { + if (_PartsContainer == null) _PartsContainer = new vlnPrintObjects(); + return _PartsContainer; + } + } + private vlnParagraphs _ChildrenAbove; + public vlnParagraphs ChildrenAbove + { + get + { + if (_ChildrenAbove == null) _ChildrenAbove = new vlnParagraphs(this); + return _ChildrenAbove; + } + } + private vlnParagraphs _ChildrenBelow; + public vlnParagraphs ChildrenBelow + { + get + { + if (_ChildrenBelow == null) _ChildrenBelow = new vlnParagraphs(this); + return _ChildrenBelow; + } + } + private vlnParagraphs _ChildrenRight; + public vlnParagraphs ChildrenRight + { + get + { + if (_ChildrenRight == null) _ChildrenRight = new vlnParagraphs(this); + return _ChildrenRight; + } + } + private vlnParagraphs _ChildrenLeft; + public vlnParagraphs ChildrenLeft + { + get + { + if (_ChildrenLeft == null) _ChildrenLeft = new vlnParagraphs(this); + return _ChildrenLeft; + } + } + //public vlnParagraph(vlnParagraph myParent, ItemInfo myItemInfo, float xoff, float yoff, float width, string rtf, ChildLocation childRelation) + //{ + // MyParent = myParent; + // MyItemInfo = myItemInfo; + // XOffset = xoff; + // YOffset = yoff; + // Width = width; + // Rtf = rtf; + // switch (childRelation) + // { + // case ChildLocation.Below: + // myParent.ChildrenBelow.Add(this); + // break; + // case ChildLocation.Above: + // myParent.ChildrenAbove.Add(this); + // break; + // case ChildLocation.Right: + // myParent.ChildrenRight.Add(this); + // break; + // } + //} + + public void AdjustXOffsetForTab(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab) + { + float tabWidth = (myTab == null) ? 0 : myTab.TabWidth; + int typ = ((int)itemInfo.MyContent.Type) % 10000; + int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex; + if (bxIndx != null) + { + Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx]; + XOffset += (float)bx.TxtStart + tabWidth + XOffsetBox; + if (myTab!=null)myTab.XOffset = XOffset - tabWidth; + } + else if (itemInfo.IsHigh) + { + XOffset += tabWidth - myTab.TabAlign; + if (myTab != null) myTab.XOffset += tabWidth - myTab.TabAlign; + } + else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh) + { + // don't adjust for rno + } + else if (MyParent != null) + { + XOffset += tabWidth - (myTab == null ? 0 : myTab.TabAlign); + if (myTab != null) myTab.XOffset += tabWidth - myTab.TabAlign; + } + } + public void AdjustWidth(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab) + { + float tabWidth = (myTab == null) ? 0 : myTab.TabWidth; + int typ = ((int)itemInfo.MyContent.Type) % 10000; + int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex; + if (bxIndx != null) + { + Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx]; + Width = _WidthAdjustBox + (float)bx.TxtWidth - tabWidth; + } + else if (itemInfo.IsHigh) + { + Width = _WidthAdjust + ToPrint(formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.WidSTablePrint, maxRNO); + } + else if (MyParent == null) + { + // 72 points / inch - 7 inches (about width of page) + Width = 72 * 7; + } + else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh) + { + Width = MyParent.Width; + } + else + { + Width = MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign); + } + } + } + public enum ChildLocation : int + { + None = 0, + Below = 1, + Above = 2, + Right = 3, // RNO + Left = 4 + } + public partial class vlnTab : vlnPrintObject + { + public float TabWidth + { + get { return _CharsToTwips * TabText.Length; } + } + private float? _TabAlign; + /// + /// Used to Align Tabs for numeric tabs that can go to 2 digits + /// + public float TabAlign // Offset to Last printable character + { + get + { + if (_TabAlign == null) + { + _TabAlign = 0; + if (_TabText != null) + { + while (_TabText[(int)_TabAlign] == ' ') + _TabAlign++; + if ("0123456789".Contains(_TabText[(int)_TabAlign].ToString())) + { + while ("0123456789".Contains(_TabText[(int)_TabAlign].ToString())) + _TabAlign++; + _TabAlign--; + } + } + } + return (float)_TabAlign * _CharsToTwips; + } + } + private float? _TabOffset; + public float TabOffset // Offset to first printable character + { + get + { + if (_TabOffset == null) + { + _TabOffset = 0; + if(_TabText != null) + while(_TabText[(int)_TabOffset]==' ') + _TabOffset ++; + } + return (float)_TabOffset * _CharsToTwips; + } + } + private string _TabText; + public string TabText + { + get { return _TabText; } + set { _TabText = value; } + } + private VE_Font _MyFont; + public VE_Font MyFont + { + get { return _MyFont; } + set { _MyFont = value; } + } + } + public partial class vlnHeader : vlnPrintObject + { + public float HeaderWidth + { + get { return _WidthAdjust + (_CharsToTwips * HeaderText.Length); } + } + private string _HeaderText; + public string HeaderText + { + get { return _HeaderText; } + set { _HeaderText = value; } + } + private VE_Font _MyFont; + public VE_Font MyFont + { + get { return _MyFont; } + set { _MyFont = value; } + } + private ContentAlignment _ContentAlignment; + public ContentAlignment ContentAlignment + { + get { return _ContentAlignment; } + set { _ContentAlignment = value; } + } + } + public partial class vlnBox : vlnPrintObject + { + private int _LineType; /* how to represent?? */ + private Color _Color; + public Color Color + { + get { return _Color; } + set { _Color = value; } + } + public vlnBox(vlnParagraph paragraph/*, FormatBox box*/) + { + } + } + public partial class vlnChangeBar : vlnPrintObject + { + public vlnChangeBar(vlnParagraph parent, float xoff, float yoff) + { + _XOffset = xoff; + _YOffset = yoff; + _MyParent = parent; + } + } + public partial class vlnRNOSeparator : vlnPrintObject + { + private VE_Font _MyFont; + public VE_Font MyFont + { + get { return _MyFont; } + set { _MyFont = value; } + } + } + public partial class vlnMacro : vlnPrintObject + { + private string _MacroDef; + public string MacroDef + { + get { return _MacroDef; } + set { _MacroDef = value; } + } + } +}