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