diff --git a/components/rasterfont/__init__.py b/components/rasterfont/__init__.py index d1f9365..49f4646 100644 --- a/components/rasterfont/__init__.py +++ b/components/rasterfont/__init__.py @@ -5,23 +5,38 @@ import esphome.config_validation as cv import esphome.codegen as cg from esphome.const import CONF_ID, CONF_GLYPHS, CONF_DATA from esphome.core import CORE, HexInt +import logging #from esphome.py_compat import sort_by_cmp +_LOGGER = logging.getLogger(__name__) + DEPENDENCIES = ['display'] MULTI_CONF = True Font = display.display_ns.class_('Font') Glyph = display.display_ns.class_('Glyph') +GlyphData = display.display_ns.struct("GlyphData") def validate_data(value): r = type(value)() for k, v in value.items(): - r[str(k)] = v + if isinstance(k, str): + try: + k = int(k) + except ValueError: + if len(k.encode()) > 1: + _LOGGER.warning(f"multi byte character: '{k}'") + continue + k = ord(k.encode()) + if k>=0 and k<=9: + k += ord('0') + r[k] = v return type(value)(sorted(r.items())) CONF_RAW_DATA_ID = 'raw_data_id' +CONF_RAW_GLYPH_ID = "raw_glyph_id" BIT0_DEFAULT = '0 ' RASTERFONT_SCHEMA = cv.Schema({ @@ -30,6 +45,7 @@ RASTERFONT_SCHEMA = cv.Schema({ cv.Optional(CONF_GLYPHS): cv.string_strict, cv.Optional('bit0', default=BIT0_DEFAULT): cv.string_strict, cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8), + cv.GenerateID(CONF_RAW_GLYPH_ID): cv.declare_id(GlyphData), }) CONFIG_SCHEMA = cv.All(RASTERFONT_SCHEMA) @@ -40,6 +56,12 @@ def string_to_int(s, bit0): r = [int(b[i:i+8], 2) for i in range(0, len(b), 8)] return r +def int_to_cchar(i): + if i >= 32 and i <= 126: + return '"%c"' % i + else: + return '"\\x%02x"' % i + def to_code(config): glyph_args = {} @@ -69,14 +91,31 @@ def to_code(config): glyph_data += string_to_int(row + '0'*(maxwidth-len(row)), bit0) width8 = ((width + 7) // 8) * 8 - glyph_args[str(glyph)] = (len(data), offset_x, offset_y, width, height) + glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) data += glyph_data rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) - glyphs = [] + glyph_initializer = [] for glyph in config[CONF_DATA].keys(): - glyphs.append(Glyph(str(glyph), prog_arr, *glyph_args[str(glyph)])) + glyph_initializer.append( + cg.StructInitializer( + GlyphData, + ("a_char", cg.RawExpression(int_to_cchar(glyph))), + ( + "data", + cg.RawExpression(str(prog_arr) + " + " + str(glyph_args[glyph][0])), + ), + ("offset_x", glyph_args[glyph][1]), + ("offset_y", glyph_args[glyph][2]), + ("width", glyph_args[glyph][3]), + ("height", glyph_args[glyph][4]), + ) + ) - cg.new_Pvariable(config[CONF_ID], glyphs, 0, 0) + glyphs = cg.static_const_array(config[CONF_RAW_GLYPH_ID], glyph_initializer) + + cg.new_Pvariable( + config[CONF_ID], glyphs, len(glyph_initializer), 0, 0 + )