234 lines
9.8 KiB
C#

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 BoxAsteriskWithSides1 = " *.* .* .* . . . *.* . .* . . "; // ip2
const string BoxAsteriskWithSides2 = "*. *.*.*. . .*.*. . *. . "; // ip3 (sub 15)
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);
_MyPageHelper.MyGaps.Add(top, bottom);
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:
DrawAsteriskTopBottom(cb, yPageStart, yTopMargin, yBottomMargin, ref top, ref bottom, left);
break;
case BoxAsteriskWithSides1:
case BoxAsteriskWithSides2:
DrawAsteriskTopBottom(cb, yPageStart, yTopMargin, yBottomMargin, ref top, ref bottom, left);
DrawAsteriskSide(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 DrawAsteriskTopBottom(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin, ref float top, ref float bottom, float left)
{
// 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)
top = CalculateYOffset(yPageStart, yTopMargin);
// Bug fix B2013-091
// added YMultiplier to handle compress pages
// bottom row of asterisks was in non-compressed line location
bottom = top - (Height * MyPageHelper.YMultiplier);//Height;
// create a new font without any styles such as underline.
VE_Font vf = new VE_Font(MyParent.MyItemInfo.FormatStepData.Font.Family, (int)MyParent.MyItemInfo.FormatStepData.Font.Size, E_Style.None, (float)MyParent.MyItemInfo.FormatStepData.Font.CPI);
// Top line first:
StringBuilder sb = new StringBuilder();
sb.Append(MyBox.BXULC);
float size = (float)(MyBox.BXULC.Length * (72/vf.CPI));
while (size < (MyBox.End - MyBox.Start))
{
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);
IParagraph = null; // set to null so that next access of IParagraph sets the Rtf.
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-MyBox.Start))
{
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);
IParagraph = null; // set to null so that next access of IParagraph sets the Rtf.
Rtf2Pdf.TextAt(cb, IParagraph, left, bottom, size, 100, "", yBottomMargin);
}
private void DrawAsteriskSide(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);
float height = (SixLinesPerInch * MyPageHelper.YMultiplier) + 4; // just add a little on so that height is a little bigger than character
VE_Font vf = MyParent.MyItemInfo.FormatStepData.Font;
// Left side first:
Rtf = GetRtf(MyBox.BXVert, vf);
IParagraph = null; // set to null so that next access of IParagraph sets the Rtf.
// start down one line because the top/bottom code draws the corner
float vertDiff = top - (SixLinesPerInch * MyPageHelper.YMultiplier);
float width = (float)(MyBox.BXVert.Length * (72 / vf.CPI));
while (vertDiff > bottom)
{
Rtf2Pdf.TextAt(cb, IParagraph, left, vertDiff, width, height, "", yBottomMargin);
vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier);
}
// right side:
vertDiff = top - (SixLinesPerInch * MyPageHelper.YMultiplier);
Rtf = GetRtf(MyBox.BXVert.TrimEnd(), vf);
IParagraph = null; // set to null so that next access of IParagraph sets the Rtf.
while (vertDiff > bottom)
{
Rtf2Pdf.TextAt(cb, IParagraph, right, vertDiff, width, height, "", yBottomMargin);
vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier);
}
}
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<string> _UnimplementedBoxStyles = new List<string>();
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();
}
}
}