Skip to content

Commit

Permalink
ported to System.Drawing for better pixel rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
HellGate94 committed Feb 23, 2024
1 parent 011e754 commit 471c572
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 26 deletions.
1 change: 1 addition & 0 deletions FontToCpp/FontToCpp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<ItemGroup>
<PackageReference Include="DotMake.CommandLine" Version="1.8.1" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.1" />
<PackageReference Include="System.Drawing.Common" Version="8.0.2" />
</ItemGroup>

</Project>
63 changes: 37 additions & 26 deletions FontToCpp/MakeFontCommand.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using DotMake.CommandLine;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.Versioning;
using System.Text;

namespace FontToCpp;

[CliCommand]
[SupportedOSPlatform("windows")]
public class MakeFontCommand {
[CliArgument(Description = "Font Name or Path to Font")]
public string Font { get; set; }
Expand All @@ -30,25 +30,36 @@ public class MakeFontCommand {

[CliOption(Description = "Alphabet")]
public string Alphabet { get; set; } = """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~""";

public void Run() {
if (!SystemFonts.TryGet(Font, out var family)) {
var fontfam = FontFamily.Families
.Where(c => c.Name == Font)
.FirstOrDefault();

Font font;

if (fontfam is null) {
if (!File.Exists(Font)) {
throw new FileNotFoundException("Could not find Font", Font);
}
FontCollection collection = new();
family = collection.Add(Font);

var myFonts = new PrivateFontCollection();
myFonts.AddFontFile(Font);
font = new Font(myFonts.Families[0], Size, Style, GraphicsUnit.Pixel);
} else {
font = new Font(fontfam, Size, Style, GraphicsUnit.Pixel);
}
var font = family.CreateFont(Size, Style);
TextOptions options = new(font) {
KerningMode = KerningMode.None,
};

FontRectangle maxSize = FontRectangle.Empty;
foreach (var c in Alphabet) {
var cs = TextMeasurer.MeasureAdvance(c.ToString(), options);
maxSize = FontRectangle.Union(maxSize, cs);
SizeF maxSizeF = SizeF.Empty;

using (var image = new Bitmap(1, 1)) {
using var g = Graphics.FromImage(image);
foreach (var c in Alphabet) {
var cs = g.MeasureString(c.ToString(), font);
maxSizeF = new(Math.Max(maxSizeF.Width, cs.Width), Math.Max(maxSizeF.Height, cs.Height));
}
}
Size maxSize = new((int)maxSizeF.Width, (int)maxSizeF.Height);
Console.WriteLine($"Font '{font.Name}' with Style '{Style}' of Size '{Size}' has the Dimensions: ({maxSize.Width}, {maxSize.Height})");

string fontName = FontSourceName ?? $"{font.Name.Replace(" ", "")}{Size}";
Expand All @@ -61,17 +72,17 @@ public void Run() {
sb.AppendLine("{");

Console.Write("Processing: ");
Image<L8> img = new((int)maxSize.Width, (int)maxSize.Height);
using Bitmap img = new((int)maxSize.Width, (int)maxSize.Height);
using Graphics context = Graphics.FromImage(img);
context.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
int index = 0;
foreach (var c in Alphabet) {
var str = c.ToString();
Console.Write(str);
var cs = TextMeasurer.MeasureAdvance(str, options);
img.Mutate((context) => {
context.Clear(Color.Black);
context.DrawText(str, font, Color.White, new(0, 0));
});

var cs = context.MeasureString(c.ToString(), font);
context.Clear(Color.Black);
context.DrawString(str, font, Brushes.White, 0, 0);

var bits = EncodeToBits(img);

sb.AppendLine($" // @{bits.Length * index} '{c}' ({img.Width} pixels wide)");
Expand All @@ -95,7 +106,7 @@ public void Run() {
Console.WriteLine("Done.");
}

private byte[] EncodeToBits(Image<L8> img) {
private byte[] EncodeToBits(Bitmap img) {
// Calculate image dimensions
int width = img.Width;
int height = img.Height;
Expand All @@ -114,7 +125,7 @@ private byte[] EncodeToBits(Image<L8> img) {
int bit_position = 7 - (x % 8);

// Extract pixel value from the glyph data
byte pixel_value = img[x, y].PackedValue;
byte pixel_value = img.GetPixel(x, y).R;

// Set or clear the corresponding bit in the font table byte
if (pixel_value > Threshold) {
Expand Down

0 comments on commit 471c572

Please sign in to comment.