
Set the offset of the BackGround (Overlay) depending on the source of the background. If the background source is 32 Bit set the offset to zero. Add DebugPagination output for blank pages Add DebugPagination output for MSWord Sections Add DbeugPagination output for Foldout pages Only adjust wordwrap if background is not 32Bit output Added Back32BitPROMS boolean property to determine if the background is 32 Bit output
390 lines
12 KiB
C#
390 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using iTextSharp.text.pdf;
|
|
using iTextSharp.text;
|
|
using Itenso.Rtf;
|
|
using Itenso.Rtf.Parser;
|
|
using Itenso.Rtf.Interpreter;
|
|
using Itenso.Rtf.Support;
|
|
using Volian.Controls.Library;
|
|
using VEPROMS.CSLA.Library;
|
|
|
|
namespace Volian.Print.Library
|
|
{
|
|
public abstract partial class vlnPrintObject
|
|
{
|
|
// Used for debugging:
|
|
private static int _UniqueDebugId = 0;
|
|
public static int UniqueDebugId
|
|
{
|
|
get { return _UniqueDebugId++; }
|
|
set { _UniqueDebugId = value; }
|
|
}
|
|
private int _DebugId = UniqueDebugId;
|
|
public int DebugId
|
|
{
|
|
get { return _DebugId; }
|
|
set { _DebugId = value; }
|
|
}
|
|
|
|
protected static float _WidthAdjust = 1; // 1 Point - adjusted to match 16-bit line wrapping. For editting it's 3.
|
|
protected static float _WidthAdjustBox = 6;
|
|
private static float _SixLinesPerInch = 12; // twips
|
|
public static float SixLinesPerInch
|
|
{
|
|
get { return vlnPrintObject._SixLinesPerInch; }
|
|
set { vlnPrintObject._SixLinesPerInch = value; }
|
|
}
|
|
protected static float _SevenLinesPerInch = 10.1F;//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 _ImageText; // ro definition, value part of #Link in case of image/figure
|
|
public string ImageText
|
|
{
|
|
get { return _ImageText; }
|
|
set { _ImageText = value; }
|
|
}
|
|
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; }
|
|
}
|
|
protected float _Height;
|
|
public float Height
|
|
{
|
|
get
|
|
{
|
|
if (_Height == 0)
|
|
_Height = GetParagraphHeight(MyContentByte, IParagraph, Width);
|
|
return _Height;
|
|
}
|
|
set { _Height = value; }
|
|
}
|
|
public float GetParagraphHeight(PdfContentByte cb, Paragraph iParagraph, float width)
|
|
{
|
|
return GetParagraphHeight(cb, iParagraph, width, true);
|
|
}
|
|
public float GetParagraphHeight(PdfContentByte cb, Paragraph iParagraph, float width, bool throwException)
|
|
{
|
|
VlnSvgPageHelper ph = null;
|
|
if(cb != null) ph = cb.PdfWriter.PageEvent as VlnSvgPageHelper;
|
|
float heightAll = GetHeight(cb, iParagraph, width, throwException);
|
|
if (ph != null && ph.MyPromsPrinter.DebugOutput && !MyPageHelper.Back32BitPROMS)
|
|
{
|
|
vlnParagraph myParagraph = this as vlnParagraph;
|
|
if (myParagraph != null)
|
|
{
|
|
//if (myParagraph.MyItemInfo.FormatStepData != null && myParagraph.MyItemInfo.FormatStepData.Font.Family == "Prestige Elite Tall")
|
|
if (!myParagraph.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WrapSameAsEdit)
|
|
{
|
|
Chunk chk = RemoveLastCharacter(iParagraph);
|
|
float heightAllButOne = GetHeight(cb, iParagraph, width, throwException);
|
|
if (heightAll != heightAllButOne)
|
|
return heightAllButOne;
|
|
if (chk != null)
|
|
RestoreLastCharacter(iParagraph, chk);
|
|
}
|
|
}
|
|
}
|
|
return heightAll;
|
|
}
|
|
private static void RestoreLastCharacter(Paragraph iParagraph, Chunk chk)
|
|
{
|
|
iParagraph.RemoveAt(iParagraph.Count - 1);
|
|
iParagraph.Add(chk);
|
|
}
|
|
private static Chunk RemoveLastCharacter(Paragraph iParagraph)
|
|
{
|
|
if (iParagraph.Count == 0)
|
|
return null;
|
|
object obj = iParagraph[iParagraph.Count-1];
|
|
Chunk chk = obj as Chunk;
|
|
if (chk == null)
|
|
return null;
|
|
string s = chk.Content;
|
|
if (s.Length > 1) // don't remove last character if it's the only one
|
|
{
|
|
iParagraph.RemoveAt(iParagraph.Count - 1);
|
|
s = s.Substring(0, s.Length - 1);
|
|
iParagraph.Add(new Chunk(s, chk.Font));
|
|
}
|
|
return chk;
|
|
}
|
|
private static float GetHeight(PdfContentByte cb, Paragraph iParagraph, float width, bool throwException)
|
|
{
|
|
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) && throwException)
|
|
//throw (new Exception("Paragraph longer than a page"));
|
|
Console.WriteLine("Paragraph longer than a page");
|
|
return 792F - myColumnText.YLine; // This gives the height of the Paragraph
|
|
}
|
|
public float GetTableWidth(PdfContentByte cb, Paragraph iParagraph, float? maxWidth)
|
|
{
|
|
int iWidth = (int)(maxWidth ?? 72 * 8.5F);
|
|
float h = GetParagraphHeight(cb, iParagraph, iWidth);
|
|
int iWidthMax = iWidth; // maximum width in Characters
|
|
int iDelta = iWidth / 2;
|
|
iWidth = iWidth / 2;
|
|
while (iDelta > 0)
|
|
{
|
|
float h2 = GetParagraphHeight(cb, iParagraph, iWidth,false);
|
|
iDelta = iDelta / 2;
|
|
if (h2 == h) iWidthMax = iWidth;
|
|
iWidth += (h2>h ? 1: -1) * iDelta;
|
|
}
|
|
return (float) iWidthMax;
|
|
}
|
|
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()
|
|
{
|
|
}
|
|
/// <summary>
|
|
/// No conversion necessary: twips -> twips
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static int ToInt(int value)
|
|
{
|
|
return value;
|
|
}
|
|
/// <summary>
|
|
/// No conversion necessary: int? twips -> int twips
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static int ToInt(int? value)
|
|
{
|
|
return ToInt((int)value);
|
|
}
|
|
/// <summary>
|
|
/// No conversion necessary: string twips -> int twips
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static int ToInt(string value)
|
|
{
|
|
return ToInt((int)Convert.ToSingle(value));
|
|
}
|
|
/// <summary>
|
|
/// No conversion necessary: value from a list in a string, twips -> int twips
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static int ToInt(string value, int i)
|
|
{
|
|
string s = value.Split(",".ToCharArray())[i];
|
|
return ToInt(s);
|
|
}
|
|
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(AddFontTable(vFont.WindowsFont));
|
|
rtfSB.Append(vlntxt.StartText);
|
|
rtfSB.Append("}");
|
|
return rtfSB.ToString();
|
|
}
|
|
public 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 = Volian.Svg.Library.VolianPdf.GetFont(font);
|
|
float fW = iFont.BaseFont.GetWidthPointKerned("W", 12);
|
|
float fE = iFont.BaseFont.GetWidthPointKerned("!", 12);
|
|
return fW == fE;
|
|
}
|
|
public 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);
|
|
if (rtf.Contains("\x05"))
|
|
{
|
|
// if there is a hanging indent, the iTextSharp paragraph properties must be set
|
|
// to print the indent. Replace the indent 'token' with a non-used symbol, this will
|
|
// create a chunk with that symbol. Then loop through all of the chunks until we find
|
|
// this symbol, adding up the widths to that point. This width is the value that
|
|
// needs to be used to set the indent.
|
|
IRtfDocument rtfDoc2 = RtfInterpreterTool.BuildDoc(rtf.Replace("\x05", @"\f1 \u9999? \f0 "));
|
|
Rtf2iTextSharp rtf2IText2 = new Rtf2iTextSharp(rtfDoc2);
|
|
iTextSharp.text.Paragraph para2 = rtf2IText2.Convert();
|
|
float chkW = 0;
|
|
foreach (Chunk chk in para2.Chunks)
|
|
{
|
|
if (chk.Content[0] == 9999) break;
|
|
chkW += chk.GetWidthPoint();
|
|
}
|
|
para.IndentationLeft = chkW;
|
|
para.FirstLineIndent = -chkW;
|
|
}
|
|
return para;
|
|
}
|
|
public abstract float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin);
|
|
protected float CalculateYOffset(float yPageStart, float yTopMargin)
|
|
{
|
|
float yLocation = yPageStart - YOffset;
|
|
if (MyPageHelper.YMultiplier != 1)
|
|
{
|
|
yLocation = -1 + yTopMargin - (yTopMargin - yLocation) * MyPageHelper.YMultiplier;
|
|
if (Rtf != null)
|
|
IParagraph.Leading = _SevenLinesPerInch;
|
|
}
|
|
return yLocation;
|
|
}
|
|
protected float CalculateYLocation(float yLocation, float yTopMargin)
|
|
{
|
|
if (MyPageHelper.YMultiplier != 1)
|
|
yLocation = -1 + yTopMargin - (yTopMargin - yLocation) * MyPageHelper.YMultiplier;
|
|
return yLocation;
|
|
}
|
|
public void DebugPdf(PdfContentByte cb, float left, float top)
|
|
{
|
|
VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper;
|
|
PdfLayer debugLayer = _MyPageHelper == null ? null : _MyPageHelper.DebugLayer;
|
|
if (debugLayer == null) return;
|
|
cb.SaveState();
|
|
cb.BeginLayer(debugLayer);
|
|
ColumnText ct = new ColumnText(cb);
|
|
ct.SetSimpleColumn(left, top, left+50, top - 50);
|
|
iTextSharp.text.Font font = FontFactory.GetFont("Arial", 2);
|
|
Chunk chk = new Chunk(DebugId.ToString(), font);
|
|
Phrase ph = new Phrase(chk);
|
|
ct.AddElement(ph);
|
|
cb.SetColorFill(new iTextSharp.text.Color(PrintOverride.OverrideDebugColor(System.Drawing.Color.Gray)));
|
|
ct.Go();
|
|
cb.EndLayer();
|
|
cb.RestoreState();
|
|
}
|
|
public virtual float YBottom
|
|
{ get { return YOffset + Height;} }
|
|
}
|
|
public partial class vlnPrintObjects : List<vlnPrintObject>
|
|
{
|
|
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 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 enum ChildLocation : int
|
|
{
|
|
None = 0,
|
|
Below = 1,
|
|
Above = 2,
|
|
Right = 3, // RNO
|
|
Left = 4
|
|
}
|
|
|
|
}
|