# Fonts

The driver supports two different types of fonts: fixed-size bitmap fonts extracted from PC VGA and Bios images and fixed or proportional width fonts converted from True-Type fonts. All fonts are stored in python modules and imported using the standard python import statement.

Pre-compiling the font python modules to .mpy files will significantly reduce the memory required for the fonts. For even more memory savings, the font files can be converted to frozen bytecode and compiled into the MicroPython firmware.

Comparison of Bitmap and TrueType Fonts Attributes
Attribute | Bitmap Fonts | TrueType Fonts
--- | --- | ---
Source | PC BIOS images | True-Type fonts
Conversion Tool | text_font_converter.py | write_font_converter.py
Character Sets | 128 and 256 PC character sets | User defined
Pixel Sizes | 8x8, 8x16, 16x6, and 16x32 | width 256 pixels or less
Rendering Method | text() method | write() method

## Bitmap Fonts

Bitmap fonts are available in 128 and 256 PC character sets in 8x8, 8x16, 16x6 and 16x32 pixel sizes. They are written using the text method.

### Bitmap Font Conversion

The utils directory contains the text_font_converter.py program used to convert PC BIOS bitmap fonts from the font-bin directory of spacerace’s https://github.com/spacerace/romfont repo.

The utility converts all romfont bin files in the specified -input-directory (-i) and writes python font files to the specified -output-directory (-o).

Characters included can be limited by using the -first-char (-f) and -last-char (-l) options.

Example:

> text_font_converter.py -i font-bin -o fonts -f 32 -l 127

Sample converted romfont font module.

     1"""converted from vga_8x8.bin """
     2
     3# font width
     4WIDTH = 8
     5
     6# font height
     7HEIGHT = 8
     8
     9# first character in front
    10FIRST = 0x20
    11
    12# last character in font
    13LAST = 0x7f
    14
    15# bitmap of each character from FIRST to LAST
    16_FONT =\
    17b'\x00\x00\x00\x00\x00\x00\x00\x00'\
    18b'\x18\x3c\x3c\x18\x18\x00\x18\x00'\
    19b'\x66\x66\x24\x00\x00\x00\x00\x00'\
    20
    21... many more lines of data...
    22
    23b'\x70\x18\x18\x0e\x18\x18\x70\x00'\
    24b'\x76\xdc\x00\x00\x00\x00\x00\x00'\
    25b'\x00\x10\x38\x6c\xc6\xc6\xfe\x00'\
    26
    27FONT = memoryview(_FONT)

### Bitmap Font Samples

#### 8x8 Rom Fonts

vga1_8x8.py: 128 Character 8x8 Font

vga2_8x8.py: 256 Character 8x8 Font

#### 8x16 Rom Fonts

vga1_8x16.py: 128 Character 8x16 Font

vga2_8x16.py: 256 Character 8x16 Font

#### 16x16 Rom Fonts

vga1_16x16.py: 128 Character 16x16 Thin Font

vga1_bold_16x16.py: 128 Character 16x16 Bold Font

vga2_16x16.py: 256 Character 16x16 Thin Font

vga2_bold_16x16.py: 256 Character 16x16 Bold Font

#### 16x32 Rom Fonts

vga1_16x32.py: 128 Character 16x32 Thin Font

vga1_bold_16x32.py: 128 Character 16x32 Bold Font

vga2_16x32.py: 256 Character 16x32 Thin Font

vga2_bold_16x32.py: 256 Character 16x32 Bold Font

## True Type fonts

The True-Type fonts can be converted to any size as long as the widest character is 256 pixels or less. They are written using the write method.

### True-Type Font Conversion

The utils directory contains the write_font_converter.py program used to convert True-Type font into bitmap font modules. Use the -h option to see details of the available options. The write_font_converter.py program uses font handling classes from Dan Bader blog post on using freetype http://dbader.org/blog/monochrome-font-rendering-with-freetype-and-python and the negative glyph.left fix from peterhinch’s font conversion program https://github.com/peterhinch/micropython-font-to-py.

The utility requires the python freetype module.

Example use:

- ./write_font_converter.py NotoSans-Regular.ttf 32 -s “0123456789ABCEDF”

- ./write_font_converter.py Chango-Regular.ttf 16 -c 0x20-0x7f

Sample converted TrueType font module.

     1# -*- coding: utf-8 -*-
     2# Converted from Chango-Regular.ttf using:
     3#     ./write_font_converter.py Chango-Regular.ttf 16 -c 0x20-0x7f
     4
     5# Maps the order of the character data
     6MAP = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
     7
     8# Number of color bits per pixel, currently only 1 is used but could be
     9# increased to support antialiased or smoothed fonts in the future.
    10BPP = 1
    11
    12# Font height
    13HEIGHT = 17
    14
    15# Font max width
    16MAX_WIDTH = 24
    17
    18# one byte per character table of widths in the same order as the MAP string
    19_WIDTHS = \
    20    b'\x06\x08\x0a\x0e\x0d\x18\x10\x06\x08\x08\x0a\x0d\x06\x08\x06\x0b'\
    21
    22    ... more lines of data...
    23
    24    b'\x0d\x0d\x0b\x0a\x0b\x0e\x0c\x12\x0d\x0c\x0b\x09\x06\x09\x0e\x0b'
    25
    26# OFFSET_WIDTH bytes per character in the same order as the MAP string
    27# to the start of each character in bits.
    28OFFSET_WIDTH = 2
    29_OFFSETS = \
    30    b'\x00\x00\x00\x66\x00\xee\x01\x98\x02\x86\x03\x63\x04\xfb\x06\x0b'\
    31
    32    ... more lines of data...
    33
    34    b'\x49\x94\x4a\x71\x4b\x3d\x4b\xf8\x4c\x91\x4c\xf7\x4d\x90\x4e\x7e'
    35
    36# character bitmaps per character in the same order as the MAP string.
    37# Note: character data may not start on byte boundaries
    38_BITMAPS =\
    39    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61'\
    40
    41    ... many more lines of data...
    42
    43    b'\x3d\xe3\xfc\x00\x00\x00\x00\x00'
    44
    45WIDTHS = memoryview(_WIDTHS)
    46OFFSETS = memoryview(_OFFSETS)
    47BITMAPS = memoryview(_BITMAPS)