using System; using System.Collections; using System.Text; using System.Collections.Generic; 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.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; } public static void RegisterFont(string fontName) { if (!iTextSharp.text.FontFactory.IsRegistered(fontName)) { //foreach (string name in FontKey.GetValueNames()) //{ // if (name.StartsWith(fontName)) // { // string fontFile = (string)FontKey.GetValue(name); // iTextSharp.text.FontFactory.Register(fontFile.Contains("\\") ? fontFile : FontFolder + "\\" + fontFile); // } //} iTextSharp.text.FontFactory.RegisterDirectories(); } } 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; } } public static iTextSharp.text.Font GetFont(string fontName, int size, int style) { RegisterFont(fontName); return iTextSharp.text.FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size / 2, style); } public static iTextSharp.text.Font GetFont(System.Drawing.Font font) // fontName, int size, int style) { RegisterFont(font.Name); int style = (font.Bold ? iTextSharp.text.Font.BOLD : 0) + (font.Italic ? iTextSharp.text.Font.ITALIC : 0); return iTextSharp.text.FontFactory.GetFont(font.Name, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, font.Size, style); } } 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; } } private SvgText _MySvgText; public SvgText MySvgText { get { return _MySvgText; } set { _MySvgText = value; } } private SvgScale _MySvgScale; public SvgScale MySvgScale { get { return _MySvgScale; } set { _MySvgScale = value; } } public SvgProcessTextArgs(string myText, SvgText mySvgText, SvgScale mySvgScale) { _MyText = myText; _MySvgText = mySvgText; _MySvgScale = mySvgScale; } } public partial class Svg : SvgGroup { public void DrawMacro(string macroDef, float x, float y, PdfContentByte cb) { _MyContentByte = cb; SvgMeasurement X = new SvgMeasurement(x, E_MeasurementUnits.PT); SvgMeasurement Y = new SvgMeasurement(Height.GetSizeInPoints(72) - y, E_MeasurementUnits.PT); if (!this.LookUp.ContainsKey(macroDef)) return; // AEP - DU1 (missing C22 macro for AEP) 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, SvgText mySvgText, SvgScale scale) { if (ProcessText != null) return ProcessText(this, new SvgProcessTextArgs(myText, mySvgText, scale)); 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); } 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); } public static iTextSharp.text.Font GetFont(string fontName, float size, int style, System.Drawing.Color color) { RegisterFont(fontName); return FontFactory.GetFont(fontName, size, style, new iTextSharp.text.Color(color)); } 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 { private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { // TODO: Could I use the template SetupInheritance(myParent.MyInheritedSettings); if (mySvg.LookUp.ContainsKey(_UseID)) mySvg[_UseID].Draw(cb, scale.AdjustOrigin(X, Y), mySvg, this); else { _MyLog.WarnFormat("Missing Macro '{0}'", _UseID); } //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); if (Height.Value != 0) img.ScaleAbsoluteHeight(scale.M(Height)); if (Width.Value != 0) img.ScaleAbsoluteWidth(scale.M(Width)); img.SetAbsolutePosition(scale.X(X), scale.Y(cb, Y) - scale.M(img.ScaledHeight)); // The next three lines set the image opacity for testing //PdfGState gState = new PdfGState(); //gState.FillOpacity = .2f; //cb.SetGState(gState); 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(LineWidth.Value); cb.SetColorStroke(new Color(LineColor)); } cb.SetLineCap(PdfContentByte.LINE_CAP_ROUND); if (myParent is SvgGroup && (myParent as SvgGroup).Description.ToUpper() == "ABSOLUTE") { cb.MoveTo(scale.AbsX(X1), scale.AbsY(cb, Y1)); cb.LineTo(scale.AbsX(X2), scale.AbsY(cb, Y2)); } else { cb.MoveTo(scale.X(X1), scale.Y(cb, Y1)); cb.LineTo(scale.X(X2), scale.Y(cb, Y2)); } 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)); 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)); } if (myParent is SvgGroup && (myParent as SvgGroup).Description.ToUpper() == "ABSOLUTE") cb.RoundRectangle(scale.AbsX(X), scale.AbsY(cb, Y), scale.M(Width), -scale.M(Height), .005F); else cb.RoundRectangle(scale.X(X), scale.Y(cb, Y), scale.M(Width), -scale.M(Height), .005F); 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)); 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 SvgText : SvgShapePart { private static string ReplaceSpecialCharacter(Match m) { int i = int.Parse(m.ToString().Substring(2, m.ToString().Length - 3)); char c = (char)i; return c.ToString(); } private static string ReplaceHexCharacter(Match m) { int i = int.Parse(m.ToString().Substring(2, 2), System.Globalization.NumberStyles.HexNumber); char c = (char)i; return c.ToString(); } public int Align { get { switch (Justify) { case SvgJustify.Left: return Element.ALIGN_LEFT; break; case SvgJustify.Center: return Element.ALIGN_CENTER; break; case SvgJustify.Right: return Element.ALIGN_RIGHT; break; } return Element.ALIGN_LEFT; } } // Draw's using PdfContentByte are for drawing PageList items. public override void Draw(PdfContentByte cb, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { string text = mySvg.OnProcessText(Text, this, scale); if (text == string.Empty) return; SetupInheritance(myParent.MyInheritedSettings); float yScale = (myParent is SvgGroup && (myParent as SvgGroup).Description.ToUpper() == "ABSOLUTE") ? scale.AbsY(cb, Y): scale.Y(cb, Y); cb.SaveState(); bool fill = FillColor != System.Drawing.Color.Transparent; bool stroke = OutlineWidth.Value != 0F && OutlineColor != System.Drawing.Color.Empty; // Strip out inline commands that are overridden by the fontStyle if (Font.Bold) text = StripCommands(text, @"\\b0", @"\\b"); if (Font.Italic) text = StripCommands(text, @"\\i0", @"\\i"); if (Font.Underline) text = StripCommands(text, @"\\ulnone", @"\\ul0", @"\\ul"); float fontSize = scale.M(new SvgMeasurement(Font.SizeInPoints, E_MeasurementUnits.PT)); int fontStyle = (Font.Bold ? iTextSharp.text.Font.BOLD : 0) + (Font.Italic ? iTextSharp.text.Font.ITALIC : 0); VolianPdf.RegisterFont(Font.Name); //if (iTextSharp.text.FontFactory.IsRegistered(Font.Name) == false) //{ // //iTextSharp.text.FontFactory.RegisterDirectories(); //} iTextSharp.text.Font font = FontFactory.GetFont(Font.Name, BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor)); Phrase ph = BuildPhrase(text, fontSize, fontStyle, font); ColumnText ct = new ColumnText(cb); float x = (myParent is SvgGroup && (myParent as SvgGroup).Description.ToUpper() == "ABSOLUTE") ? scale.AbsX(X): scale.X(X); float w = 0; // chk.GetWidthPoint(); foreach (Chunk chk in ph.Chunks) w += chk.GetWidthPoint(); switch (Justify) { //case SvgJustify.Left: // x = x; // break; case SvgJustify.Center: x-=w/2; break; case SvgJustify.Right: x-=w; break; } float y = yScale; float xRight = x + w; float Offset = 0; if (Font.Underline) { foreach (Chunk chk in ph.Chunks) chk.SetUnderline(new Color(FillColor), 0, 0.047F, 0, -.1373F, PdfContentByte.LINE_CAP_ROUND); } // The following line was changed so that a 6.5 size font would print, i.e. the 2 was changed to a 3 to make the // 6.5 size work. ct.SetSimpleColumn(x, y + ph.Leading + Offset, xRight + 1F, y + ph.Leading + Offset - 3 * font.Size);//2 * font.Size); ct.AddElement(ph); cb.SaveState(); cb.SetColorFill(new Color(FillColor)); ct.Go(); cb.RestoreState(); } private Phrase BuildPhrase(string text, float fontSize, int fontStyle, iTextSharp.text.Font font) { //if (text == "Caution") //{ // if (iTextSharp.text.FontFactory.IsRegistered("VolianScript")) // Console.WriteLine("Is Registered"); // Console.WriteLine("stop"); //} bool fontUnderline = false; float fontTextRise = 0; text = Regex.Replace(text, @"\\u[0-9]+[?]", new MatchEvaluator(ReplaceSpecialCharacter)); text = Regex.Replace(text, @"\\'[0-9a-fA-F][0-9a-fA-F]", new MatchEvaluator(ReplaceHexCharacter)); text += " "; Phrase ph = new Phrase(); while (text.Length > 0) { string next = ""; Match m = Regex.Match(text, @"\\[^ ]*?[ $]"); if (m.Success) { // text is portion of text and next is remaining portion to process next next = text.Substring(m.Index + m.Length); text = text.Substring(0, m.Index); } else if (text[text.Length - 1] == ' ') text = text.Substring(0, text.Length - 1); foreach (Chunk chk in BuildPartialPhrase(text, fontSize, fontStyle, font).Chunks) { if (fontUnderline) chk.SetUnderline(font.Color, 0, 0.05F, 0, -.131F, PdfContentByte.LINE_CAP_ROUND); if (fontTextRise != 0) chk.SetTextRise(fontTextRise * chk.Font.Size); ph.Add(chk); } if (m.Success) { // bold, underline, italics, subscript, superscript if (m.Value.Contains(@"\ulnone") || m.Value.Contains(@"\ul0")) // off fontUnderline = false; else if (m.Value.Contains(@"\ul")) fontUnderline = true; if (m.Value.Contains(@"\up0") || m.Value.Contains(@"\dn0")) fontTextRise = 0; else if (m.Value.Contains(@"\up")) fontTextRise = .25F; else if (m.Value.Contains(@"\dn")) fontTextRise = -.25F; if (m.Value.Contains(@"\b0")) { fontStyle ^= iTextSharp.text.Font.BOLD; font = FontFactory.GetFont(font.Familyname, BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor)); } else if (m.Value.Contains(@"\b")) { fontStyle |= iTextSharp.text.Font.BOLD; font = FontFactory.GetFont(font.Familyname, BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor)); } if (m.Value.Contains(@"\i0")) { fontStyle ^= iTextSharp.text.Font.ITALIC; font = FontFactory.GetFont(font.Familyname, BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor)); } else if (m.Value.Contains(@"\i")) { fontStyle |= iTextSharp.text.Font.ITALIC; font = FontFactory.GetFont(font.Familyname, BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor)); } } text = next; } return ph; } private Phrase BuildPartialPhrase(string text, float fontSize, int fontStyle, iTextSharp.text.Font font) { iTextSharp.text.pdf.FontSelector fs = new FontSelector(); fs.AddFont(font); if (font.BaseFont != null && font.BaseFont.GetWidthPoint("m", 12) == font.BaseFont.GetWidthPoint(".", 12)) { VolianPdf.RegisterFont("VESymbFix"); fs.AddFont(FontFactory.GetFont("VESymbFix", BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor))); } else { VolianPdf.RegisterFont("Arial Unicode MS"); fs.AddFont(FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, true, fontSize, fontStyle, new Color(FillColor))); } Phrase ph = fs.Process(text); return ph; } private string StripCommands(string text, params string [] rtfCommands) { foreach (string rtfCommand in rtfCommands) { // remove rtf command preceeded by another rtf command with previous // rtf ending with a space, i.e. "\ulnone\b0 " removing the "b0", leaves " " // * - as many as there are, ? - minimum number that results in a match text = Regex.Replace(text, @"(\\[^ ]*?)" + rtfCommand + " ", "$1 "); // remove rtf command follwed by a space text = Regex.Replace(text, rtfCommand + " ", ""); // remove just the rtf command text = Regex.Replace(text, rtfCommand, ""); } return text; } // Draw's using PdfTemplate are for drawing SVG (16-bit genmac). public override void Draw(PdfTemplate tmp, SvgScale scale, Svg mySvg, SvgPartInheritance myParent) { string text = mySvg.OnProcessText(Text, this, scale); if (text == string.Empty) return; 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; tmp.BeginText(); if (fill) tmp.SetColorFill(new Color(FillColor)); if (stroke) { tmp.SetLineWidth(scale.M(OutlineWidth)); tmp.SetColorStroke(new Color(OutlineColor)); } iTextSharp.text.Font font = Svg.GetFont(Font.Name); BaseFont baseFont = font.BaseFont; tmp.MoveText(scale.X(X), yScale); tmp.SetFontAndSize(baseFont, 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 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; private System.Drawing.Font _MyFont; 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 List _AllowedWatermarks = new List(); public List AllowedWatermarks { get { return _AllowedWatermarks; } set { _AllowedWatermarks = value; } } private Svg _MySvg; public Svg MySvg { 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; } } private bool _DoZoomOMatic = false; public bool DoZoomOMatic { get { return _DoZoomOMatic; } set { _DoZoomOMatic = value; } } private int _CurrentPageNumber = 0; public int CurrentPageNumber { get { return _CurrentPageNumber; } set { _CurrentPageNumber = value; } } private bool _OnFoldoutPage = false; public bool OnFoldoutPage { get { return _OnFoldoutPage; } set { _OnFoldoutPage = value; } } private bool _CreatingFoldoutPage = false; public bool CreatingFoldoutPage { get { return _CreatingFoldoutPage; } set { _CreatingFoldoutPage = value; } } public SvgPageHelper(Svg mySvg) { _MySvg = mySvg; } public SvgPageHelper() { } private int _BGPageOffset = 0; public int BackgroundPageOffset { get { return _BGPageOffset; } set { _BGPageOffset = value; } } 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) { if (!OnFoldoutPage) { base.OnEndPage(writer, document); if (!CreatingFoldoutPage) { DrawBackground(writer.DirectContentUnder); DrawPageList(writer.DirectContent); DrawWatermark(writer.DirectContentUnder); if (DoZoomOMatic) DrawZoomOMatic(writer.DirectContent); } CurrentPageNumber++; } else { if (!CreatingFoldoutPage) { DrawBackground(writer.DirectContentUnder); DrawPageList(writer.DirectContent); DrawWatermark(writer.DirectContentUnder); if (DoZoomOMatic) 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 = cb.PdfWriter.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, 36); cb.RestoreState(); } private bool _AllowAllWatermarks = false; public bool AllowAllWatermarks { get { return _AllowAllWatermarks; } set { _AllowAllWatermarks = value; } } private void DrawWatermark(PdfContentByte cb) { if (Watermark == null || Watermark.ToLower().Contains("none") || Watermark == "") return; if (!AllowAllWatermarks && !AllowedWatermarks.Contains(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) { if (_MySvg != null) { cb.SaveState(); if (_PageListLayer != null) cb.BeginLayer(_PageListLayer); // Do anything needed to finish off the page _MySvg.Draw(cb); 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); } } } 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_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 } }