diff options
Diffstat (limited to 'src/stm/ao-parse-font.5c')
| -rw-r--r-- | src/stm/ao-parse-font.5c | 174 | 
1 files changed, 174 insertions, 0 deletions
| diff --git a/src/stm/ao-parse-font.5c b/src/stm/ao-parse-font.5c new file mode 100644 index 00000000..fe785854 --- /dev/null +++ b/src/stm/ao-parse-font.5c @@ -0,0 +1,174 @@ +#!/usr/bin/env nickle +# +# Parse a 14-segment font file +# and construct the bitmasks for each +# character. Output is in the same +# format as the input: +# 	[5] = 0x1212, +# /* +# CHAR 37 '%' +# 	        +# 	|    /  +# 	|   /   +# 	        +# 	  /   | +# 	 /    | +# 	        +# */ +# +# Note that there can only be tabs before the glyph image +# as spaces are significant in the image itself. +# + +typedef struct { +	int		c; +	bool[14]	bits; +} glyph; + +exception done(); + +glyph read_glyph(file f) { +	int	c; + +	for (;;) { +		if (File::end(f)) +			raise done(); +		string	l = File::fgets(f); +		if (File::sscanf(l, "CHAR %d", &c) == 1) +			break; +	} + +	string strip_tab(string x) { +		int i = 0; +		while (i < String::length(x) && x[i] == '\t') +			i++; +		string n = String::substr(x, i, String::length(x) - i); +		while (String::length(n) < 7) +			n = n + " "; +		return n; +	} + +	string[7] lines = { [i] = strip_tab(File::fgets(f)) }; + +	glyph	g = { .c = c }; + +	g.bits[0] = lines[0][1] == '-'; + +	g.bits[1] = lines[1][0] == '|'; +	g.bits[2] = lines[1][1] == '\\'; +	g.bits[3] = lines[1][3] == '|'; +	g.bits[4] = lines[1][5] == '/'; +	g.bits[5] = lines[1][6] == '|'; + +	g.bits[6] = lines[3][1] == '-'; +	g.bits[7] = lines[3][4] == '-'; + +	g.bits[8] = lines[5][0] == '|'; +	g.bits[9] = lines[5][1] == '/'; +	g.bits[10] = lines[5][3] == '|'; +	g.bits[11] = lines[5][5] == '\\'; +	g.bits[12] = lines[5][6] == '|'; + +	g.bits[13] = lines[6][1] == '-'; +	return g; +} + +string[*] glyph_image(glyph g) { +	int[7][7] chars = { { ' ' ... } ... }; + +	if (g.bits[0]) +		for (int c = 1; c < 6; c++) +			chars[0][c] = '-'; + +	if (g.bits[1]) +		for (int r = 1; r < 3; r++) +			chars[r][0] = '|'; +	if (g.bits[2]) +		for (int p = 1; p < 3; p++) +			chars[p][p] = '\\'; +	if (g.bits[3]) +		for (int p = 1; p < 3; p++) +			chars[p][3] = '|'; +	if (g.bits[4]) +		for (int p = 1; p < 3; p++) +			chars[p][6-p] = '/'; +	if (g.bits[5]) +		for (int p = 1; p < 3; p++) +			chars[p][6] = '|'; + +	if (g.bits[6]) +		for (int p = 1; p < 3; p++) +			chars[3][p] = '-'; +	if (g.bits[7]) +		for (int p = 4; p < 6; p++) +			chars[3][p] = '-'; + +	if (g.bits[8]) +		for (int r = 4; r < 6; r++) +			chars[r][0] = '|'; +	if (g.bits[9]) +		for (int p = 4; p < 6; p++) +			chars[p][6-p] = '/'; +	if (g.bits[10]) +		for (int p = 4; p < 6; p++) +			chars[p][3] = '|'; +	if (g.bits[11]) +		for (int p = 4; p < 6; p++) +			chars[p][p] = '\\'; +	if (g.bits[12]) +		for (int p = 4; p < 6; p++) +			chars[p][6] = '|'; + +	if (g.bits[13]) +		for (int c = 1; c < 6; c++) +			chars[6][c] = '-'; +		 +	return (string[7]) { [i] = String::new(chars[i]) }; + +} + +int glyph_value(glyph g) { +	int	v = 0; + +	for (int b = 0; b < 14; b++) +		if (g.bits[b]) +			v |= (1 << b); +	return v; +} + +void write_glyph(file f, glyph g) { +	File::fprintf (f, "CHAR %d '%s'\n", g.c, g.c == 127 ? "DEL" : String::new(g.c)); +	string[7] lines = glyph_image(g); +	for (int i = 0; i < 7; i++) +		File::fprintf (f, "\t%s\n", lines[i]); +} + +autoload Sort; + +glyph[*] read_font(file f) { +	glyph[128 - 32] font = { [i] = read_glyph(f) }; + +	Sort::qsort(&font, bool func (glyph a, glyph b) = (a.c > b.c)); +	return font; +} + +glyph[*] font; +void init () { +	twixt (file f = File::open("ao_lcd_font.h", "r"); File::close(f)) { +		font = read_font(f); +	} +} + +void dump() { +	twixt(file f = File::open("ao_lcd_font.h.new", "w"); File::close(f)) { +		for (int i = 0; i < dim(font); i++) { +			File::fprintf (f, "\t[%d] = 0x%04x,\n", i, glyph_value(font[i])); +			File::fprintf (f, "/*\n"); +			write_glyph(f, font[i]); +			File::fprintf (f, "*/\n\n"); +		} +	} +} + +init(); +dump(); | 
