diff options
Diffstat (limited to 'tools')
| m--------- | tools/Tecate-bitmap-fonts | 0 | ||||
| m--------- | tools/bitmap_font | 0 | ||||
| -rw-r--r-- | tools/gen_display_resources.py | 174 |
3 files changed, 174 insertions, 0 deletions
diff --git a/tools/Tecate-bitmap-fonts b/tools/Tecate-bitmap-fonts new file mode 160000 +Subproject 6f52a7ca0838967cc57e9a44d76c6e1f60e6284 diff --git a/tools/bitmap_font b/tools/bitmap_font new file mode 160000 +Subproject 62dd78abdd0b823824fe15d1bab0611246145c2 diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py new file mode 100644 index 000000000..e0021650d --- /dev/null +++ b/tools/gen_display_resources.py @@ -0,0 +1,174 @@ +import argparse + +import os +import struct +import sys + +sys.path.append("bitmap_font") +sys.path.append("../../tools/bitmap_font") + +from adafruit_bitmap_font import bitmap_font + +parser = argparse.ArgumentParser(description='Generate USB descriptors.') +parser.add_argument('--font', type=str, + help='Font path', required=True) +parser.add_argument('--extra_characters', type=str, + help='Unicode string of extra characters') +parser.add_argument('--sample_file', type=argparse.FileType('r'), + help='Text file that includes strings to support.') +parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True) + +args = parser.parse_args() + +class BitmapStub: + def __init__(self, width, height, color_depth): + self.width = width + self.rows = [b''] * height + + def _load_row(self, y, row): + self.rows[y] = bytes(row) + +f = bitmap_font.load_font(args.font, BitmapStub) +real_bb = [0, 0] + +# Load extra characters from the sample file. +sample_characters = set() +if args.sample_file: + for line in args.sample_file: + # Skip comments because we add additional characters in our huffman comments. + if line.startswith("//"): + continue + for c in line.strip(): + sample_characters.add(c) + +# Merge visible ascii, sample characters and extra characters. +visible_ascii = bytes(range(0x20, 0x7f)).decode("utf-8") +all_characters = visible_ascii +for c in sample_characters: + if c not in all_characters: + all_characters += c +if args.extra_characters: + all_characters.extend(args.extra_characters) +filtered_characters = all_characters + +# Try to pre-load all of the glyphs. Misses will still be slow later. +f.load_glyphs(set(all_characters)) + +# Get each glyph. +for c in all_characters: + g = f.get_glyph(ord(c)) + if not g: + print("Font missing character:", c, ord(c)) + filtered_characters = filtered_characters.replace(c, "") + continue + x, y, dx, dy = g["bounds"] + if g["shift"][1] != 0: + raise RuntimeError("y shift") + real_bb[0] = max(real_bb[0], x - dx) + real_bb[1] = max(real_bb[1], y - dy) + +tile_x, tile_y = real_bb +total_bits = tile_x * len(all_characters) +total_bits += 32 - total_bits % 32 +bytes_per_row = total_bits // 8 +b = bytearray(bytes_per_row * tile_y) + +for x, c in enumerate(filtered_characters): + g = f.get_glyph(ord(c)) + start_bit = x * tile_x + g["bounds"][2] + start_y = (tile_y - 2) - (g["bounds"][1] + g["bounds"][3]) + for y, row in enumerate(g["bitmap"].rows): + for i in range(g["bounds"][0]): + byte = i // 8 + bit = i % 8 + if row[byte] & (1 << (7-bit)) != 0: + overall_bit = start_bit + (start_y + y) * bytes_per_row * 8 + i + b[overall_bit // 8] |= 1 << (7 - (overall_bit % 8)) + + +extra_characters = "" +for c in filtered_characters: + if c not in visible_ascii: + extra_characters += c + +c_file = args.output_c_file + +c_file.write("""\ + +#include "shared-bindings/displayio/Palette.h" +#include "supervisor/shared/display.h" + +""") + +c_file.write("""\ +uint32_t terminal_transparency[1] = {0x00000000}; + +// These colors are RGB 565 with the bytes swapped. +uint32_t terminal_colors[1] = {0xffff0000}; + +displayio_palette_t supervisor_terminal_color = { + .base = {.type = &displayio_palette_type }, + .opaque = terminal_transparency, + .colors = terminal_colors, + .color_count = 2, + .needs_refresh = false +}; +""") + +c_file.write("""\ +displayio_tilegrid_t supervisor_terminal_text_grid = {{ + .base = {{ .type = &displayio_tilegrid_type }}, + .bitmap = (displayio_bitmap_t*) &supervisor_terminal_font, + .pixel_shader = &supervisor_terminal_color, + .x = 16, + .y = 0, + .bitmap_width_in_tiles = {0}, + .width_in_tiles = 1, + .height_in_tiles = 1, + .total_width = {1}, + .total_height = {2}, + .tile_width = {1}, + .tile_height = {2}, + .tiles = NULL, + .needs_refresh = false, + .inline_tiles = false +}}; +""".format(len(all_characters), tile_x, tile_y)) + +c_file.write("""\ +const uint32_t font_bitmap_data[{}] = {{ +""".format(bytes_per_row * tile_y // 4)) + +for i, word in enumerate(struct.iter_unpack(">I", b)): + c_file.write("0x{:08x}, ".format(word[0])) + if (i + 1) % (bytes_per_row // 4) == 0: + c_file.write("\n") + +c_file.write("""\ +}; +""") + +c_file.write("""\ +const displayio_bitmap_t supervisor_terminal_font = {{ + .base = {{.type = &displayio_bitmap_type }}, + .width = {}, + .height = {}, + .data = (uint32_t*) font_bitmap_data, + .stride = {}, + .bits_per_value = 1, + .x_shift = 5, + .x_mask = 0x1f, + .bitmask = 0x1 +}}; +""".format(len(all_characters) * tile_x, tile_y, bytes_per_row / 4)) + +c_file.write("""\ +terminalio_terminal_obj_t supervisor_terminal = {{ + .base = {{.type = &terminalio_terminal_type }}, + .cursor_x = 0, + .cursor_y = 0, + .tilegrid = &supervisor_terminal_text_grid, + .unicode_characters = (const uint8_t*) "{}", + .unicode_characters_len = {} +}}; +""".format(extra_characters, len(extra_characters.encode("utf-8")))) |
