summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2019-01-31 16:03:51 -0500
committerGitHub <noreply@github.com>2019-01-31 16:03:51 -0500
commit7c443fbef2b92bfdd382db9aeaddcdcecbc02cd0 (patch)
tree93c06f6ba863e234148555f41042b354286cb52e /tools
parent63d456127b783efb376bd2b25598cc9e7f9dceb6 (diff)
parentd72cd5b2d6cbc95665c41a43d6d914e71ac58017 (diff)
Merge pull request #1510 from tannewt/terminalio
Add a terminal that shows by default on displays.
Diffstat (limited to 'tools')
m---------tools/Tecate-bitmap-fonts0
m---------tools/bitmap_font0
-rw-r--r--tools/gen_display_resources.py174
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"))))