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) { //int[] problemIDs = { 871, 877 }; //List lProblemIDs = new List( problemIDs ); //if (lProblemIDs.Contains(itemInfo.ItemID)) // Console.WriteLine("Found Item {0}", itemInfo.ItemID); 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) // if (itemInfo.MyHeader != null && itemInfo.MyHeader.Text != null && itemInfo.MyHeader.Text != "") // EquipmentWBlank uses an empty string 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 (itemInfo.IsTablePart) { Width = GetTableWidth(cb, IParagraph); vlnParagraph hls = MyParent; bool aerTable = itemInfo.FormatStepData.Type.Contains("AER"); while (hls.MyParent != null) { if (aerTable && hls.MyItemInfo.IsHigh) break; hls = hls.MyParent; } XOffset = hls.XOffset + hls.Width / 2 - Width / 2; if (XOffset < (float)itemInfo.MyDocStyle.Layout.LeftMargin) XOffsetBox = (float)itemInfo.MyDocStyle.Layout.LeftMargin; } //if (MyItemInfo.ItemID == 117) //{ // Rtf = Rtf.Replace("3 psig", @"3\'A0psig"); // //Console.WriteLine("'{0}'", Rtf); //} if (!itemInfo.IsStepSection) // Don't add any lines for the Section Title { 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: // // Locations: With Text, Outside Box, AER on Left RNO on Right, To The Left of Text // Text: Date & Change ID, Revision Number, Change ID, None, Custom (use input data) // Flag AERChgBarMsgRNOChgBarNoMsg and AERMsgRNONoMsg are NOT Used in 16-bit. 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; // Now get the text. // This is only the User Change Bar Message from the docversion config. Any other data is determined // during printing, i.e. item or page specific. //if (cbd.MyChangeBarText == DocVersionConfig.PrintChangeBarText.ChgID || cbd.MyChangeBarText == DocVersionConfig.PrintChangeBarText.DateChgID) //{ // cbd.MyChangeBarMessage = myItemInfo.UserID; // string mydts = null; // if (changeBarData.ChgBarMessageFromEdit) // { // StepInfo si = (StepInfo)myItemInfo; // if (si != null) // { // StepConfig sc = si.MyConfig as StepConfig; // if (sc != null && sc.Step_MultipleChangeID != null) cbd.MyChangeBarMessage = sc.Step_MultipleChangeID; // } // } // if (cbd.MyChangeBarText == DocVersionConfig.PrintChangeBarText.DateChgID) cbd.MyChangeBarMessage = cbd.MyChangeBarMessage + @"\" + myItemInfo.DTS.Date.ToString(); //} //else if (cbd.MyChangeBarText == DocVersionConfig.PrintChangeBarText.RevNum) //{ // //TODO //} //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 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); if (fixedChgCol < -10 || fixedChgCol >= 0) return ((fixedChgCol > 0) ? fixedChgCol : (fixedChgCol == 0) ? (int)c + 1 : (c > cols + colr + COL_WID_ADJ) ? -fixedChgCol : AERLeftChangeBarLocation(formatInfo)); else return (fixedChgCol + (((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; } } }