2012-01-10 14:46:05 +00:00

1168 lines
41 KiB
C#

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<string, PdfTemplate> _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<string, PdfTemplate>();
//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<string> _AllowedWatermarks = new List<string>();
public List<string> 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 int _CurrentTOCPageNumber = 0;
public int CurrentTOCPageNumber
{
get { return _CurrentTOCPageNumber; }
set { _CurrentTOCPageNumber = 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 void DrawWatermark(PdfContentByte cb)
{
if (Watermark.ToLower().Contains("none") || Watermark == "") return;
if (!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
}
}