// 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); } } }