import os, math from PIL import Image import framebuf current_path = os.path.abspath(os.path.dirname(__file__)) def main(): block_width = 8 block_height = 16 preview_path = os.path.join(current_path, "pix{}x{}.png".format(block_width, block_height)) c_output_path = os.path.join(current_path, "pix{}x{}.h".format(block_width, block_height)) external_char_dir = os.path.join(current_path, "char{}x{}".format(block_width, block_height)) os.makedirs(external_char_dir, exist_ok=True) unicodes = [] unicodes.extend(c for c in range(0x21, 0x7E+1)) # ascii some ascii_width = bytearray(0x7E+1 - 0x21) # 0x20 ascii space # make fnt def my_get_char_data(char_str, block_w, block_h, invert=False, ascii_width = bytearray(0x7E+1 - 0x21)): byts = char_str.encode("utf8") # ascii use external image fnt_img_path = os.path.join(external_char_dir, "{}.pbm".format(byts[0])) ascii_offset = byts[0] - 0x21 block_size = math.ceil(block_w / 8) * block_h ascii_width[ascii_offset] = 8 # record ascii width, == 8 fnt_img = Image.open(fnt_img_path) # draw framebuffer buffer = bytearray(block_size) frame = framebuf.FrameBuffer(buffer, block_w, block_h, framebuf.MONO_HLSB) for y in range(block_h): for x in range(8): pixel = fnt_img.getpixel((x, y)) pixel = 1 if ((pixel == 0) ^ invert) else 0 frame.pixel(x, y, pixel) return buffer, fnt_img font_data = bytearray() # generate font preview = Image.new("1", (block_width*16, block_height*math.ceil((0x7F - 0x21)/16)), color=255) preview_x_count = 0 preview_y_count = 0 for unic in range(0x21, 0x7E+1): # ascii try: char = bytes([unic]).decode("ascii") except: continue data, img = my_get_char_data(char, block_width, block_height, False, ascii_width) font_data.extend(data) preview.paste(img, (preview_x_count * block_width, preview_y_count * block_height)) preview_x_count += 1 if preview_x_count >= 16: preview_x_count = 0 preview_y_count += 1 preview.save(preview_path) # write out with open(c_output_path, "wt") as f: f.write("#pragma once\n") f.write("#include \n") f.write("\n") f.write(f"const uint8_t FONT_UNIFONT_{block_width}_{block_height}[] = {{") for i, byte in enumerate(font_data): if i % 16 == 0: f.write("\n ") f.write(f" 0x{byte:02X},") f.write("\n};\n") f.write(f"const uint8_t FONT_UNIFONT_ASCII_WIDTH_{block_width}_{block_height}[] = {{") for i, byte in enumerate(ascii_width): if i % 16 == 0: f.write("\n ") f.write(f" 0x{byte:02X},") f.write("\n};\n") f.write("\n") f.close() if __name__ == "__main__": main()