diff --git a/font/README.md b/font/README.md index 4f85e99..c4b93a0 100644 --- a/font/README.md +++ b/font/README.md @@ -28,3 +28,16 @@ copied to the scripts directory and used to build firmware with the file as a fr This assumes Linux but CfontToBinary.py is plain Python3 and should run on other platforms. +# The font matrix + +In the C file each character is stored as a fixed size array of bytes, the first byte being +the character width. When rendering a font to a device, fonts designed as variable pitch +should use this byte as the width. Monospaced fonts should be rendered using the font's +width (see pyfont.py). + +# Note + +If anyone knows a Python way of converting a font file (a.g. ttf) to a bitmap, please let me +know. My own efforts were not good enough hence my reluctant advocacy of the above closed source +program. + diff --git a/font/pyfont.py b/font/pyfont.py new file mode 100644 index 0000000..ccfd216 --- /dev/null +++ b/font/pyfont.py @@ -0,0 +1,34 @@ + +class PyFont(object): + def __init__(self, font, vert, horiz, nchars): + self.bits_horiz = horiz + self.bits_vert = vert + div, mod = divmod(self.bits_vert, 8) + self.bytes_vert = div if mod == 0 else div +1 + self.bytes_per_ch = self.bytes_vert * self.bits_horiz +1 + self.nchars = nchars + self.font = font + self.monospaced = False + + def render(self, ch): # enter with ord(ch) + relch = ch -32 + if relch > self.nchars: + raise ValueError('Illegal character') + offset = relch * self.bytes_per_ch + bv = self.bits_vert + bh = self.bits_horiz if self.monospaced else self.font[offset] # Char width + offset += 1 + for bit_vert in range(bv): # for each vertical line + bytenum = bit_vert >> 3 + bit = 1 << (bit_vert & 0x07) # Faster than divmod + for bit_horiz in range(bh): # horizontal line + fontbyte = self.font[offset + self.bytes_vert * bit_horiz + bytenum] + z = '*' if fontbyte & bit else ' ' + print(z, end='') +# self.setpixelfast(self.char_x +bit_horiz, self.char_y +bit_vert, (fontbyte & bit) > 0) + print() +# self.char_x += bh # Somehow account for width of current char + + def test(self, s): + for c in s: + self.render(ord(c))