// 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; namespace Spludlow.Drawing { /// /// Creating "Font Books" of fonts in a directory (don't need to be installed) /// /// Create "Unicode Tables" to show all the glyphs (characters) in a font /// /// For fun run: Spludlow.Drawing.FontReports.UnicodeFun(@"D:\OutputDir", false); /// public class FontReports { public static void Book(string fontDirectory) { string targetPdfFilename = fontDirectory + ".pdf"; Book(fontDirectory, targetPdfFilename); } public static void Book(string fontDirectory, string targetPdfFilename) { Book(fontDirectory, targetPdfFilename, true, true); } public static void Book(string fontDirectory, string targetPdfFilename, bool embed, bool unicode) { List filenames = new List(); foreach (string filename in Directory.GetFiles(fontDirectory, "*", SearchOption.AllDirectories)) { string extention = Path.GetExtension(filename).ToLower(); if (extention != ".ttf" && extention != ".otf") continue; filenames.Add(filename); } Book(filenames.ToArray(), targetPdfFilename, embed, unicode); } public static void Book(string[] fontFilenames, string targetPdfFilename, bool embed, bool unicode) { List glyphTypefaceInfos = new List(); foreach (string fontFilename in fontFilenames) { GlyphTypefaceInfo info; try { info = new GlyphTypefaceInfo(fontFilename); } catch (Exception ee) { Spludlow.Log.Error("FontReports, Book; GlyphTypefaceInfo: " + fontFilename, ee); continue; } try { Spludlow.Drawing.PDFFontChest.RegisterFont(info.Name, fontFilename, embed); glyphTypefaceInfos.Add(info); } catch (Exception ee) { Spludlow.Log.Error("FontReports, Book; RegisterFont: " + fontFilename, ee); } } //// Printing normally fails when hitting bad fonts //Spludlow.Printing.PrintDoc doc = new Printing.PrintDoc("A4*", "FontReports Book"); //Book(doc, glyphTypefaceInfos.ToArray(), unicode); //Spludlow.Printing.Printer.Print(doc, "pdf:" + targetPdfFilename); // Print directly to PDF using (Spludlow.Drawing.PDF pdf = new PDF(targetPdfFilename, "A4*")) { Book(pdf, glyphTypefaceInfos.ToArray(), unicode); } } public static void Book(Spludlow.Printing.IPrintDoc doc, GlyphTypefaceInfo[] glyphTypefaceInfos, bool unicode) { int[] pointSizes = new int[] { 9, 24, 48 }; string unicodeMark = ""; if (unicode == true) unicodeMark = "*"; string infoFont = "Courier New, 7"; for (int index = 0; index < glyphTypefaceInfos.Length; ++index) { if (index > 0) doc.NewPage(); GlyphTypefaceInfo info = glyphTypefaceInfos[index]; doc.TextBox(info.ToString(), infoFont, 10, 10, 277, 50, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); doc.Rectangle(10, 10, 277, 50, 1.0F, System.Drawing.Color.Red, System.Drawing.Color.Empty); try { float y = 65.0F; foreach (int pointSize in pointSizes) { string fontInfo = info.Name + unicodeMark + ", " + pointSize; doc.Text(info.Name, fontInfo, 10, y, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); y += pointSize / 2.0F; } float xOffset = 10.0F; float yOffset = 100.0F; float boxWidth = 8.0F; float boxHeight = 8.0F; int columns = 20; for (int id = 30; id < 256; ++id) { DataRow asciiRow = Spludlow.ASCII.Table.Rows[id]; if ((bool)asciiRow["Printable"] == true) { float xBox = xOffset + (id % columns) * boxWidth; float yBox = yOffset + (id / columns) * boxHeight; string asciiString = Char.ConvertFromUtf32(id).ToString(); doc.Text(asciiString, info.Name + unicodeMark + ", 24", xBox + (boxWidth / 2), yBox + (boxHeight / 2), System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Center, 0, System.Drawing.Color.Empty); doc.Rectangle(xBox, yBox, boxWidth, boxHeight, 1, System.Drawing.Color.Black, System.Drawing.Color.Empty); } } } catch (Exception ee) { doc.TextBox(ee.Message, infoFont, 10, 65, 277, 135, System.Drawing.Color.Red, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); doc.Rectangle(10, 65, 277, 135, 1.0F, System.Drawing.Color.Red, System.Drawing.Color.Empty); } } } public static void UnicodeTables(string fontDirectory, string targetDirectory) { foreach (string existingFilename in Directory.GetFiles(targetDirectory, "*.pdf")) File.Delete(existingFilename); foreach (string fontFilename in Directory.GetFiles(fontDirectory, "*", SearchOption.AllDirectories)) { string extention = Path.GetExtension(fontFilename).ToLower(); if (extention != ".ttf" && extention != ".otf") continue; GlyphTypefaceInfo info = new GlyphTypefaceInfo(fontFilename); string targetFilename = targetDirectory + @"\" + Spludlow.Io.Paths.LegalFileName(info.Name) + ".pdf"; targetFilename = Spludlow.Io.Files.UniqueExistingName(targetFilename); UnicodeTable(info, targetFilename); } } public static void UnicodeTable(GlyphTypefaceInfo info, string targetPdfFilename) { Spludlow.Drawing.PDFFontChest.RegisterFont(info.Name, info.Filename, true); // Printing normally fails when hitting bad fonts //Spludlow.Printing.PrintDoc doc = new Printing.PrintDoc("A4*", "FontReports Book"); //UnicodeTable(doc, info); //Spludlow.Printing.Printer.Print(doc, "pdf:" + targetPdfFilename); // Print directly to PDF using (Spludlow.Drawing.PDF pdf = new PDF(targetPdfFilename, "A4*")) { UnicodeTable(pdf, info); } } public static void UnicodeTable(Spludlow.Printing.IPrintDoc doc, GlyphTypefaceInfo info) { string font = info.Name + "*, 24"; DataTable unicodeBlocksTable = Spludlow.Drawing.Unicode.BlocksTable(); string infoFont = "Courier New, 24"; string nameFont = "Courier New, 9"; float step = 10.0F; float halfStep = step / 2; for (int page = 0; page < 0x200; ++page) // 0x1100 { if (page >= 0xD8 && page < 0xE0) continue; if (page > 0) doc.NewPage(); int offset = page * 256; doc.Text(page.ToString(), infoFont, 10, 10, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); for (int id = 0; id < 256; ++id) { float x = 60 + (id % 16) * step; float y = 40 + (id / 16) * step; doc.Rectangle(x, y, step, step, 1.0F, System.Drawing.Color.Red, System.Drawing.Color.Empty); if (id < 16) doc.Text(id.ToString("X"), infoFont, x, 30, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); if ((id % 16) == 0) { doc.Text("0x" + (offset + id).ToString("X6"), infoFont, 10, y, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); if (unicodeBlocksTable != null) { int start = offset + id; DataRow row = unicodeBlocksTable.Rows.Find(start); if (row != null) doc.Text((string)row["BlockName"], nameFont, 220, y, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Near, 0, System.Drawing.Color.Empty); } } int charId = offset + id; string text = Char.ConvertFromUtf32(charId).ToString(); doc.Text(text, font, x + halfStep, y + halfStep, System.Drawing.Color.Black, 0, System.Drawing.StringAlignment.Center, 0, System.Drawing.Color.Empty); } } } public static void UnicodeFun(string directory, bool includeSegoe) { Spludlow.Drawing.PDFFontChest.RegisterDirectory(); int count = 512; UnicodeFun(directory + @"\Greek.pdf", "Arial Bold", count, 0x000390, 0x0003FF); UnicodeFun(directory + @"\Cyrillic.pdf", "Arial Bold", count, 0x000400, 0x00052F); UnicodeFun(directory + @"\Hebrew.pdf", "Arial Bold", count, 0x0005D0, 0x0005EA); UnicodeFun(directory + @"\Arabic.pdf", "Arial Bold", count, 0x000600, 0x0006FF); UnicodeFun(directory + @"\Arabic.pdf", "Arial Bold", count, 0x000600, 0x0006FF); UnicodeFun(directory + @"\Currency.pdf", "Arial Bold", count, 0x0020A0, 0x0020BF); if (includeSegoe == true) { UnicodeFun(directory + @"\Emoji.pdf", "Segoe UI Emoji", count, 0x01F300, 0x01F4FF); UnicodeFun(directory + @"\Ogham.pdf", "Segoe UI Historic", count, 0x001680, 0x00169C); UnicodeFun(directory + @"\Runic.pdf", "Segoe UI Historic", count, 0x0016A0, 0x0016F0); UnicodeFun(directory + @"\Glagolitic.pdf", "Segoe UI Historic", count, 0x002C00, 0x002C5E); UnicodeFun(directory + @"\Coptic.pdf", "Segoe UI Historic", count, 0x002C80, 0x002CEE); UnicodeFun(directory + @"\OldTurkic.pdf", "Segoe UI Historic", count, 0x010C00, 0x010C48); UnicodeFun(directory + @"\Brahmi.pdf", "Segoe UI Historic", count, 0x011000, 0x01106F); UnicodeFun(directory + @"\Cuneiform.pdf", "Segoe UI Historic", count, 0x012000, 0x012398); UnicodeFun(directory + @"\Hieroglyphs.pdf", "Segoe UI Historic", count, 0x013000, 0x01342E); UnicodeFun(directory + @"\TaiXuanJing.pdf", "Segoe UI Symbol", count, 0x01D300, 0x01D356); UnicodeFun(directory + @"\Transport.pdf", "Segoe UI Symbol", count, 0x01F680, 0x01F6D2); } } public static void UnicodeFun(string filename, string fontName, int count, int start, int end) { List fonts = new List(); foreach (int size in new int[] { 16, 24, 28, 32, 48, 64, 128, 196 }) fonts.Add(fontName + "*, " + size.ToString()); Random rand = new Random(); using (Spludlow.Drawing.PDF pdf = new Spludlow.Drawing.PDF(filename, "A4")) { for (int item = 0; item < count; ++item) { float x = rand.Next((int)pdf.Width); float y = rand.Next((int)pdf.Height); string font = fonts[rand.Next(fonts.Count)]; int charId = start + rand.Next((end - start) + 1); string text = Char.ConvertFromUtf32(charId).ToString(); float angle = rand.Next(360); System.Drawing.Color color = Spludlow.Drawing.Colour.FromHSV(rand.Next(360), 1, 1); pdf.Text(text, font, x, y, System.Drawing.Color.White, angle, System.Drawing.StringAlignment.Center, 2, System.Drawing.Color.Black); pdf.Text(text, font, x, y, color, angle, System.Drawing.StringAlignment.Center, 0, System.Drawing.Color.Empty); } } } } }