From be26ac9abfbf3bae97077b59b694d3148e0c473b Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 4 Dec 2016 12:23:56 +1100 Subject: coretmpl: add an associative LRU cache with map-like behaviour selmenu: use LRU cache so icons don't all need to be reloaded on scroll uismall.bdf: set default character for missing glyphs rendfont.cpp: * encapsulate many BDF and BDC handling details * make file I/O 64-bit clean, check for allocation errors * more solid BDF parser with error messages and trace logging * fix heap smash when building bitmaps for BDF fonts * extend BDC format to support high planes and default character * render default character if glyph not found for BDF/BDC --- scripts/build/png2bdc.py | 109 ++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 45 deletions(-) (limited to 'scripts/build/png2bdc.py') diff --git a/scripts/build/png2bdc.py b/scripts/build/png2bdc.py index 4ffeb4c01ab..a1be5c552d0 100644 --- a/scripts/build/png2bdc.py +++ b/scripts/build/png2bdc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python ## ## license:BSD-3-Clause ## copyright-holders:Aaron Giles, Andrew Gardner @@ -50,7 +50,7 @@ ## ## Python note: ## This is a near-literal translation of the original C++ code. As such there -## are some very non-pythonic things done throughout. The conversion was done +## are some very non-pythonic things done throughout. The conversion was done ## this way so as to insure compatibility as much as possible given the small ## number of test cases. ## @@ -74,7 +74,7 @@ class RenderFontChar: """ Contains information about a single character in a font. """ - + def __init__(self): """ """ @@ -90,10 +90,11 @@ class RenderFont: """ Contains information about a font """ - + def __init__(self): self.height = 0 # height of the font, from ascent to descent self.yOffs = 0 # y offset from baseline to descent + self.defChar = -1 # default character for glyphs not present self.chars = list() # array of characters for i in range(0, 65536): self.chars.append(RenderFontChar()) @@ -107,7 +108,7 @@ def pixelIsSet(value): return (value & 0xffffff) == 0 -def renderFontSaveCached(font, filename, hash32): +def renderFontSaveCached(font, filename, length64, hash32): """ """ fp = open(filename, "wb") @@ -120,45 +121,61 @@ def renderFontSaveCached(font, filename, hash32): if c.width > 0: numChars += 1 - CACHED_CHAR_SIZE = 12 - CACHED_HEADER_SIZE = 16 - + CACHED_CHAR_SIZE = 16 + CACHED_HEADER_SIZE = 32 + try: + fp.write(b'b') + fp.write(b'd') + fp.write(b'c') fp.write(b'f') - fp.write(b'o') fp.write(b'n') fp.write(b't') + fp.write(b2p(1)) + fp.write(b2p(0)) + fp.write(b2p(length64 >> 56 & 0xff)) + fp.write(b2p(length64 >> 48 & 0xff)) + fp.write(b2p(length64 >> 40 & 0xff)) + fp.write(b2p(length64 >> 32 & 0xff)) + fp.write(b2p(length64 >> 24 & 0xff)) + fp.write(b2p(length64 >> 16 & 0xff)) + fp.write(b2p(length64 >> 8 & 0xff)) + fp.write(b2p(length64 >> 0 & 0xff)) fp.write(b2p(hash32 >> 24 & 0xff)) fp.write(b2p(hash32 >> 16 & 0xff)) fp.write(b2p(hash32 >> 8 & 0xff)) fp.write(b2p(hash32 >> 0 & 0xff)) - fp.write(b2p(font.height >> 8 & 0xff)) - fp.write(b2p(font.height >> 0 & 0xff)) - fp.write(b2p(font.yOffs >> 8 & 0xff)) - fp.write(b2p(font.yOffs >> 0 & 0xff)) fp.write(b2p(numChars >> 24 & 0xff)) fp.write(b2p(numChars >> 16 & 0xff)) fp.write(b2p(numChars >> 8 & 0xff)) fp.write(b2p(numChars >> 0 & 0xff)) - + fp.write(b2p(font.height >> 8 & 0xff)) + fp.write(b2p(font.height >> 0 & 0xff)) + fp.write(b2p(font.yOffs >> 8 & 0xff)) + fp.write(b2p(font.yOffs >> 0 & 0xff)) + fp.write(b2p(font.defChar >> 24 & 0xff)) + fp.write(b2p(font.defChar >> 16 & 0xff)) + fp.write(b2p(font.defChar >> 8 & 0xff)) + fp.write(b2p(font.defChar >> 0 & 0xff)) + # Write a blank table at first (?) charTable = [0]*(numChars * CACHED_CHAR_SIZE) for i in range(numChars * CACHED_CHAR_SIZE): fp.write(b2p(charTable[i])) - + # Loop over all characters tableIndex = 0 - + for i in range(len(font.chars)): c = font.chars[i] if c.width == 0: continue - + if c.bitmap: dBuffer = list() accum = 0 accbit = 7 - + # Bit-encode the character data for y in range(0, c.bmHeight): src = None @@ -173,42 +190,44 @@ def renderFontSaveCached(font, filename, hash32): dBuffer.append(accum) accum = 0 accbit = 7 - + # Flush any extra if accbit != 7: dBuffer.append(accum) - + # Write the data for j in range(len(dBuffer)): fp.write(b2p(dBuffer[j])) - + destIndex = tableIndex * CACHED_CHAR_SIZE - charTable[destIndex + 0] = i >> 8 & 0xff - charTable[destIndex + 1] = i >> 0 & 0xff - charTable[destIndex + 2] = c.width >> 8 & 0xff - charTable[destIndex + 3] = c.width >> 0 & 0xff - charTable[destIndex + 4] = c.xOffs >> 8 & 0xff - charTable[destIndex + 5] = c.xOffs >> 0 & 0xff - charTable[destIndex + 6] = c.yOffs >> 8 & 0xff - charTable[destIndex + 7] = c.yOffs >> 0 & 0xff - charTable[destIndex + 8] = c.bmWidth >> 8 & 0xff - charTable[destIndex + 9] = c.bmWidth >> 0 & 0xff - charTable[destIndex + 10] = c.bmHeight >> 8 & 0xff - charTable[destIndex + 11] = c.bmHeight >> 0 & 0xff + charTable[destIndex + 0] = i >> 24 & 0xff + charTable[destIndex + 1] = i >> 16 & 0xff + charTable[destIndex + 2] = i >> 8 & 0xff + charTable[destIndex + 3] = i >> 0 & 0xff + charTable[destIndex + 4] = c.width >> 8 & 0xff + charTable[destIndex + 5] = c.width >> 0 & 0xff + charTable[destIndex + 8] = c.xOffs >> 8 & 0xff + charTable[destIndex + 9] = c.xOffs >> 0 & 0xff + charTable[destIndex + 10] = c.yOffs >> 8 & 0xff + charTable[destIndex + 11] = c.yOffs >> 0 & 0xff + charTable[destIndex + 12] = c.bmWidth >> 8 & 0xff + charTable[destIndex + 13] = c.bmWidth >> 0 & 0xff + charTable[destIndex + 14] = c.bmHeight >> 8 & 0xff + charTable[destIndex + 15] = c.bmHeight >> 0 & 0xff tableIndex += 1 - + # Seek back to the beginning and rewrite the table fp.seek(CACHED_HEADER_SIZE, 0) for i in range(numChars * CACHED_CHAR_SIZE): fp.write(b2p(charTable[i])) - + fp.close() return 0 except: print(sys.exc_info[1]) return 1 - + def bitmapToChars(pngObject, font): """ @@ -225,7 +244,7 @@ def bitmapToChars(pngObject, font): for r,g,b,a in zip(irpd, irpd, irpd, irpd): cRow.append(a << 24 | r << 16 | g << 8 | b) bitmap.append(cRow) - + rowStart = 0 while rowStart < height: # Find the top of the row @@ -317,7 +336,7 @@ def bitmapToChars(pngObject, font): ch.yOffs = font.yOffs ch.bmWidth = len(ch.bitmap[0]) ch.bmHeight = len(ch.bitmap) - + # Insert the character into the list font.chars[chStart] = ch @@ -327,7 +346,7 @@ def bitmapToChars(pngObject, font): # Next row rowStart = rowEnd + 1 - + # Return non-zero if we errored return rowStart < height @@ -341,7 +360,7 @@ def main(): sys.stderr.write("Usage:\n%s [ [...]] \n" % sys.argv[0]) return 1 bdcName = sys.argv[-1] - + font = RenderFont() for i in range(1, len(sys.argv)-1): filename = sys.argv[i] @@ -359,12 +378,12 @@ def main(): error = bitmapToChars(pngObject, font) if error: return 1 - - error = renderFontSaveCached(font, bdcName, 0) + + error = renderFontSaveCached(font, bdcName, 0, 0) return error - - - + + + ######################################## ## Program entry point ######################################## -- cgit v1.2.3-70-g09d2