Skip to content

Repository files navigation

3x5 Microfont

A Highly Legible 3x5 Pixel Font With Full ASCII Support

A demo of every ASCII character.

A Spanish pangram.

A Greek pangram.

Itch.io Page

Examples

Sample Images

A strange headline about undead horse terrorists and baby zebra surgery.

(Contains all uppercase and lowercase letters.)

Angry Buzzing Citizens Denounced Equine Federal Government Hijackers In July, Keeping Local Militias Near Our Public Quarters, Rapidly Silencing Toxic Underworld Violence Without Xenografting Young Zebras.


The poem "Ozymandias" by Percy Bysshe Shelley.

The poem "Ozymandias" by Percy Bysshe Shelley.


A standard "Hello, World!" program written in C.

A standard "Hello, World!" program written in C.


The poem "The Road Not Taken" by Robert Frost.

The poem "The Road Not Taken" by Robert Frost.


ASCII art of my logo.

ASCII art of my logo.

Bitmap Fonts (Sprite Sheets)

Two different formats of bitmap font are provided:

  • Microfont_1D is a simple format that has one long row of all 128 ASCII characters laid out left-to-right.
  • Microfont_2D is a more complex format that has the 128 ASCII characters laid out in 8 rows of 16. They are laid out left-to-right, top-to-bottom (like English text).

How To Use The Sprite Sheets

Calculating Glyph Position

The layout of the sprite sheets has been optimized to make converting from an ASCII character code to X and Y coordinates extremely simple.

All characters are 3 pixels wide by 5 pixels tall. The X and Y coordinates calculated below are for the top left corner of the desired glyph. So the full bounding box for any glyph is:

left = x
right = x + 3
top = y
bottom = y + 5

1D Calculations

These calculations work for Microfont_1D.png and are probably the simplest to do. The X coordinate is directly related to the full ASCII character code.

x = get_ascii_code(character) * 3
y = 0

2D Calculations

These calculations work for Microfont_2D.png. While they are slightly more complex, they allow for the sprite sheet to be a more reasonable aspect ratio. The X coordinate is based on the low nibble of the character code and the Y coordinate is based on the high nibble.

x = (get_ascii_code(character) & 0b1111) * 3
y = (get_ascii_code(character) >> 4) * 5

Vector Fonts (TrueType / WOFF / WOFF2)

Thanks to the freeware program PixelForge, I was able to create two different versions of this bitmap font in .ttf format! And thanks to fontTools for Python, I was able to convert those into .woff and .woff2 fonts, which are more suitable for web usage.

Two different font styles are provided:


How To Use The Vector Fonts

Optimal Text Sizes

Because the height of the characters is 5 pixels with 1 pixel between rows, PixelForge recommend using multiples of 6pt @ 96 DPI for best results. That will render the font pixel-perfectly without antialiasing.

So, for best results, use the following settings:

  • 1x - 6pt @ 96 DPI
  • 2x - 12pt @ 96 DPI
  • 3x - 18pt @ 96 DPI
  • 4x - 24pt @ 96 DPI
  • 5x - 30pt @ 96 DPI
  • 6x - 36pt @ 96 DPI
  • ... etc.

(Note: Due to a bug in PixelForge, I have to use Python to change the Units Per Em value to 75% of the one PixelForge sets on export. Without this change, the suggested font sizes are incorrect.)

Web Usage

You can add these fonts for use on a webpage by including the following code in your CSS stylesheet:

