// Spludlow Software
// Copyright © Samuel P. Ludlow 2020 All Rights Reserved
// Distributed under the terms of the GNU General Public License version 3
// Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
// https://www.spludlow.co.uk/LICENCE.TXT
// The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission
// v1.14
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Reflection;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace Spludlow.Drawing
{
///
/// Keep cache of created font objects
/// Provides lookup for font conversions for the 'Postscipt standard 14'
///
public class PDFFontChest
{
private static Dictionary Fonts;
private static List EmbeddedFonts;
private static List BuiltInFonts;
private static Dictionary FontConversions;
static PDFFontChest()
{
Fonts = new Dictionary();
EmbeddedFonts = new List();
BuiltInFonts = new List(new string[]
{
"Courier",
"Courier-Bold",
"Courier-Oblique",
"Courier-BoldOblique",
"Helvetica",
"Helvetica-Bold",
"Helvetica-Oblique",
"Helvetica-BoldOblique",
"Symbol",
"Times-Roman",
"Times-Bold",
"Times-Italic",
"Times-BoldItalic",
"ZapfDingbats",
});
FontConversions = new Dictionary();
FontConversions.Add("Courier New", "Courier");
FontConversions.Add("Courier New, Bold", "Courier-Bold");
FontConversions.Add("Courier New, Italic", "Courier-Oblique");
FontConversions.Add("Courier New, Bold, Italic", "Courier-BoldOblique");
FontConversions.Add("Courier New Bold", "Courier-Bold");
FontConversions.Add("Courier New Italic", "Courier-Oblique");
FontConversions.Add("Courier New Bold Italic", "Courier-BoldOblique");
FontConversions.Add("Arial", "Helvetica");
FontConversions.Add("Arial, Bold", "Helvetica-Bold");
FontConversions.Add("Arial, Italic", "Helvetica-Oblique");
FontConversions.Add("Arial, Bold, Italic", "Helvetica-BoldOblique");
FontConversions.Add("Arial Bold", "Helvetica-Bold");
FontConversions.Add("Arial Italic", "Helvetica-Oblique");
FontConversions.Add("Arial Bold Italic", "Helvetica-BoldOblique");
FontConversions.Add("Times New Roman", "Times-Roman");
FontConversions.Add("Times New Roman, Bold", "Times-Bold");
FontConversions.Add("Times New Roman, Italic", "Times-Italic");
FontConversions.Add("Times New Roman, Bold, Italic", "Times-BoldItalic");
FontConversions.Add("Times New Roman Bold", "Times-Bold");
FontConversions.Add("Times New Roman Italic", "Times-Italic");
FontConversions.Add("Times New Roman Bold Italic", "Times-BoldItalic");
}
public static void RegisterDirectory()
{
RegisterDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Fonts));
}
public static void RegisterDirectory(string directory)
{
FontFactory.RegisterDirectory(directory);
}
//public static void RegisterFont(string fontName, bool embed)
//{
//}
public static void RegisterFont(string fontName, string fontFilename, bool embed)
{
if (FontFactory.IsRegistered(fontName) == true)
return;
if (fontFilename.Contains(@"\") == false)
fontFilename = Environment.GetFolderPath(Environment.SpecialFolder.Fonts) + @"\" + fontFilename;
if (File.Exists(fontFilename) == false)
throw new ApplicationException("PDFFontChest RegisterFont; File not found: " + fontFilename);
FontFactory.Register(fontFilename);
//Font font = FontFactory.GetFont(fontName, BaseFont.CP1252, embed, 9.0F);
//if (font == null || font.BaseFont == null)
// throw new ApplicationException("PDFFontChest RegisterFont; Did not register: " + fontName + ", " + fontFilename);
if (embed == true)
{
lock (EmbeddedFonts)
{
if (EmbeddedFonts.Contains(fontName) == false)
EmbeddedFonts.Add(fontName);
}
}
}
public static string[] RegisteredFonts()
{
List fontNames = new List();
foreach (string fontName in FontFactory.RegisteredFonts)
fontNames.Add(fontName);
return fontNames.ToArray();
}
// CP1250 Windows Eastern European Microsoft Windows to represent texts in Central European and Eastern European languages that use Latin script shows custom in adobe reader
// CP1252 Windows Latin-1 Microsoft Windows legacy components of in English and some other Western languages (superset of ISO 8859-1 "Latin 1") USE THIS !!!!!!!! shows ANSI in adobe reader
// CP1257 Windows Baltic Microsoft Windows Baltic used to support the Estonian, Latvian and Lithuanian languages
// IDENTITY_H Unicode
// IDENTITY_V
public static Font GetFont(string fontInfoText)
{
// Only need locks on writes?
lock (Fonts)
{
if (Fonts.ContainsKey(fontInfoText) == true)
return Fonts[fontInfoText];
}
Spludlow.Drawing.FontInfo fontInfo = new FontInfo(fontInfoText);
string fontNameWithStyle = fontInfo.NameWithStyle(); // Coversions for PDF Built in postscript fonts
if (FontConversions.ContainsKey(fontNameWithStyle) == true && FontFactory.IsRegistered(fontInfo.Name) == false)
{
fontInfo.RemoveBoldItalic();
fontInfo.Name = FontConversions[fontNameWithStyle];
}
int fontStyle = ParseFontStyles(fontInfo.FontStyles);
Font font;
if (BuiltInFonts.Contains(fontInfo.Name) == true)
{
BaseFont baseFont = BaseFont.CreateFont(fontInfo.Name, BaseFont.CP1252, false);
font = new Font(baseFont, fontInfo.Size, fontStyle);
}
else
{
bool embed = false;
lock (EmbeddedFonts)
{
embed = EmbeddedFonts.Contains(fontInfo.Name);
}
string encoding = BaseFont.CP1252;
if (fontInfo.UniCode == true)
encoding = BaseFont.IDENTITY_H;
font = FontFactory.GetFont(fontInfo.Name, encoding, embed, fontInfo.Size, fontStyle); // IDENTITY_H forcing embedding
}
if (font == null || font.BaseFont == null) //.Familyname == "unknown")
throw new ApplicationException("PDFFontChest GetFont; Can't get font, have you registered it? : " + fontInfo.Name);
lock (Fonts)
{
Fonts.Add(fontInfoText, font);
return Fonts[fontInfoText];
}
}
public static int ParseFontStyles(System.Drawing.FontStyle fontStyle)
{
int result = 0;
foreach (string styleNname in Enum.GetNames(typeof(System.Drawing.FontStyle)))
{
System.Drawing.FontStyle testStyle = (System.Drawing.FontStyle)Enum.Parse(typeof(System.Drawing.FontStyle), styleNname);
if (testStyle == System.Drawing.FontStyle.Regular)
continue;
if (fontStyle.HasFlag(testStyle) == true)
result |= ParseFontStyle(styleNname);
}
return result;
}
public static int ParseFontStyle(string text)
{
text = text.ToUpper();
if (text == "STRIKEOUT")
text = "STRIKETHRU";
Type type = typeof(Font);
return (int)type.InvokeMember(text, BindingFlags.GetField, null, type, null);
}
public static string ParseFontName(string text) // Get propper name from lowercase name
{
text = text.ToUpper().Replace("-", "_");
Type type = typeof(BaseFont);
return (string)type.InvokeMember(text, BindingFlags.GetField, null, type, null);
}
}
}