diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2022-06-19 19:47:51 +0530 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2022-06-19 19:47:51 +0530 |
commit | 4fd287655a72b9aea14cdac715ad5b90ed082ed2 (patch) | |
tree | 65d393bc0e699dd12d05b29ba568e04cea666207 /circuitpython/tools/gen_display_resources.py | |
parent | 0150f70ce9c39e9e6dd878766c0620c85e47bed0 (diff) |
add circuitpython code
Diffstat (limited to 'circuitpython/tools/gen_display_resources.py')
-rw-r--r-- | circuitpython/tools/gen_display_resources.py | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/circuitpython/tools/gen_display_resources.py b/circuitpython/tools/gen_display_resources.py new file mode 100644 index 0000000..552e5f1 --- /dev/null +++ b/circuitpython/tools/gen_display_resources.py @@ -0,0 +1,234 @@ +# SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) +# +# SPDX-License-Identifier: MIT + +import argparse + +import os +import struct +import sys + +sys.path.insert(0, "bitmap_font") +sys.path.insert(0, "../../tools/bitmap_font") + +from adafruit_bitmap_font import bitmap_font + +parser = argparse.ArgumentParser(description="Generate displayio resources.") +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", encoding="utf-8"), + 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) + +# 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 = list(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) +all_characters = "".join(sorted(set(all_characters))) +filtered_characters = all_characters + +# Try to pre-load all of the glyphs. Misses will still be slow later. +f.load_glyphs(set(ord(c) for c in all_characters)) + +missing = 0 +# Get each glyph. +for c in set(all_characters): + if ord(c) not in f._glyphs: + missing += 1 + filtered_characters = filtered_characters.replace(c, "") + continue + g = f.get_glyph(ord(c)) + if g["shift"][1] != 0: + raise RuntimeError("y shift") + +if missing > 0: + print("Font missing", missing, "characters", file=sys.stderr) + +x, y, dx, dy = f.get_bounding_box() +tile_x, tile_y = x - dx, y - dy +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( + """\ +_displayio_color_t terminal_colors[2] = { + { + .rgb888 = 0x000000, + .rgb565 = 0x0000, + .luma = 0x00, + .chroma = 0 + }, + { + .rgb888 = 0xffffff, + .rgb565 = 0xffff, + .luma = 0xff, + .chroma = 0 + }, +}; + +displayio_palette_t supervisor_terminal_color = { + .base = {.type = &displayio_palette_type }, + .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_bitmap, + .pixel_shader = &supervisor_terminal_color, + .x = 16, + .y = 0, + .pixel_width = {1}, + .pixel_height = {2}, + .bitmap_width_in_tiles = {0}, + .tiles_in_bitmap = {0}, + .width_in_tiles = 1, + .height_in_tiles = 1, + .tile_width = {1}, + .tile_height = {2}, + .tiles = NULL, + .partial_change = false, + .full_change = false, + .hidden = false, + .hidden_by_parent = false, + .moved = false, + .inline_tiles = false, + .in_group = true +}}; +""".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( + """\ +displayio_bitmap_t supervisor_terminal_font_bitmap = {{ + .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, + .read_only = true +}}; +""".format( + len(all_characters) * tile_x, tile_y, bytes_per_row / 4 + ) +) + + +c_file.write( + """\ +const fontio_builtinfont_t supervisor_terminal_font = {{ + .base = {{.type = &fontio_builtinfont_type }}, + .bitmap = &supervisor_terminal_font_bitmap, + .width = {}, + .height = {}, + .unicode_characters = (const uint8_t*) "{}", + .unicode_characters_len = {} +}}; +""".format( + tile_x, tile_y, extra_characters, len(extra_characters.encode("utf-8")) + ) +) + +c_file.write( + """\ +terminalio_terminal_obj_t supervisor_terminal = { + .base = { .type = &terminalio_terminal_type }, + .font = &supervisor_terminal_font, + .cursor_x = 0, + .cursor_y = 0, + .tilegrid = NULL +}; +""" +) |