Rearranging code: moving the content creation functions to a new class SimpleTextAndIcons to have them out of the way when importing only LedNameBadge.

rebase020124
Ben 1 year ago
parent 46574a7348
commit d13f9ebf9f
  1. 97
      led-badge-11x44.py
  2. 18
      tests/test_led-badge-11x44.py

@ -70,7 +70,9 @@ except:
__version = "0.12"
font_11x44 = (
class SimpleTextAndIcons:
font_11x44 = (
# 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00,
0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00,
@ -222,9 +224,9 @@ font_11x44 = (
0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, # Û
0x60, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, # Ù
0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, # Ÿ
)
)
charmap = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
charmap = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
u'abcdefghijklmnopqrstuvwxyz' + \
u'0987654321^ !"\0$%&/()=?` °\\}][{' + \
u"@ ~ |<>,;.:-_#'+* " + \
@ -232,15 +234,12 @@ charmap = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
u"àäòöùüèéêëôöûîïÿç" + \
u"ÀÅÄÉÈÊËÖÔÜÛÙŸ"
char_offsets = {}
for i in range(len(charmap)):
char_offsets = {}
for i in range(len(charmap)):
char_offsets[charmap[i]] = 11 * i
# print(i, charmap[i], char_offset[charmap[i]])
bitmap_preloaded = [([], 0)]
bitmaps_preloaded_unused = False
bitmap_named = {
bitmap_named = {
'ball': (array('B', (
0b00000000,
0b00000000,
@ -286,30 +285,48 @@ bitmap_named = {
'owncloud': (array('B', (0x00, 0x01, 0x02, 0x03, 0x06, 0x0c, 0x1a, 0x13, 0x11, 0x19, 0x0f,
0x78, 0xcc, 0x87, 0xfc, 0x42, 0x81, 0x81, 0x81, 0x81, 0x43, 0xbd,
0x00, 0x00, 0x00, 0x80, 0x80, 0xe0, 0x30, 0x10, 0x28, 0x28, 0xd0)), 3, '\x14'),
}
bitmap_builtin = {}
for i in bitmap_named:
}
bitmap_builtin = {}
for i in bitmap_named:
bitmap_builtin[bitmap_named[i][2]] = bitmap_named[i]
def bitmap_char(ch):
def __init__(self):
self.bitmap_preloaded = [([], 0)]
self.bitmaps_preloaded_unused = False
def add_preload_img(self, filename):
self.bitmap_preloaded.append(SimpleTextAndIcons.bitmap_img(filename))
self.bitmaps_preloaded_unused = True
def are_preloaded_unused(self):
return self.bitmaps_preloaded_unused == True
@staticmethod
def get_named_bitmaps_keys():
return SimpleTextAndIcons.bitmap_named.keys()
def bitmap_char(self, ch):
""" Returns a tuple of 11 bytes,
ch = '_' returns (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255)
The bits in each byte are horizontal, highest bit is left.
"""
if ord(ch) < 32:
if ch in bitmap_builtin:
return bitmap_builtin[ch][:2]
if ch in SimpleTextAndIcons.bitmap_builtin:
return SimpleTextAndIcons.bitmap_builtin[ch][:2]
global bitmaps_preloaded_unused
bitmaps_preloaded_unused = False
return bitmap_preloaded[ord(ch)]
self.bitmaps_preloaded_unused = False
return self.bitmap_preloaded[ord(ch)]
o = char_offsets[ch]
return (font_11x44[o:o + 11], 1)
o = SimpleTextAndIcons.char_offsets[ch]
return (SimpleTextAndIcons.font_11x44[o:o + 11], 1)
def bitmap_text(text):
def bitmap_text(self, text):
""" returns a tuple of (buffer, length_in_byte_columns_aka_chars)
We preprocess the text string for substitution patterns
"::" is replaced with a single ":"
@ -326,21 +343,22 @@ def bitmap_text(text):
if re.match('^[0-9]*$', name): # py3 name.isdecimal()
return chr(int(name))
if '.' in name:
bitmap_preloaded.append(bitmap_img(name))
return chr(len(bitmap_preloaded) - 1)
return bitmap_named[name][2]
self.bitmap_preloaded.append(SimpleTextAndIcons.bitmap_img(name))
return chr(len(self.bitmap_preloaded) - 1)
return SimpleTextAndIcons.bitmap_named[name][2]
text = re.sub(r':([^:]*):', replace_symbolic, text)
buf = array('B')
cols = 0
for c in text:
(b, n) = bitmap_char(c)
(b, n) = self.bitmap_char(c)
buf.extend(b)
cols += n
return (buf, cols)
def bitmap_img(file):
@staticmethod
def bitmap_img(file):
""" returns a tuple of (buffer, length_in_byte_columns)
"""
from PIL import Image
@ -373,13 +391,13 @@ def bitmap_img(file):
return (buf, cols)
def bitmap(arg):
def bitmap(self, arg):
""" if arg is a valid and existing path name, we load it as an image.
Otherwise, we take it as a string.
"""
if os.path.exists(arg):
return bitmap_img(arg)
return bitmap_text(arg)
return SimpleTextAndIcons.bitmap_img(arg)
return self.bitmap_text(arg)
class LedNameBadge:
@ -391,6 +409,7 @@ class LedNameBadge:
)
_have_pyhidapi = False
@staticmethod
def init_class():
try:
@ -429,11 +448,13 @@ or
print("""Please with Linux or MacOS or help us implement support for """ + sys.platform)
sys.exit(1)
@staticmethod
def _expand_tuple(l):
l = l + (l[-1],) * (8 - len(l)) # repeat last element
return l
@staticmethod
def header(lengths, speeds, modes, blinks, ants, brightness=100, date=datetime.now()):
""" lengths[0] is the number of chars of the first text
@ -476,6 +497,7 @@ or
return h
@staticmethod
def write(buf):
if len(buf) > 8192:
@ -536,7 +558,7 @@ if __name__ == '__main__':
parser.add_argument('-p', '--preload', metavar='FILE', action='append',
help=argparse.SUPPRESS) # "Load bitmap images. Use ^A, ^B, ^C, ... in text messages to make them visible. Deprecated, embed within ':' instead")
parser.add_argument('-l', '--list-names', action='version', help="list named icons to be embedded in messages and exit",
version=':' + ': :'.join(bitmap_named.keys()) + ': :: or e.g. :path/to/some_icon.png:')
version=':' + ': :'.join(SimpleTextAndIcons.get_named_bitmaps_keys()) + ': :: or e.g. :path/to/some_icon.png:')
parser.add_argument('message', metavar='MESSAGE', nargs='+',
help="Up to 8 message texts with embedded builtin icons or loaded images within colons(:) -- See -l for a list of builtins")
parser.add_argument('--mode-help', action='version', help=argparse.SUPPRESS, version="""
@ -562,16 +584,17 @@ if __name__ == '__main__':
""" % sys.argv[0])
args = parser.parse_args()
creator = SimpleTextAndIcons()
if args.preload:
for file in args.preload:
bitmap_preloaded.append(bitmap_img(file))
bitmaps_preloaded_unused = True
for filename in args.preload:
creator.add_preload_img(filename)
msg_bitmaps = []
for msg_arg in args.message:
msg_bitmaps.append(bitmap(msg_arg))
msg_bitmaps.append(creator.bitmap(msg_arg))
if bitmaps_preloaded_unused == True:
if creator.are_preloaded_unused():
print(
"\nWARNING:\n Your preloaded images are not used.\n Try without '-p' or embed the control character '^A' in your message.\n")
@ -580,8 +603,8 @@ if __name__ == '__main__':
for msg_bitmap in msg_bitmaps:
# trivial hack to support 12x48 badges:
# patch extra empty lines into the message stream.
for o in reversed(range(1, int(len(msg_bitmap[0]) / 11) + 1)):
msg_bitmap[0][o * 11:o * 11] = array('B', [0])
for i in reversed(range(1, int(len(msg_bitmap[0]) / 11) + 1)):
msg_bitmap[0][i * 11:i * 11] = array('B', [0])
else:
print("Type: 11x44")

@ -54,15 +54,29 @@ class Test(TestCase):
self.assertNotEqual(buf1[38:38 + 6], buf2[38:38 + 6])
def test_bitmap_png(self):
buf = testee.bitmap("resources/bitpatterns.png")
creator = testee.SimpleTextAndIcons()
buf = creator.bitmap("resources/bitpatterns.png")
self.assertEqual((array('B',
[128, 64, 32, 16, 8, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 32, 0, 1, 2, 3,
4, 5, 15, 31, 63, 127, 255]),
3), buf)
def test_bitmap_text(self):
buf = testee.bitmap("/:HEART2:\\")
creator = testee.SimpleTextAndIcons()
buf = creator.bitmap("/:HEART2:\\")
self.assertEqual((array('B',
[0, 0, 2, 6, 12, 24, 48, 96, 192, 128, 0, 0, 12, 30, 63, 63, 63, 31, 15, 7, 3, 1, 0, 96,
240, 248, 248, 248, 240, 224, 192, 128, 0, 0, 128, 192, 96, 48, 24, 12, 6, 2, 0, 0]),
4), buf)
def test_preload(self):
creator = testee.SimpleTextAndIcons()
self.assertFalse(creator.are_preloaded_unused())
creator.add_preload_img("resources/bitpatterns.png")
self.assertTrue(creator.are_preloaded_unused())
buf = creator.bitmap("\x01")
self.assertFalse(creator.are_preloaded_unused())
self.assertEqual((array('B',
[128, 64, 32, 16, 8, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 32, 0, 1, 2, 3,
4, 5, 15, 31, 63, 127, 255]),
3), buf)

Loading…
Cancel
Save