aboutsummaryrefslogtreecommitdiff
path: root/host/matelight/renderers.py
diff options
context:
space:
mode:
authorjaseg <jaseg@jaseg.net>2013-12-29 02:52:28 +0100
committerjaseg <jaseg@jaseg.net>2013-12-29 02:52:28 +0100
commit7e2c51dc2645c4dffe7cc33e8533f0667b8775a6 (patch)
treefb1e7da9904d60e141d68bc8964f43fd5f46f486 /host/matelight/renderers.py
parenta95e0305aeaffadf071e963863c102b30b76993a (diff)
downloadmatelight-7e2c51dc2645c4dffe7cc33e8533f0667b8775a6.tar.gz
matelight-7e2c51dc2645c4dffe7cc33e8533f0667b8775a6.tar.bz2
matelight-7e2c51dc2645c4dffe7cc33e8533f0667b8775a6.zip
Added basic text rendering & TCP server
Diffstat (limited to 'host/matelight/renderers.py')
-rw-r--r--host/matelight/renderers.py55
1 files changed, 31 insertions, 24 deletions
diff --git a/host/matelight/renderers.py b/host/matelight/renderers.py
index 0e223a2..f507513 100644
--- a/host/matelight/renderers.py
+++ b/host/matelight/renderers.py
@@ -1,11 +1,13 @@
-import numpy as np
+import time
try:
import re2 as re
except ImportError:
import re
+import numpy as np
from PIL import Image
from pixelterm import xtermcolors
from config import *
+from font import *
default_palette = [
(0x00, 0x00, 0x00), # 0 normal colors
@@ -24,17 +26,19 @@ default_palette = [
(0xff, 0x00, 0xff), # 13
(0x00, 0xff, 0xff), # 14
(0xff, 0xff, 0xff)] # 15
+default_colors = (default_palette[8], default_palette[0])
class CharGenerator:
def __init__(self, seq=None, lg=None, text=''):
- settings = False, False, False, default_palette[8], default_palette[0]
+ settings = False, False, False, default_colors
if lg:
- settings = lg,bold, lg.blink, lg.underscore, lg.fg, lg.bg
- self.bold, self.blink, self.underscore, self.fg, self.bg = settings
+ settings = lg.bold, lg.blink, lg.underscore, (lg.fg, lg.bg)
+ self.bold, self.blink, self.underscore, (self.fg, self.bg) = settings
self.text = text
- self.parse_escape_sequence(seq)
+ if seq:
+ self.parse_escape_sequence(seq)
- def parse_escape_sequence(seq):
+ def parse_escape_sequence(self, seq):
codes = list(map(int, seq[2:-1].split(';')))
fg, bg, reverse, i = self.fg, self.bg, False, 0
while i<len(codes):
@@ -49,7 +53,7 @@ class CharGenerator:
elif a == 49:
bg = (0,0,0)
elif a == 0:
- fg, bg = (0,0,0), (0,0,0)
+ fg, bg = default_colors
self.bold, self.blink, self.underscore = False, False, False
elif a in range(30, 38):
fg = default_palette[a-30]
@@ -57,7 +61,7 @@ class CharGenerator:
fg = default_palette[a-90+8]
elif a in range(40, 48):
bg = default_palette[a-40]
- elif a in range(100, 108):
+ elif a in range(101, 108):
bg = default_palette[a-100+8]
elif a == 7:
reverse = True
@@ -68,20 +72,22 @@ class CharGenerator:
elif a == 1: # Literally "bright", not bold.
self.bold = True
i += 1
- fg, bg = bg, fg if reverse else fg, bg
+ fg, bg = (bg, fg) if reverse else (fg, bg)
self.fg, self.bg = fg, bg
def generate_char(self, c, now):
- fg, bg = self.bg, self.bg if self.blink and now%1.0 < 0.3 else self.fg, self.bg
- glyph = font.glyphs_by_codepoint[c]
+ fg, bg = (self.bg, self.fg) if self.blink and now%1.0 < 0.3 else (self.fg, self.bg)
+ glyph = FONT.glyphs_by_codepoint[ord(c)]
# Please forgive the string manipulation below.
lookup = {'0': bg, '1': fg}
- return [ list(map(lookup.get, FONT_PADDED_BINARY(int(row, 16)))) for row in glyph.get_data() ]
+ FONT_PADDED_BINARY = ('{:0'+str(glyph.bbW)+'b}').format
+ FONT_Y_PAD = [[bg]*glyph.bbW]*(DISPLAY_HEIGHT-FONT_HEIGHT)
+ return np.swapaxes(np.array([ list(map(lookup.get, FONT_PADDED_BINARY(int(row, 16))[:glyph.bbW])) for row in glyph.get_data() ] + FONT_Y_PAD, dtype=np.uint8), 0, 1)
def generate(self, now):
chars = [self.generate_char(c, now) for c in self.text]
# This refers to inter-letter spacing
- space = np.zeros((LETTER_SPACING, DISPLAY_HEIGHT, 3))
+ space = np.zeros((LETTER_SPACING, DISPLAY_HEIGHT, 3), dtype=np.uint8)
spaces = [space]*(len(chars)-1)
everything = chars + spaces
everything[::2] = chars
@@ -96,25 +102,26 @@ class TextRenderer:
"""
generators = []
current_generator = CharGenerator()
- for esc, char in r'(\x1B\[[0-9;]+m)|(.)'.finditer(text):
+ for match in re.finditer('(\x1B\[[0-9;]+m)|(.)', text):
+ esc, char = match.groups()
if esc:
if current_generator.text != '':
generators.append(current_generator)
current_generator = CharGenerator(esc, current_generator)
elif char:
current_generator.text += char
- self.generators = generators + [current_generator]
-
- def frames(self, start):
- now = time.time()
- zeros = [np.zeros((DISPLAY_WIDTH, DISPLAY_HEIGHT, 3))]
+ generators = generators + [current_generator]
+ # Generate the actual frame buffer
+ zeros = [np.zeros((DISPLAY_WIDTH, DISPLAY_HEIGHT, 3), dtype=np.uint8)]
# Pad the array with one screen's worth of zeros on both sides so the text fully scrolls through.
- raw = np.concatenate([zeros]+[g.generate(now) for g in generators]+[zeros])
- w,h,_ = raw.size
- for i in range(DISPLAY_WIDTH+w, 0, -1):
- frame = raw[i:i+DISPLAY_WIDTH, :, :]
+ now = time.time()
+ self.raw = np.concatenate(zeros+[g.generate(now) for g in generators]+zeros)
+
+ def frames(self):
+ w,h,_ = self.raw.shape
+ for i in range(0, w-DISPLAY_WIDTH, 2):
+ frame = self.raw[i:i+DISPLAY_WIDTH, :, :]
yield frame, 1/DEFAULT_SCROLL_SPEED
- raw = np.concatenate([zeros]+[g.generate(now) for g in generators]+[zeros])
class ImageRenderer:
def __new__(cls, image_data):