PixFont.cs
namespace PixelPusher;
public static class PixFont
{
public static void Draw( Color32[] buf, int bw, int bh, int x, int y, string text, Color32 color, int scale = 1 )
{
if ( buf is null || string.IsNullOrEmpty( text ) )
return;
scale = Math.Max( 1, scale );
var cx = x;
foreach ( var ch in text.ToUpperInvariant() )
{
if ( ch == '\n' )
{
cx = x;
y += (5 + 1) * scale;
continue;
}
if ( Glyphs.TryGetValue( ch, out var bits ) )
Blit( buf, bw, bh, cx, y, bits, color, scale );
cx += (3 + 1) * scale;
}
}
public static int Width( string text, int scale = 1 )
{
if ( string.IsNullOrEmpty( text ) )
return 0;
var lines = text.Split( '\n' );
var max = 0;
foreach ( var line in lines )
max = Math.Max( max, line.Length );
return max * 4 * Math.Max( 1, scale );
}
static void Blit( Color32[] buf, int bw, int bh, int x, int y, ushort bits, Color32 color, int scale )
{
for ( var row = 0; row < 5; row++ )
for ( var col = 0; col < 3; col++ )
{
if ( (bits & (1 << (row * 3 + col))) == 0 )
continue;
for ( var sy = 0; sy < scale; sy++ )
for ( var sx = 0; sx < scale; sx++ )
{
var px = x + col * scale + sx;
var py = y + row * scale + sy;
if ( (uint)px >= (uint)bw || (uint)py >= (uint)bh )
continue;
buf[py * bw + px] = color;
}
}
}
static ushort Pack( string a, string b, string c, string d, string e )
{
ushort bits = 0;
void Row( string s, int r )
{
for ( var i = 0; i < 3; i++ )
{
if ( i < s.Length && s[i] == '#' )
bits |= (ushort)(1 << (r * 3 + i));
}
}
Row( a, 0 );
Row( b, 1 );
Row( c, 2 );
Row( d, 3 );
Row( e, 4 );
return bits;
}
static readonly Dictionary<char, ushort> Glyphs = Build();
static Dictionary<char, ushort> Build()
{
var g = new Dictionary<char, ushort>
{
[' '] = 0,
['0'] = Pack( "###", "# #", "# #", "# #", "###" ),
['1'] = Pack( " # ", "## ", " # ", " # ", "###" ),
['2'] = Pack( "###", " #", "###", "# ", "###" ),
['3'] = Pack( "###", " #", "###", " #", "###" ),
['4'] = Pack( "# #", "# #", "###", " #", " #" ),
['5'] = Pack( "###", "# ", "###", " #", "###" ),
['6'] = Pack( "###", "# ", "###", "# #", "###" ),
['7'] = Pack( "###", " #", " # ", " # ", " # " ),
['8'] = Pack( "###", "# #", "###", "# #", "###" ),
['9'] = Pack( "###", "# #", "###", " #", "###" ),
['A'] = Pack( " # ", "# #", "###", "# #", "# #" ),
['B'] = Pack( "## ", "# #", "## ", "# #", "## " ),
['C'] = Pack( " ##", "# ", "# ", "# ", " ##" ),
['D'] = Pack( "## ", "# #", "# #", "# #", "## " ),
['E'] = Pack( "###", "# ", "## ", "# ", "###" ),
['F'] = Pack( "###", "# ", "## ", "# ", "# " ),
['G'] = Pack( " ##", "# ", "# #", "# #", " ##" ),
['H'] = Pack( "# #", "# #", "###", "# #", "# #" ),
['I'] = Pack( "###", " # ", " # ", " # ", "###" ),
['J'] = Pack( "###", " #", " #", "# #", " # " ),
['K'] = Pack( "# #", "# #", "## ", "# #", "# #" ),
['L'] = Pack( "# ", "# ", "# ", "# ", "###" ),
['M'] = Pack( "# #", "###", "###", "# #", "# #" ),
['N'] = Pack( "# #", "###", "###", "###", "# #" ),
['O'] = Pack( " # ", "# #", "# #", "# #", " # " ),
['P'] = Pack( "## ", "# #", "## ", "# ", "# " ),
['Q'] = Pack( " # ", "# #", "# #", " ##", " #" ),
['R'] = Pack( "## ", "# #", "## ", "# #", "# #" ),
['S'] = Pack( " ##", "# ", " # ", " #", "## " ),
['T'] = Pack( "###", " # ", " # ", " # ", " # " ),
['U'] = Pack( "# #", "# #", "# #", "# #", "###" ),
['V'] = Pack( "# #", "# #", "# #", "# #", " # " ),
['W'] = Pack( "# #", "# #", "###", "###", "# #" ),
['X'] = Pack( "# #", "# #", " # ", "# #", "# #" ),
['Y'] = Pack( "# #", "# #", " # ", " # ", " # " ),
['Z'] = Pack( "###", " #", " # ", "# ", "###" ),
['.'] = Pack( " ", " ", " ", " ", " # " ),
[','] = Pack( " ", " ", " ", " # ", "# " ),
[':'] = Pack( " ", " # ", " ", " # ", " " ),
['-'] = Pack( " ", " ", "###", " ", " " ),
['+'] = Pack( " ", " # ", "###", " # ", " " ),
['!'] = Pack( " # ", " # ", " # ", " ", " # " ),
['?'] = Pack( "## ", " #", " # ", " ", " # " ),
['/'] = Pack( " #", " #", " # ", "# ", "# " ),
['·'] = Pack( " ", " ", " # ", " ", " " ),
['\''] = Pack( " # ", " # ", " ", " ", " " )
};
return g;
}
}