@font-face {
  font-family: 'Microfont';
  src: url('https://raw.githubusercontent.com/nimaid/microfont/refs/heads/main/Microfont.woff2') format('woff2');
  src: url('https://raw.githubusercontent.com/nimaid/microfont/refs/heads/main/Microfont.woff') format('woff');
  src: url('https://raw.githubusercontent.com/nimaid/microfont/refs/heads/main/Microfont.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Microfont-Mono';
  src: url('https://raw.githubusercontent.com/nimaid/microfont/refs/heads/main/Microfont-Mono.woff2') format('woff2');
  src: url('https://raw.githubusercontent.com/nimaid/microfont/refs/heads/main/Microfont-Mono.woff') format('woff');
  src: url('https://raw.githubusercontent.com/nimaid/microfont/refs/heads/main/Microfont-Mono.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

Direct Encodings

Thanks to slaimon and his converter script src/encode_binary_array.py, you can now directly store this font in a simple array of binary numbers. Because each character is only 15 pixels total, they fit well into a 16-bit word. The number representing an ASCII character's glyph is indexed by that ASCII character's code.

Here is that array for the current iteration of the Microfont:

{
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x2482, 0x5a00, 0x5f7d, 0x3cfa, 0x52a5, 0x3ceb, 0x2400,
    0x1491, 0x4494, 0x5540, 0x05d0, 0x0014, 0x01c0, 0x0002, 0x12a4,
    0x7b6f, 0x2c97, 0x62a7, 0x628e, 0x1779, 0x798e, 0x79ef, 0x72a4,
    0x7bef, 0x7bcf, 0x0410, 0x0414, 0x1511, 0x0e38, 0x4454, 0x72c2,
    0x2b63, 0x2bed, 0x6bae, 0x3923, 0x6b6e, 0x79a7, 0x79a4, 0x396b,
    0x5bed, 0x7497, 0x126a, 0x5bad, 0x4927, 0x5fed, 0x5ffd, 0x2b6a,
    0x6ba4, 0x3b73, 0x6bad, 0x388e, 0x7492, 0x5b6f, 0x5b6a, 0x5bfd,
    0x5aad, 0x5a92, 0x72a7, 0x3493, 0x4889, 0x6496, 0x2a00, 0x0007,
    0x4400, 0x076b, 0x4d6e, 0x0723, 0x176b, 0x0573, 0x15d2, 0x07ce,
    0x49ad, 0x2092, 0x2094, 0x4bad, 0x2491, 0x0bed, 0x0d6d, 0x056a,
    0x0d74, 0x0759, 0x0564, 0x070e, 0x2691, 0x0b6b, 0x0b6a, 0x0b7d,
    0x0a95, 0x0aca, 0x0e67, 0x3513, 0x2492, 0x6456, 0x00f0, 0x0000
}

How To Use The Binary Array

Decoding The Binary Array

To learn how to decode each glyph, see the decode_glyph_from_binary() function in src/modules/common.py.

To learn how to use the decoded glyph bitmap arrays, see the print_bitmap() function.

Scripts

This project has helper scripts to assist me in converting to the various formats when I need to update everything.

All the functionality of these scripts is stored in src/modules/common.py, all the defaults are stored in src/modules/defaults.py, and the argument parsers are stored in src/modules/parsers.py.

Each script file listed below is a simple wrapper for functions and values defined in the above files.

These scripts require Python 3 to be installed. Additionally, the following packages must installed via pip:

pip install Pillow fontTools brotli

Image Generators

I have included two Python scripts named src/generate_1D.py and src/generate_2D.py. I used these to generate the example images.

Both are tools with a command line interface that render text into images using a sprite sheet, however:

  • src/generate_1D.py uses Microfont_1D.png
  • src/generate_2D.py uses Microfont_2D.png

To see the key differences between using the 1D and 2D sprite sheet, open src/modules/common.py and compare the following functions:

  • validate_image_font_1d() / validate_image_font_2d()
  • image_font_char_size_1d() / image_font_char_size_2d()
  • get_glyph_position_1d() / get_glyph_position_2d()

You can see how to use the scripts with:

python src/generate_1D.py --help
python src/generate_2D.py --help

Binary Array Converter

To see how to use the script used to encode the font into a binary array:

python src/encode_binary_array.py --help

About

A Highly Legible 3x5 Pixel Font With Full ASCII Support

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Contributors

Languages