circuitpython/tools/gen_display_resources.py

171 lines
4.9 KiB
Python

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='manufacturer of the device', required=True)
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)
f.load_glyphs(range(0x20, 0x7f))
print(f.get_bounding_box())
real_bb = [0, 0]
visible_ascii = bytes(range(0x20, 0x7f)).decode("utf-8")
extra_characters = "üàêùéáçãÍóíαψ◌"
all_characters = visible_ascii + extra_characters
filtered_characters = all_characters
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, "")
extra_characters = extra_characters.replace(c, "")
continue
x, y, dx, dy = g["bounds"]
#print(c, g["bounds"], g["shift"])
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)
#real_bb[1] += 1
#print(real_bb)
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])
# print(c, g["bounds"], g["shift"], tile_y, start_y)
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))
# print("*",end="")
# else:
# print("_",end="")
#print()
# print(b)
# print("tile_x = {}".format(tile_x))
# print("tile_y = {}".format(tile_y))
# print("tiles = {}".format(len(all_characters)))
# print("font = displayio.Bitmap(tile_x * tiles, tile_y, 2)")
# for row in range(tile_y):
# print("font._load_row({}, {})".format(row, bytes(b[row*bytes_per_row:row*bytes_per_row+bytes_per_row])))
# for row in range(tile_y):
# for byte in b[row*bytes_per_row:row*bytes_per_row+bytes_per_row]:
# print("{:08b} ".format(byte),end="")
# print()
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"))))