using System; using System.Collections; using System.Text; using System.Collections.Generic; //using System.Text; using System.Xml.Serialization; 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; using System.Text.RegularExpressions; using System.Xml; using System.IO; namespace Volian.Svg.Library { public static class VolianPdf { public static int PageCount(string fileName) { PdfReader pdfr = new PdfReader(fileName); int retval = pdfr.NumberOfPages; pdfr.Close(); return retval; } } internal static class SvgITextLibrary { public static void StrokeAndFill(PdfContentByte cb, bool stroke, bool fill) { switch ((stroke ? 1 : 0) + (fill ? 2 : 0)) { case 0: // No Stroke or Fill break; case 1: // Stroke cb.Stroke(); break; case 2: // Fill cb.Fill(); break; case 3: // Stroke and Fill cb.FillStroke(); break; } } } public abstract partial class SvgPart { public abstract void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent); public abstract void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent); } public partial class SvgPartInheritance : SvgPart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { } } // TODO: Pages // TODO: Page Background public delegate string SvgProcessTextEvent(object sender, SvgProcessTextArgs args); public class SvgProcessTextArgs { private string _MyText; public string MyText { get { return _MyText; } } public SvgProcessTextArgs(string myText) { _MyText = myText; } } public partial class Svg : SvgGroup { public void DrawMacro(string macroDef, float x, float y, PdfContentByte cb) { _MyContentByte = cb; SvgMeasurement X = new SvgMeasurement(x-6, E_MeasurementUnits.PT); // Not sure why this is? seems to be a character too far to the right? SvgMeasurement Y = new SvgMeasurement(Height.GetSizeInPoints(72) - y, E_MeasurementUnits.PT); SvgGroup macro = this[macroDef] as SvgGroup; macro.SvgParts.Draw(cb, MyScale.AdjustOrigin(X, Y), this,this); } public event SvgProcessTextEvent ProcessText; internal string OnProcessText(string myText) { if (ProcessText != null) return ProcessText(this, new SvgProcessTextArgs(myText)); return myText; } private Dictionary _Templates; public PdfTemplate GetTemplate(string name, PdfContentByte cb) { if (!_Templates.ContainsKey(name)) { PdfTemplate tmp = cb.CreateTemplate(100, 100); _Templates.Add(name, tmp); //tmp.BoundingBox = new iTextSharp.text.Rectangle(-200,-200,700,200); } return _Templates[name]; } public static void FixBoundingBox(PdfTemplate tmp, float xll, float yll, float xul, float yul) { float left = tmp.BoundingBox.Left; float bottom = tmp.BoundingBox.Bottom; float right = tmp.BoundingBox.Right; float top = tmp.BoundingBox.Top; left = (xll < xul ? (xll < left ? xll : left) : (xul < left ? xul : left)); right = (xll > xul ? (xll > right ? xll : right) : (xul > right ? xul : right)); bottom = (yll < yul ? (yll < bottom ? yll : bottom) : (yul < bottom ? yul : bottom)); top = (yll > yul ? (yll > top ? yll : top) : (yul > top ? yul : top)); tmp.BoundingBox = new iTextSharp.text.Rectangle(xll, yll, xul, yul); } private PdfContentByte _MyContentByte; [XmlIgnore] public PdfContentByte MyContentByte { get { return _MyContentByte; } set { _MyContentByte = value; } } private float _LeftMargin = 0; public float LeftMargin { get { return _LeftMargin; } set { _LeftMargin = value; } } private float _TopMargin = 0; public float TopMargin { get { return _TopMargin; } set { _TopMargin = value; } } private SvgScale _MyScale; public SvgScale MyScale { get { if (_MyScale == null) { _MyScale = new SvgScale(72, new System.Drawing.RectangleF(0, 0, _MyContentByte.PdfWriter.PageSize.Width, _MyContentByte.PdfWriter.PageSize.Height), _Width, _Height, _ViewBox); _MyScale.XLowerLimit -= _LeftMargin; _MyScale.YLowerLimit -= _TopMargin; } return _MyScale; } } public void Draw(PdfContentByte cb) { //myPdf.Clear(); _MyContentByte = cb; _Templates = new Dictionary(); //RegisterFonts(); SvgParts.Draw(cb, MyScale, this, this); //72 - Points } public static iTextSharp.text.Font GetFont(string fontName) { RegisterFont(fontName); return FontFactory.GetFont(fontName); } //private void RegisterFonts() //{ // //if (!FontFactory.IsRegistered("Arial")) // //{ // // RegisterFont("Prestige Elite Tall"); // //} //} public static void RegisterFont(string fontName) { if (!FontFactory.IsRegistered(fontName)) { foreach (string name in FontKey.GetValueNames()) { if (name.StartsWith(fontName)) { string fontFile = (string) FontKey.GetValue(name); 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 int _StackTraceSkip = 1; private static DateTime _LastTime = DateTime.Now; private static DateTime _StartTime = DateTime.Now; public static void ResetWhen() { _StartTime = _LastTime = DateTime.Now; } public static void WhenAndWhere() { DateTime thisTime = DateTime.Now; System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(_StackTraceSkip, true); Console.WriteLine("{0:000000},{1:000000},'{2}',{3},'{4}'", TimeSpan.FromTicks(thisTime.Ticks - _StartTime.Ticks).TotalMilliseconds, TimeSpan.FromTicks(thisTime.Ticks - _LastTime.Ticks).TotalMilliseconds, sf.GetMethod().Name, sf.GetFileLineNumber() ,sf.GetFileName()); _LastTime = thisTime; } } public partial class SvgArc : SvgShapePart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { cb.SaveState(); SetupInheritance(myParent.MyInheritedSettings); if (FillColor != System.Drawing.Color.Transparent) cb.SetColorFill(new Color(FillColor)); if (OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty) { cb.SetLineWidth(scale.M(OutlineWidth)); cb.SetColorStroke(new Color(OutlineColor)); } cb.Ellipse(scale.X(CX - Radius), scale.Y(cb, CY - Radius), scale.M(Radius * 2), scale.M(Radius * 2)); SvgITextLibrary.StrokeAndFill(cb, (OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty), (FillColor != System.Drawing.Color.Transparent)); cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { tmp.SaveState(); SetupInheritance(myParent.MyInheritedSettings); if (FillColor != System.Drawing.Color.Transparent) tmp.SetColorFill(new Color(FillColor)); if (OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty) { tmp.SetLineWidth(scale.M(OutlineWidth)); tmp.SetColorStroke(new Color(OutlineColor)); } tmp.Ellipse(scale.X(CX - Radius), scale.Y(CY - Radius), scale.M(Radius * 2), scale.M(Radius * 2)); SvgITextLibrary.StrokeAndFill(tmp, (OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty), (FillColor != System.Drawing.Color.Transparent)); tmp.RestoreState(); } } public partial class SvgCircle : SvgShapePart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); cb.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; if (fill) cb.SetColorFill(new Color(FillColor)); if (stroke) { cb.SetLineWidth(scale.M(OutlineWidth)); cb.SetColorStroke(new Color(OutlineColor)); } float x1 = scale.X(CX - Radius); float y1 = scale.Y(cb, CY - Radius); float x2 = scale.X(CX + Radius); float y2 = scale.Y(cb, CY + Radius); cb.Ellipse(x1, y1, x2, y2); SvgITextLibrary.StrokeAndFill(cb, stroke, fill); cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); tmp.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; if (fill) tmp.SetColorFill(new Color(FillColor)); if (stroke) { tmp.SetLineWidth(scale.M(OutlineWidth)); tmp.SetColorStroke(new Color(OutlineColor)); } tmp.Ellipse(scale.X(CX - Radius), scale.Y(CY - Radius), scale.X(CX + Radius), scale.Y(CY + Radius)); SvgITextLibrary.StrokeAndFill(tmp, stroke, fill); tmp.RestoreState(); Svg.FixBoundingBox(tmp, scale.X(CX - Radius), scale.Y(CY - Radius), scale.X(CX + Radius), scale.Y(CY + Radius)); } } public partial class SvgDefine : SvgGroup { public override void Draw(PdfContentByte cb, SvgScale myScale, Svg mySvg, SvgPartInheritance myParent) { // TODO: Could I try creating a template // Don't draw // SvgParts.Draw(cb, myScale, mySvg, myParent); PdfTemplate tmp = null; if (ID != "") tmp = mySvg.GetTemplate(ID, cb); // the size will be adjusted as items are added. SvgParts.Draw(tmp, myScale, mySvg, myParent); } public override void Draw(PdfTemplate tmp, SvgScale myScale, Svg mySvg, SvgPartInheritance myParent) { // TODO: Could I try creating a template // Don't draw // SvgParts.Draw(cb, myScale, mySvg, myParent); //PdfTemplate tmp2 = mySvg.GetTemplate(ID); // the size will be adjusted as items are added. //SvgParts.Draw(tmp2, myScale, mySvg, myParent); } } public partial class SvgUse : SvgPartInheritance { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { // TODO: Could I use the template SetupInheritance(myParent.MyInheritedSettings); mySvg[_UseID].Draw(cb, scale.AdjustOrigin(X, Y), mySvg, this); //cb.AddTemplate(mySvg.GetTemplate(_UseID.Substring(1),cb), scale.X(X), scale.Y(cb, Y)); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { // TODO: Could I use the template SetupInheritance(myParent.MyInheritedSettings); //mySvg[_UseID.Substring(1)].Draw(tmp, scale.AdjustOrigin(X, Y), mySvg, this); mySvg[_UseID].Draw(tmp, scale.AdjustOrigin(X, Y), mySvg, this); } } public partial class SvgEllipse : SvgShapePart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); cb.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; if (fill) cb.SetColorFill(new Color(FillColor)); if (stroke) { cb.SetLineWidth(scale.M(OutlineWidth)); cb.SetColorStroke(new Color(OutlineColor)); } cb.Ellipse(scale.X(CX - RX), scale.Y(cb, CY - RY), scale.X(CX + RX), scale.Y(cb, CY + RY)); SvgITextLibrary.StrokeAndFill(cb, stroke, fill); cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); tmp.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; if (fill) tmp.SetColorFill(new Color(FillColor)); if (stroke) { tmp.SetLineWidth(scale.M(OutlineWidth)); tmp.SetColorStroke(new Color(OutlineColor)); } tmp.Ellipse(scale.X(CX - RX), scale.Y(CY - RY), scale.X(CX + RX), scale.Y(CY + RY)); SvgITextLibrary.StrokeAndFill(tmp, stroke, fill); tmp.RestoreState(); } } public partial class SvgGroup : SvgPartInheritance { public override void Draw(PdfContentByte cb, SvgScale myScale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); _SvgParts.Draw(cb, myScale, mySvg, this); } public override void Draw(PdfTemplate tmp, SvgScale myScale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); if (ID != "") tmp = mySvg.GetTemplate(ID, mySvg.MyContentByte); // the size will be adjusted as items are added. SvgParts.Draw(tmp, myScale, mySvg, this); } } public partial class SvgImage : SvgPart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); cb.SaveState(); iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(ImagePath); //Console.WriteLine("Before ScaledHeight = {0}", img.ScaledHeight); if (Height.Value != 0) img.ScaleAbsoluteHeight(scale.M(Height)); if (Width.Value != 0) img.ScaleAbsoluteWidth(scale.M(Width)); //Console.WriteLine("After ScaledHeight = {0}", img.ScaledHeight); img.SetAbsolutePosition(scale.X(X), scale.Y(cb, Y) - scale.M(img.ScaledHeight)); cb.AddImage(img); cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); tmp.SaveState(); iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(ImagePath); img.ScaleAbsolute(scale.M(Width), scale.M(Height)); img.SetAbsolutePosition(scale.X(X), scale.Y(Y) - scale.M(img.ScaledHeight)); tmp.AddImage(img); tmp.RestoreState(); } } public partial class SvgLine : SvgLinePart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); cb.SaveState(); bool stroke = LineColor != System.Drawing.Color.Empty; if (stroke) { //cb.SetLineWidth(scale.M(LineWidth)); cb.SetLineWidth(LineWidth.Value); cb.SetColorStroke(new Color(LineColor)); //cb.SetColorStroke(Color.BLACK); } //cb.SetColorStroke(Color.GREEN); cb.SetLineCap(PdfContentByte.LINE_CAP_ROUND); cb.MoveTo(scale.X(X1), scale.Y(cb, Y1)); cb.LineTo(scale.X(X2), scale.Y(cb, Y2)); //Console.WriteLine("'CB Line',{0},{1},{2},{3},{4}", scale.X(X1), scale.Y(cb, Y1), scale.X(X2), scale.Y(cb, Y2), scale.M(LineWidth)); cb.Stroke(); cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); tmp.SaveState(); bool stroke = LineColor != System.Drawing.Color.Empty; if (stroke) { tmp.SetLineWidth(scale.M(LineWidth)); tmp.SetColorStroke(new Color(LineColor)); } tmp.MoveTo(scale.X(X1), scale.Y(Y1)); tmp.LineTo(scale.X(X2), scale.Y(Y2)); //Console.WriteLine("'Template Line',{0},{1},{2},{3},{4}", scale.X(X1), scale.Y(tmp, Y1), scale.X(X2), scale.Y(tmp, Y2), scale.M(LineWidth)); tmp.Stroke(); tmp.RestoreState(); Svg.FixBoundingBox(tmp, scale.X(X1), scale.Y(Y1), scale.X(X2), scale.Y(Y2)); } } public partial class SvgParts : CollectionBase { public void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { foreach (SvgPart svgPart in List) svgPart.Draw(cb, scale, mySvg, myParent); } public void Draw(PdfTemplate tmp, SvgScale myScale, Svg mySvg, SvgPartInheritance myParent) { foreach (SvgPart svgPart in List) svgPart.Draw(tmp, myScale, mySvg, myParent); } } public partial class SvgRectangle : SvgShapePart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); cb.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; if (fill) cb.SetColorFill(new Color(FillColor)); if (stroke) { cb.SetLineWidth(scale.M(OutlineWidth)); cb.SetColorStroke(new Color(OutlineColor)); } cb.Rectangle(scale.X(X), scale.Y(cb, Y), scale.M(Width), -scale.M(Height)); SvgITextLibrary.StrokeAndFill(cb, stroke, fill); cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { SetupInheritance(myParent.MyInheritedSettings); if (ID != "") tmp = mySvg.GetTemplate(ID, mySvg.MyContentByte); // the size will be adjusted as items are added. tmp.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; if (fill) tmp.SetColorFill(new Color(FillColor)); if (stroke) { tmp.SetLineWidth(scale.M(OutlineWidth)); tmp.SetColorStroke(new Color(OutlineColor)); } //tmp.Rectangle(scale.X(X), scale.Y(Y), scale.M(Width), -scale.M(Height)); tmp.Rectangle(scale.X(X), scale.Y(Y), scale.M(Width), -scale.M(Height)); SvgITextLibrary.StrokeAndFill(tmp, stroke, fill); Svg.FixBoundingBox(tmp, scale.X(X), scale.Y(Y), scale.X(X) + scale.M(Width), scale.Y(Y) - scale.M(Height)); tmp.RestoreState(); } } //public partial class SvgRtf : SvgShapePart //{ // public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) // { // ColumnText ct = new ColumnText(cb); // IRtfDocument myRtf = RtfInterpreterTool.BuildDoc(Rtf); // Rtf2iTextSharp rtf = new Rtf2iTextSharp(myRtf); // Paragraph p = rtf.Convert(); // p.SetLeading(0, 1); // float leading = 10; // ct.SetSimpleColumn(scale.X(X), scale.Y(cb, Y) + leading, scale.X(X) + scale.M(Width), scale.Y(cb, Y) - cb.PdfDocument.PageSize.Height); // ct.AddElement(p); // ct.Go(); // } // public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) // { // ColumnText ct = new ColumnText(tmp); // IRtfDocument myRtf = RtfInterpreterTool.BuildDoc(Rtf); // Rtf2iTextSharp rtf = new Rtf2iTextSharp(myRtf); // Paragraph p = rtf.Convert(); // p.SetLeading(0, 1); // float leading = 10; // ct.SetSimpleColumn(scale.X(X), scale.Y(Y) + leading, scale.X(X) + scale.M(Width), scale.Y(Y) - tmp.PdfDocument.PageSize.Height); // ct.AddElement(p); // ct.Go(); // } //} public partial class SvgText : SvgShapePart { public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { string text = mySvg.OnProcessText(Text); SetupInheritance(myParent.MyInheritedSettings); float yScale = scale.Y(cb, Y); cb.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; //cb.MoveTo(0, scale.Y(cb, Y)); //cb.LineTo(500, scale.Y(cb, Y)); //cb.SetColorStroke(Color.BLUE); //cb.Stroke(); //cb.BeginText(); /* if (fill) cb.SetColorFill(new Color(FillColor)); if (stroke) { cb.SetLineWidth(scale.M(OutlineWidth)); cb.SetColorStroke(new Color(OutlineColor)); } cb.SetColorFill(Color.RED); */ //iTextSharp.text.pdf.ColumnText ct = new ColumnText(cb); iTextSharp.text.Font font = FontFactory.GetFont(Font.Name, scale.M(new SvgMeasurement(Font.SizeInPoints, E_MeasurementUnits.PT))); //BaseFont baseFont = font.BaseFont; //cb.MoveText(scale.X(X), yScale); //cb.SetFontAndSize(baseFont, Font.SizeInPoints); //BaseFont baseFont = BaseFont.CreateFont("Helvetica", BaseFont.CP1252, BaseFont.NOT_EMBEDDED); //cb.SetFontAndSize(baseFont, scale.M(new SvgMeasurement(Font.SizeInPoints, E_MeasurementUnits.PT))); //Console.WriteLine("\"FontSize\",{0},{1}", Font.SizeInPoints, scale.M(new SvgMeasurement(Font.SizeInPoints, E_MeasurementUnits.PT))); /* switch ((stroke ? 1 : 0) + (fill ? 2 : 0)) { case 0: // No Stroke or Fill cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_INVISIBLE); break; case 1: // Stroke cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_STROKE); break; case 2: // Fill cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); break; case 3: // Stroke and Fill cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); break; } */ ColumnText ct = new ColumnText(cb); Chunk chk = new Chunk(text, font); float x = scale.X(X); float w = chk.GetWidthPoint(); switch (Justify) { //case SvgJustify.Left: //x=x; //cb.ShowTextAlignedKerned(PdfContentByte.ALIGN_LEFT, Text, scale.X(X), yScale, 0F); //break; case SvgJustify.Center: x-=w/2; //cb.ShowTextAlignedKerned(PdfContentByte.ALIGN_CENTER, Text, scale.X(X), yScale, 0F); break; case SvgJustify.Right: x-=w; //cb.ShowTextAlignedKerned(PdfContentByte.ALIGN_RIGHT, Text, scale.X(X), yScale, 0F); break; } float y = yScale; float xRight = x + w; //float adjustForUnderline = Font.Underline ? Font.Size * .047F / 2 : 0; //float adjustForDescender = font.BaseFont.GetDescentPoint("Almg", font.Size); //float width = font.BaseFont.GetWidthPoint(Text, font.Size); //x -= isCentered ? width / 2 : 0; //xRight = x + font.BaseFont.GetWidthPoint(Text, font.Size) + adjustForUnderline; float Offset = 0; if (Font.Underline) { chk.SetUnderline(new Color(FillColor), 0, 0.047F, 0, -.1373F, PdfContentByte.LINE_CAP_ROUND); } Phrase ph = new Phrase(chk); //Paragraph ph = new Paragraph(chk); ct.SetSimpleColumn(x, y + ph.Leading + Offset, xRight + 1F, y + ph.Leading + Offset - 2 * font.Size); ct.AddElement(ph); cb.SaveState(); cb.SetColorFill(new Color(FillColor)); ct.Go(); cb.RestoreState(); //Console.WriteLine("'{0}',{1},{2},{3},{4}", Text, scale.X(X), yScale, X, Y); //cb.ShowTextKerned(Text); //cb.EndText(); //cb.RestoreState(); } public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { string text = mySvg.OnProcessText(Text); SetupInheritance(myParent.MyInheritedSettings); float yScale = -scale.Y(Y); tmp.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; //cb.MoveTo(0, scale.Y(cb, Y)); //cb.LineTo(500, scale.Y(cb, Y)); //cb.SetColorStroke(Color.BLUE); //cb.Stroke(); tmp.BeginText(); if (fill) tmp.SetColorFill(new Color(FillColor)); if (stroke) { tmp.SetLineWidth(scale.M(OutlineWidth)); tmp.SetColorStroke(new Color(OutlineColor)); } //iTextSharp.text.pdf.ColumnText ct = new ColumnText(cb); //Console.WriteLine("Font['{0}'].IsRegistered = {1}",Font.Name,FontFactory.IsRegistered(Font.Name)); iTextSharp.text.Font font = Svg.GetFont(Font.Name); BaseFont baseFont = font.BaseFont; tmp.MoveText(scale.X(X), yScale); //cb.SetFontAndSize(baseFont, Font.SizeInPoints); //BaseFont baseFont = BaseFont.CreateFont("Helvetica", BaseFont.CP1252, BaseFont.NOT_EMBEDDED); tmp.SetFontAndSize(baseFont, scale.M(new SvgMeasurement(Font.SizeInPoints, E_MeasurementUnits.PT))); //Console.WriteLine("\"FontSize\",{0},{1}", Font.SizeInPoints, scale.M(new SvgMeasurement(Font.SizeInPoints, E_MeasurementUnits.PT))); switch ((stroke ? 1 : 0) + (fill ? 2 : 0)) { case 0: // No Stroke or Fill tmp.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_INVISIBLE); break; case 1: // Stroke tmp.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_STROKE); break; case 2: // Fill tmp.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); break; case 3: // Stroke and Fill tmp.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); break; } tmp.ShowTextKerned(text); tmp.EndText(); tmp.RestoreState(); } } //public class Rtf2iTextSharp : RtfVisualVisitorBase //{ // private IRtfDocument _RtfDoc; // private Paragraph _MyParagraph = new Paragraph(); // // 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(); // 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: // break; // case RtfVisualBreakKind.Page: // break; // case RtfVisualBreakKind.Paragraph: // //_MyParagraph.Add("\r\n"); // 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; // } // } // //private static Dictionary _MyBaseFonts = new Dictionary(); // //private static BaseFont GetBaseFont(string fontName) // //{ // // if (!_MyBaseFonts.ContainsKey(fontName)) // // _MyBaseFonts.Add(fontName, BaseFont.CreateFont(FontFind.FullFileName(fontName), BaseFont.IDENTITY_H, BaseFont.EMBEDDED)); // // return _MyBaseFonts[fontName]; // //} // //private static Dictionary _MyFonts = new Dictionary(); // //private static iTextSharp.text.Font GetFont(string fontName, int size, int style) // //{ // // string key = string.Format("{0}.{1}.{2}", fontName, size, style); // // if (!_MyFonts.ContainsKey(key)) // // _MyFonts.Add(key, new iTextSharp.text.Font(GetBaseFont(fontName), size / 2, style)); // // return _MyFonts[key]; // //} // //protected override void DoVisitText(IRtfVisualText visualText) // //{ // // 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)); // // 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(visualText.Format.ForegroundColor.AsDrawingColor); // // Chunk chk = new Chunk(visualText.Text, font); // // chk.SetBackground(new iTextSharp.text.Color(visualText.Format.BackgroundColor.AsDrawingColor)); // // if (visualText.Format.IsStrikeThrough) // // chk.SetUnderline(iTextSharp.text.Color.BLACK, 0, 0.05F, 0, .3F, PdfContentByte.LINE_CAP_ROUND); // Relative Based upon font size // // if (visualText.Format.IsUnderline) // // chk.SetUnderline(iTextSharp.text.Color.BLACK, 0, 0.05F, 0, -.09F, PdfContentByte.LINE_CAP_ROUND); // Relative Based upon font size // // if (visualText.Format.SuperScript == -1) // // chk.SetTextRise(.45F * chk.Font.Size); // // else if (visualText.Format.SuperScript == 1) // // chk.SetTextRise(-.25F * chk.Font.Size); // // //Console.WriteLine("\"RTF FontSize\",{0},{1}", visualText.Format.FontSize / 2,chk.Font.Size); // // _MyParagraph.Add(chk); // //}// 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 //} public class SvgPageTotal { public SvgPageTotal(System.Drawing.Font myFont, PdfContentByte cb) { _MyFont = myFont; _MyTemplate = cb.CreateTemplate(100, 100); _MyTemplate.BoundingBox= new Rectangle(-20, -20, 100, 100); } private int _PageCount=1; //public int PageCount //{ // get { return _PageCount; } // set { _PageCount = value; } //} private System.Drawing.Font _MyFont; //public System.Drawing.Font MyFont //{ // get { return _MyFont; } // set { _MyFont = value; } //} private PdfTemplate _MyTemplate; public PdfTemplate MyTemplate { get { return _MyTemplate; } } public void Draw() { // Output Page Count _MyTemplate.BeginText(); iTextSharp.text.Font font = Svg.GetFont(_MyFont.Name); BaseFont baseFont = font.BaseFont; _MyTemplate.SetFontAndSize(baseFont,_MyFont.Size); _MyTemplate.SetTextMatrix(0, 0); _MyTemplate.ShowText(_PageCount.ToString()); _MyTemplate.EndText(); } } public class SvgPageHelper : PdfPageEventHelper { private Svg _MySvg; //private Svg _MyNextSvg; public Svg MySvg { //get { return _MyNextSvg; } //set { _MyNextSvg = value; } get { return _MySvg; } set { _MySvg = value; } } private PdfLayer _PageListLayer; public PdfLayer PageListLayer { get { return _PageListLayer; } set { _PageListLayer = value; } } private PdfLayer _WatermarkLayer; public PdfLayer WatermarkLayer { get { return _WatermarkLayer; } set { _WatermarkLayer = value; } } private string _Watermark=string.Empty; public string Watermark { get { return _Watermark; } set { _Watermark = value.ToUpper()=="NONE"?"":value; } } private int _CurrentPageNumber = 0; public int CurrentPageNumber { get { return _CurrentPageNumber; } set { _CurrentPageNumber = value; } } public SvgPageHelper(Svg mySvg) { //_MySvg = _MyNextSvg = mySvg; _MySvg = mySvg; } public SvgPageHelper() { } private int _BGPageOffset = 0; public int BackgroundPageOffset { get { return _BGPageOffset; } set { _BGPageOffset = value; } } //private Regex regexReplaceTokens = new Regex(@"{[^{}]}"); protected virtual string ReplacePageListToken(Match match) { return string.Empty; } public override void OnOpenDocument(PdfWriter writer, Document document) { //base.OnOpenDocument(writer, document); //tmpTotal = writer.DirectContent.CreateTemplate(100, 100); //tmpTotal.BoundingBox = new Rectangle(-20, -20, 100, 100); //PdfContentByte cb = writer.DirectContent; } public override void OnEndPage(PdfWriter writer, Document document) { base.OnEndPage(writer, document); DrawBackground(writer.DirectContentUnder); DrawPageList(writer.DirectContent); DrawWatermark(writer.DirectContentUnder); DrawZoomOMatic(writer.DirectContent); CurrentPageNumber++; } private PdfReader _BackgroundReader = null; public PdfReader BackgroundReader { get { if (_BackgroundReader == null && _BackgroundFile != null && File.Exists(_BackgroundFile)) _BackgroundReader = new PdfReader(_BackgroundFile); return _BackgroundReader; } } private string _BackgroundFile = null; public string BackgroundFile { get { return _BackgroundFile; } set { _BackgroundFile = value; } } private PdfLayer _BackgroundLayer = null; public PdfLayer BackgroundLayer { get { return _BackgroundLayer; } set { _BackgroundLayer = value; } } private System.Drawing.PointF _BackgroundOffset = new System.Drawing.PointF(0, 0); public System.Drawing.PointF BackgroundOffset { get { return _BackgroundOffset; } set { _BackgroundOffset = value; } } public int BackgroundPageCount { get { return BackgroundReader == null ? 0 : BackgroundReader.NumberOfPages; } } private PdfImportedPage GetBackgroundPage(PdfContentByte cb) { if (BackgroundReader == null) return null; int page = CurrentPageNumber + BackgroundPageOffset; if (page < 1 || page > BackgroundPageCount) return null; return cb.PdfWriter.GetImportedPage(BackgroundReader, page); } private void DrawBackground(PdfContentByte cb) { PdfImportedPage backgroundPage = GetBackgroundPage(cb); if (backgroundPage == null) return; if(BackgroundLayer != null) cb.BeginLayer(BackgroundLayer); iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(backgroundPage); image.SetAbsolutePosition(BackgroundOffset.X,BackgroundOffset.Y); cb.AddImage(image); if (BackgroundLayer != null) cb.EndLayer(); } private void DrawZoomOMatic(PdfContentByte cb) { cb.SaveState(); ZoomOMatic(cb, 18); cb.RestoreState(); } private void DrawWatermark(PdfContentByte cb) { if (Watermark.ToLower() == "(none)" || Watermark == "") return; cb.SaveState(); if (_WatermarkLayer != null) cb.BeginLayer(_WatermarkLayer); SvgWatermark myWatermark = new SvgWatermark(cb, Watermark, System.Drawing.Color.Blue, .15F); myWatermark.SetSquareDotPattern(.7F); myWatermark.Draw(); if (_WatermarkLayer != null) cb.EndLayer(); cb.RestoreState(); } private void DrawPageList(PdfContentByte cb) { cb.SaveState(); if (_PageListLayer != null) cb.BeginLayer(_PageListLayer); // Do anything needed to finish off the page _MySvg.Draw(cb); //_MySvg = _MyNextSvg; // After doing to current page update the Svg for the next page. if (_PageListLayer != null) cb.EndLayer(); cb.RestoreState(); } private void ZoomOMatic(PdfContentByte cb, float size) { for (float xx = 0; xx < cb.PdfDocument.PageSize.Width; xx += size) { for (float yy = 0; yy < cb.PdfDocument.PageSize.Height; yy += size) { PdfDestination dest = new PdfDestination(PdfDestination.FITR, xx - 1.5F * size, yy - 1.5F * size, xx + 1.5F * size, yy + 1.5F * size); cb.SetAction(PdfAction.GotoLocalPage(cb.PdfWriter.CurrentPageNumber, dest, cb.PdfWriter), xx - size, yy - size, xx + size, yy + size); } } } //private void DrawRectangle(PdfContentByte cb, float x, float y, float w, float h, Color fill, Color stroke) //{ // cb.SaveState(); // PdfGState gState = new PdfGState(); // gState.StrokeOpacity = .95F; // gState.FillOpacity = .75F; // cb.SetGState(gState); // cb.SetColorFill(fill); // cb.SetLineWidth(1F); // cb.SetColorStroke(stroke); // cb.Rectangle(x, cb.PdfWriter.PageSize.Height - y, w, -h); // cb.FillStroke(); // cb.RestoreState(); //} public override void OnStartPage(PdfWriter writer, Document document) { //base.OnStartPage(writer, document); } public override void OnCloseDocument(PdfWriter writer, Document document) { // Build Templates for Page Count } } public class SvgWatermark { private PdfContentByte _ContentByte; private string _Text; private Color _Color; private PdfPatternPainter _PatternPainter; private BaseFont _Basefont; private float _Fontsize; private float _XOffset; private float _YOffset; private float _TextAngle; private float _Opacity; public SvgWatermark(PdfContentByte contentByte, string text, System.Drawing.Color color, float opacity) { _ContentByte = contentByte; _Text = text; float radius = .5F; float space = 3; _Color = new Color(color); _Opacity = opacity; SetDotPattern(radius, space); SetTextLayout(); } private void SetTextLayout() { Rectangle pageSize = _ContentByte.PdfWriter.PageSize; // Get page size _Basefont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false); float hgtA = _Basefont.GetAscentPoint(_Text, 12); //float hgtD = basefont.GetDescentPoint(text,20); float wid = _Basefont.GetWidthPointKerned(_Text, 12); //Console.WriteLine("{0} {1} {2}",hgtA,hgtD,wid); float rho = wid / hgtA; float x2 = (rho * pageSize.Height - pageSize.Width) / (rho * rho - 1); float y1 = x2 * rho; float y2 = pageSize.Height - y1; float x1 = pageSize.Width - x2; _XOffset = x2 + x1 / 2; _YOffset = y1 / 2; _TextAngle = CalcAngle(y1, x1); _Fontsize = (float)(10 * Math.Sqrt(x2 * x2 + y2 * y2) / hgtA); } public void SetDotPattern(float radius, float space) { _PatternPainter = _ContentByte.CreatePattern(radius * 2, radius * 2, radius * 2 + space, radius * 2 + space); PdfGState gState = new PdfGState(); gState.FillOpacity = _Opacity; _PatternPainter.SetGState(gState); _PatternPainter.SetColorFill(_Color); _PatternPainter.Circle(radius, radius, radius); _PatternPainter.Fill(); } public void SetSquareDotPattern(float radius) { _PatternPainter = _ContentByte.CreatePattern(radius * 4, radius * 2, radius * 4, radius * 2); PdfGState gState = new PdfGState(); gState.FillOpacity = .5f * _Opacity; _PatternPainter.SetGState(gState); _PatternPainter.SetColorFill(_Color); _PatternPainter.Rectangle(0, 0, radius, radius); _PatternPainter.Rectangle(radius * 2, radius, radius, radius); _PatternPainter.Fill(); } public void SetHashPattern(float thickness, float size) { _PatternPainter = _ContentByte.CreatePattern(size, size, size, size); PdfGState gState = new PdfGState(); gState.FillOpacity = _Opacity; gState.StrokeOpacity = _Opacity; _PatternPainter.SetGState(gState); _PatternPainter.SetLineWidth(.01F); _PatternPainter.SetColorStroke(_Color); // Set color _PatternPainter.MoveTo(0, 0); _PatternPainter.LineTo(size, size); _PatternPainter.MoveTo(size, 0); _PatternPainter.LineTo(0, size); _PatternPainter.Stroke(); } public void SetTextPattern(float fontSize, float space) { float hgtA = _Basefont.GetAscentPoint(_Text, fontSize) + _Basefont.GetDescentPoint(_Text, fontSize); float wid = _Basefont.GetWidthPointKerned(_Text, fontSize); _PatternPainter = _ContentByte.CreatePattern(wid, hgtA, wid + space, hgtA + space); _PatternPainter.SetFontAndSize(_Basefont, fontSize); _PatternPainter.BoundingBox = new Rectangle(-20, -20, 100, 100); _PatternPainter.BeginText(); PdfGState gs1 = new PdfGState(); gs1.FillOpacity = _Opacity; _PatternPainter.SetGState(gs1); _PatternPainter.SetColorFill(_Color); // Set color _PatternPainter.ShowText(_Text); _PatternPainter.EndText(); } public void SetTextPattern2(float fontSize) { BaseFont _Basefont2 = BaseFont.CreateFont(BaseFont.HELVETICA, Encoding.ASCII.EncodingName, false); float hgtA = _Basefont2.GetAscentPoint(_Text, fontSize); float wid = _Basefont2.GetWidthPointKerned(_Text, fontSize); _PatternPainter = _ContentByte.CreatePattern(wid * 2, hgtA * 2, wid * 2, hgtA * 2); _PatternPainter.SetFontAndSize(_Basefont2, fontSize); _PatternPainter.BoundingBox = new Rectangle(-20, -20, 100, 100); _PatternPainter.BeginText(); PdfGState gs1 = new PdfGState(); gs1.FillOpacity = _Opacity; _PatternPainter.SetGState(gs1); _PatternPainter.SetColorFill(_Color); // Set color _PatternPainter.ShowText(_Text); _PatternPainter.ShowTextAligned(PdfContentByte.ALIGN_LEFT, _Text, wid, hgtA, 0); _PatternPainter.EndText(); } public void Draw() { _ContentByte.SaveState(); _ContentByte.BeginText(); _ContentByte.SetPatternFill(_PatternPainter); //_ContentByte.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); //_ContentByte.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_STROKE); _ContentByte.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); _ContentByte.SetLineWidth(.5F); _ContentByte.SetFontAndSize(_Basefont, _Fontsize);// Set font and size _ContentByte.SetColorStroke(_Color); PdfGState gs2 = new PdfGState(); gs2.StrokeOpacity = _Opacity; _ContentByte.SetGState(gs2); _ContentByte.ShowTextAlignedKerned(PdfContentByte.ALIGN_CENTER, _Text, _XOffset, _YOffset, _TextAngle);// Draw the text _ContentByte.EndText(); _ContentByte.FillStroke(); // Controlled by TextRenderMode above _ContentByte.RestoreState(); } private float CalcAngle(float opposite, float adjacent) { return (float)(Math.Atan2(opposite, adjacent) * (180 / Math.PI)); } } public enum SvgWatermarkFill { Dots = 1, Text1 = 2, Text2 = 3, Hash = 4 } }