using System; using System.Collections.Generic; using System.Text; using System.Drawing; using iTextSharp.text.pdf; using iTextSharp.text; using VEPROMS.CSLA.Library; namespace Volian.Print.Library { public partial class vlnBox : vlnPrintObject { private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private int _LineType; /* how to represent?? */ private System.Drawing.Color _Color; public System.Drawing.Color Color { get { return _Color; } set { _Color = value; } } private Box _MyBox; public Box MyBox { get { return _MyBox; } set { _MyBox = value; } } // the following two fields are used if 'boxed' step, thus // no 'Box' was defined in format file. public string DefBox = null; public float DefEnd = 0; public vlnBox() { } public vlnBox(vlnParagraph paragraph) { } public const string BoxThin = "\x2510.\x2500.\x250c.\x2502. . .\x2518.\x2514. .\x2500. . "; const string BoxThick = "\x2584.\x2584.\x2584.\x2588. . .\x2580.\x2580. .\x2580. . "; const string BoxDouble = "\x2557.\x2550.\x2554.\x2551. . .\x255D.\x255A. .\x2550. . "; const string BoxFPLNote = "\x2557.\x2550\xad.\x2554\xad.\x2551. . .\x255d.\x255a\xad. .\x2550\xad. . "; const string BoxFPLCaution = "\x2588.\x2580.\x2588.\x2588. . .\x2588.\x2588. .\x2584. . "; const string BoxAsterisk = " *.* .* . . . . *.* . .* . . "; const string BoxAsteriskWithSides = " *.* .* .* . . . *.* . .* . . "; public override float ToPdf(PdfContentByte cb, float yPageStart, ref float yTopMargin, ref float yBottomMargin) { if (MyBox == null) return yPageStart; cb.SaveState(); VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; PdfLayer textLayer = _MyPageHelper == null ? null : _MyPageHelper.TextLayer; if (textLayer != null) cb.BeginLayer(textLayer); MyContentByte = cb; //Console.WriteLine("'{0}','{1}'", CharToAsc(MyBox.BoxStyle), MyParent.MyItemInfo.ShortPath); float top = CalculateYOffset(yPageStart, yTopMargin) - (7*MyPageHelper.YMultiplier); float bottom = top - (Height * MyPageHelper.YMultiplier); float left = (float)((MyBox.Start ?? 0) + MyParent.MyItemInfo.MyDocStyle.Layout.LeftMargin); float right = (float)MyParent.MyItemInfo.MyDocStyle.Layout.LeftMargin + (float)(MyBox.End ?? DefEnd); iTextSharp.text.Color boxColor = new iTextSharp.text.Color(PrintOverride.OverrideBoxColor(System.Drawing.Color.Black)); cb.SetColorStroke(boxColor); if (DefBox != null) { cb.SetLineWidth(.6F); cb.Rectangle(left, bottom, right - left, Height * MyPageHelper.YMultiplier); } else { const float llxOffset = 3; float lineThickness = 0; switch (MyBox.BoxStyle) { case BoxThin: lineThickness = .6F; cb.SetLineWidth(lineThickness); cb.Rectangle(left + llxOffset, bottom + (lineThickness / 2), right - left, (Height - lineThickness) * MyPageHelper.YMultiplier); break; case BoxThick: lineThickness = 6; cb.SetLineWidth(lineThickness); cb.Rectangle(left + llxOffset, bottom + (lineThickness / 2), right - left, (Height - lineThickness) * MyPageHelper.YMultiplier); break; case BoxDouble: lineThickness = .6F; cb.SetLineWidth(lineThickness); // outer rectangle (rectangle's are defined as x,y,w,h) cb.Rectangle(left + llxOffset - lineThickness * 1.5F, bottom - lineThickness, right - left + lineThickness * 3, (Height + lineThickness * 2) * MyPageHelper.YMultiplier); // inner rectangle cb.Rectangle(left + llxOffset + lineThickness, bottom + lineThickness * 1.5F, right - left - lineThickness * 2, (Height - lineThickness * 3) * MyPageHelper.YMultiplier); break; case BoxFPLNote: lineThickness = 2; cb.SetLineWidth(lineThickness); float[] linePattern = { 6, 1.75F, 2.5F, 1.75F }; cb.SetLineDash(linePattern,3); cb.Rectangle(left + llxOffset, bottom + (lineThickness / 2) -1, right - left, (2 + Height - lineThickness) * MyPageHelper.YMultiplier); break; case BoxFPLCaution: lineThickness = 3; cb.SetLineWidth(lineThickness); // use a Y adjustment (top & bottom) to make the caution box match the 16bit output. float YbxAdjust = 6.5F; cb.Rectangle(left + llxOffset, bottom - YbxAdjust + (lineThickness / 2), right - left, (Height - lineThickness + 2*YbxAdjust) * MyPageHelper.YMultiplier); break; case BoxAsterisk: // this box is not drawn, it is a series of asterisks drawn above and below text. // For this box, there are no vertical edges (RGE uses this box type) DrawTopBottomAsterisk(cb, yPageStart, yTopMargin, yBottomMargin, ref top, ref bottom, left); break; case BoxAsteriskWithSides: DrawTopBottomAsterisk(cb, yPageStart, yTopMargin, yBottomMargin, ref top, ref bottom, left); DrawSideAsterisk(cb, yPageStart, yTopMargin, yBottomMargin, top, bottom, left, right); break; default: // For other than thick, thin and double. if (!_UnimplementedBoxStyles.Contains(MyBox.BoxStyle)) { _UnimplementedBoxStyles.Add(MyBox.BoxStyle); _MyLog.InfoFormat("Unimplemented Box Style {0} {1}", ShowBoxStyle(MyBox.BoxStyle), MyParent.MyItemInfo.ShortPath); //Console.WriteLine("Unimplemented Box Style {0} {1}", ShowBoxStyle(MyBox.BoxStyle), MyParent.MyItemInfo.ShortPath); } break; //throw new Exception("Missing vlnBox handler"); } } cb.Stroke(); if (textLayer != null) cb.EndLayer(); cb.RestoreState(); return yPageStart; } private void DrawSideAsterisk(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin, float top, float bottom, float left, float right) { top = CalculateYOffset(yPageStart, yTopMargin); bottom = top - (Height * MyPageHelper.YMultiplier); VE_Font vf = MyParent.MyItemInfo.FormatStepData.Font; // Left side first: string Rtf = GetRtf(MyBox.BXVert, vf); float vertDiff = top; float size = (float)(MyBox.BXVert.Length * (72 / vf.CPI)); while (vertDiff > bottom) { Rtf2Pdf.TextAt(cb, IParagraph, left, vertDiff, size, 100, "", yBottomMargin); vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier); } // right side: vertDiff = top; Rtf = GetRtf(MyBox.BXVert.TrimEnd(), vf); while (vertDiff > bottom) { if (MyBox.End != null)Rtf2Pdf.TextAt(cb, IParagraph, (float) MyBox.End, vertDiff, size, 100, "", yBottomMargin); vertDiff = (SixLinesPerInch * MyPageHelper.YMultiplier); } } private void DrawTopBottomAsterisk(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin, ref float top, ref float bottom, float left) { top = CalculateYOffset(yPageStart, yTopMargin); bottom = top - (Height * MyPageHelper.YMultiplier); VE_Font vf = MyParent.MyItemInfo.FormatStepData.Font; // Top line first: StringBuilder sb = new StringBuilder(); sb.Append(MyBox.BXVert); float size = (float)(MyBox.BXULC.Length * (72 / vf.CPI)); while (size < MyBox.End) { sb.Append(MyBox.BXHorz); size = size + (float)(MyBox.BXHorz.Length * (72 / vf.CPI)); } // Tack on the right upper corner. For some reason, the upper right corner in the // formats had the first character as a space, this would put two spaces in a row // at the end of the string, so remove the space before tacking on the upper right // corner: string bxstr = sb.ToString().TrimEnd() + MyBox.BXURC; size = size + (float)((MyBox.BXURC.Length) * (72 / vf.CPI)); Rtf = GetRtf(bxstr, vf); Rtf2Pdf.TextAt(cb, IParagraph, left, top, size, 100, "", yBottomMargin); // Bottom line now sb.Remove(0, sb.Length); sb.Append(MyBox.BXLLC); size = (float)(MyBox.BXLLC.Length * (72 / vf.CPI)); while (size < MyBox.End) { sb.Append(MyBox.BXHorz); size = size + (float)(MyBox.BXHorz.Length * (72 / vf.CPI)); } bxstr = sb.ToString().TrimEnd() + MyBox.BXLRC; size = size + (float)((MyBox.BXLRC.Length) * (72 / vf.CPI)); Rtf = GetRtf(bxstr, vf); Rtf2Pdf.TextAt(cb, IParagraph, left, bottom, size, 100, "", yBottomMargin); } private string ShowBoxStyle(string str) { StringBuilder sb = new StringBuilder(); foreach (Char c in str) { if (c >= ' ' && c < 128) sb.Append(c); else sb.Append(string.Format("x{0:X0000}", (int)c)); } return sb.ToString(); } private static List _UnimplementedBoxStyles = new List(); private string CharToAsc(string p) { StringBuilder sb = new StringBuilder(); foreach (char c in p) { if (c >= ' ' && c < 127) sb.Append(c); else sb.Append(string.Format("\\x{0:x}", (int)c)); } return sb.ToString(); } } }