# Tool to extract 8x8 font data, save to bitmap file, and apply modifications # to source code after editing the bitmap. from __future__ import print_function from matplotlib.pyplot import imread, imsave, imshow, show import numpy as np import sys # Where to find the font data - may need updated if code has changed. source_file = 'ui_lcd_hy28_fonts.c' start_marker = 'const uint8_t GL_ASCII8x8_Table [] =' start_offset = 2 # Data starts this number of lines after start marker. end_marker = '};' # Indicates end of font data. # Image filename used in extract and insert modes. image_file = 'font-8x8.png' #mode = None #mode = show mode = extract #mode = insert if len(sys.argv) > 1: mode = sys.argv[1] if mode not in ('show', 'extract', 'insert'): print("Usage: %s { show | extract | insert }" % sys.argv[0]) sys.exit(1) # Get the literals used to populate the font array in the source file lines = [line.rstrip() for line in open(source_file).readlines()] start = lines.index(start_marker) + start_offset end = start + lines[start:].index(end_marker) data = str.join("", lines[start:end]) # Eval the literals to get the values into a numpy array packed = eval("np.array([%s], np.uint8)" % data) # Reorganise into a monochrome image, with the 96 8 x 8 characters # laid out in 8 rows by 12 columns for easier viewing/editing unpacked = np.unpackbits(packed) bitmaps = unpacked.reshape(96, 8, 8) indices = np.arange(96).reshape(8, 12) image = np.block([[bitmaps[idx] for idx in row] for row in indices]) if mode == 'show': # Display font image imshow(image, cmap='binary') show() elif mode == 'extract': # Save font image imsave(image_file, image, format='png', cmap='binary') elif mode == 'insert': # Read in modified font image image = imread(image_file)[:,:,0].astype(bool) # Reorganise back to original order bitmaps = np.vstack([np.vstack(np.split(row, 12, 1)) for row in np.split(image, 8)]) unpacked = bitmaps.reshape(-1) packed = ~np.packbits(unpacked) # Replace lines of file in same format as used before grouped = packed.reshape(-1, 8) for i, group in enumerate(grouped): line = (" " + " 0x%02x," * 8) % tuple(group) lines[start + i] = line # Write out modified source file open(source_file, 'w').writelines([line + "\n" for line in lines])