display: Rework write_graphics() to take one character cell at a time
Change write_graphics() from taking one pixel row of n characters to taking all the rows and columns for one character cell. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
467e8e6f40
commit
9465618adb
|
@ -168,7 +168,9 @@ class PrinterLCD:
|
||||||
data = dg.get('data', None)
|
data = dg.get('data', None)
|
||||||
if data is not None:
|
if data is not None:
|
||||||
idata = self._parse_glyph(config, glyph_name, data, 16, 16)
|
idata = self._parse_glyph(config, glyph_name, data, 16, 16)
|
||||||
icons.setdefault(glyph_name, {})['icon16x16'] = idata
|
icon1 = [(bits >> 8) & 0xff for bits in idata]
|
||||||
|
icon2 = [bits & 0xff for bits in idata]
|
||||||
|
icons.setdefault(glyph_name, {})['icon16x16'] = (icon1, icon2)
|
||||||
data = dg.get('hd44780_data', None)
|
data = dg.get('hd44780_data', None)
|
||||||
if data is not None:
|
if data is not None:
|
||||||
slot = dg.getint('hd44780_slot', minval=0, maxval=7)
|
slot = dg.getint('hd44780_slot', minval=0, maxval=7)
|
||||||
|
@ -206,22 +208,11 @@ class PrinterLCD:
|
||||||
# write glyph
|
# write glyph
|
||||||
pos += self.lcd_chip.write_glyph(pos, row, text)
|
pos += self.lcd_chip.write_glyph(pos, row, text)
|
||||||
def draw_progress_bar(self, row, col, width, value):
|
def draw_progress_bar(self, row, col, width, value):
|
||||||
value = int(value * 100.)
|
pixels = -1 << int(width * 8 * (1. - value) + .5)
|
||||||
data = [0x00] * width
|
pixels |= (1 << (width * 8 - 1)) | 1
|
||||||
char_pcnt = int(100/width)
|
|
||||||
for i in range(width):
|
for i in range(width):
|
||||||
if (i+1)*char_pcnt <= value:
|
data = [0xff] + [(pixels >> (i * 8)) & 0xff] * 14 + [0xff]
|
||||||
# Draw completely filled bytes
|
self.lcd_chip.write_graphics(col + width - 1 - i, row, data)
|
||||||
data[i] |= 0xFF
|
|
||||||
elif (i*char_pcnt) < value:
|
|
||||||
# Draw partially filled bytes
|
|
||||||
data[i] |= (-1 << 8-((value % char_pcnt)*8/char_pcnt)) & 0xff
|
|
||||||
data[0] |= 0x80
|
|
||||||
data[-1] |= 0x01
|
|
||||||
self.lcd_chip.write_graphics(col, row, 0, [0xff]*width)
|
|
||||||
for i in range(1, 15):
|
|
||||||
self.lcd_chip.write_graphics(col, row, i, data)
|
|
||||||
self.lcd_chip.write_graphics(col, row, 15, [0xff]*width)
|
|
||||||
return ""
|
return ""
|
||||||
cmd_SET_DISPLAY_GROUP_help = "Set the active display group"
|
cmd_SET_DISPLAY_GROUP_help = "Set the active display group"
|
||||||
def cmd_SET_DISPLAY_GROUP(self, gcmd):
|
def cmd_SET_DISPLAY_GROUP(self, gcmd):
|
||||||
|
|
|
@ -112,7 +112,7 @@ class HD44780:
|
||||||
self.write_text(x, y, char)
|
self.write_text(x, y, char)
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
def write_graphics(self, x, y, pixel_row, pixel_col):
|
def write_graphics(self, x, y, data):
|
||||||
pass
|
pass
|
||||||
def clear(self):
|
def clear(self):
|
||||||
spaces = ' ' * 40
|
spaces = ' ' * 40
|
||||||
|
|
|
@ -115,34 +115,35 @@ class ST7920:
|
||||||
base_icon = self.icons.get(base_glyph_name)
|
base_icon = self.icons.get(base_glyph_name)
|
||||||
if icon is None or base_icon is None:
|
if icon is None or base_icon is None:
|
||||||
return
|
return
|
||||||
for i, (bits, base_bits) in enumerate(zip(icon, base_icon)):
|
all_bits = zip(icon[0], icon[1], base_icon[0], base_icon[1])
|
||||||
|
for i, (ic1, ic2, b1, b2) in enumerate(all_bits):
|
||||||
|
x1, x2 = ic1 ^ b1, ic2 ^ b2
|
||||||
pos = glyph_id*32 + i*2
|
pos = glyph_id*32 + i*2
|
||||||
b1, b2 = (bits >> 8) & 0xff, bits & 0xff
|
self.glyph_framebuffer[pos:pos+2] = [x1, x2]
|
||||||
b1, b2 = b1 ^ (base_bits >> 8) & 0xff, b2 ^ base_bits & 0xff
|
self.all_framebuffers[1][1][pos:pos+2] = [x1 ^ 1, x2 ^ 1]
|
||||||
self.glyph_framebuffer[pos:pos+2] = [b1, b2]
|
|
||||||
self.all_framebuffers[1][1][pos:pos+2] = [b1 ^ 1, b2 ^ 1]
|
|
||||||
self.cached_glyphs[glyph_name] = (base_glyph_name, (0, glyph_id*2))
|
self.cached_glyphs[glyph_name] = (base_glyph_name, (0, glyph_id*2))
|
||||||
|
def set_glyphs(self, glyphs):
|
||||||
|
for glyph_name, glyph_data in glyphs.items():
|
||||||
|
icon = glyph_data.get('icon16x16')
|
||||||
|
if icon is not None:
|
||||||
|
self.icons[glyph_name] = icon
|
||||||
|
# Setup animated glyphs
|
||||||
|
self.cache_glyph('fan2', 'fan1', 0)
|
||||||
|
self.cache_glyph('bed_heat2', 'bed_heat1', 1)
|
||||||
def write_text(self, x, y, data):
|
def write_text(self, x, y, data):
|
||||||
if x + len(data) > 16:
|
if x + len(data) > 16:
|
||||||
data = data[:16 - min(x, 16)]
|
data = data[:16 - min(x, 16)]
|
||||||
pos = [0, 32, 16, 48][y] + x
|
pos = [0, 32, 16, 48][y] + x
|
||||||
self.text_framebuffer[pos:pos+len(data)] = data
|
self.text_framebuffer[pos:pos+len(data)] = data
|
||||||
def write_graphics(self, x, y, row, data):
|
def write_graphics(self, x, y, data):
|
||||||
if x + len(data) > 16:
|
if x >= 16 or y >= 4 or len(data) != 16:
|
||||||
data = data[:16 - min(x, 16)]
|
return
|
||||||
gfx_fb = y * 16 + row
|
gfx_fb = y * 16
|
||||||
if gfx_fb >= 32:
|
if gfx_fb >= 32:
|
||||||
gfx_fb -= 32
|
gfx_fb -= 32
|
||||||
x += 16
|
x += 16
|
||||||
self.graphics_framebuffers[gfx_fb][x:x+len(data)] = data
|
for i, bits in enumerate(data):
|
||||||
def set_glyphs(self, glyphs):
|
self.graphics_framebuffers[gfx_fb + i][x] = bits
|
||||||
for glyph_name, glyph_data in glyphs.items():
|
|
||||||
data = glyph_data.get('icon16x16')
|
|
||||||
if data is not None:
|
|
||||||
self.icons[glyph_name] = data
|
|
||||||
# Setup animated glyphs
|
|
||||||
self.cache_glyph('fan2', 'fan1', 0)
|
|
||||||
self.cache_glyph('bed_heat2', 'bed_heat1', 1)
|
|
||||||
def write_glyph(self, x, y, glyph_name):
|
def write_glyph(self, x, y, glyph_name):
|
||||||
glyph_id = self.cached_glyphs.get(glyph_name)
|
glyph_id = self.cached_glyphs.get(glyph_name)
|
||||||
if glyph_id is not None and x & 1 == 0:
|
if glyph_id is not None and x & 1 == 0:
|
||||||
|
@ -152,8 +153,8 @@ class ST7920:
|
||||||
icon = self.icons.get(glyph_name)
|
icon = self.icons.get(glyph_name)
|
||||||
if icon is not None:
|
if icon is not None:
|
||||||
# Draw icon in graphics mode
|
# Draw icon in graphics mode
|
||||||
for i, bits in enumerate(icon):
|
self.write_graphics(x, y, icon[0])
|
||||||
self.write_graphics(x, y, i, [(bits >> 8) & 0xff, bits & 0xff])
|
self.write_graphics(x + 1, y, icon[1])
|
||||||
return 2
|
return 2
|
||||||
char = TextGlyphs.get(glyph_name)
|
char = TextGlyphs.get(glyph_name)
|
||||||
if char is not None:
|
if char is not None:
|
||||||
|
@ -163,8 +164,7 @@ class ST7920:
|
||||||
font = CharGlyphs.get(glyph_name)
|
font = CharGlyphs.get(glyph_name)
|
||||||
if font is not None:
|
if font is not None:
|
||||||
# Draw single width character
|
# Draw single width character
|
||||||
for i, bits in enumerate(font):
|
self.write_graphics(x, y, font)
|
||||||
self.write_graphics(x, y, i, [bits])
|
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
|
|
@ -57,6 +57,13 @@ class DisplayBase:
|
||||||
bits_top[col] |= ((data[row] >> (7 - col)) & 1) << row
|
bits_top[col] |= ((data[row] >> (7 - col)) & 1) << row
|
||||||
bits_bot[col] |= ((data[row + 8] >> (7 - col)) & 1) << row
|
bits_bot[col] |= ((data[row + 8] >> (7 - col)) & 1) << row
|
||||||
return (bits_top, bits_bot)
|
return (bits_top, bits_bot)
|
||||||
|
def set_glyphs(self, glyphs):
|
||||||
|
for glyph_name, glyph_data in glyphs.items():
|
||||||
|
icon = glyph_data.get('icon16x16')
|
||||||
|
if icon is not None:
|
||||||
|
top1, bot1 = self._swizzle_bits(icon[0])
|
||||||
|
top2, bot2 = self._swizzle_bits(icon[1])
|
||||||
|
self.icons[glyph_name] = (top1 + top2, bot1 + bot2)
|
||||||
def write_text(self, x, y, data):
|
def write_text(self, x, y, data):
|
||||||
if x + len(data) > 16:
|
if x + len(data) > 16:
|
||||||
data = data[:16 - min(x, 16)]
|
data = data[:16 - min(x, 16)]
|
||||||
|
@ -68,24 +75,16 @@ class DisplayBase:
|
||||||
page_top[pix_x:pix_x+8] = bits_top
|
page_top[pix_x:pix_x+8] = bits_top
|
||||||
page_bot[pix_x:pix_x+8] = bits_bot
|
page_bot[pix_x:pix_x+8] = bits_bot
|
||||||
pix_x += 8
|
pix_x += 8
|
||||||
def write_graphics(self, x, y, row, data):
|
def write_graphics(self, x, y, data):
|
||||||
if x + len(data) > 16:
|
if x >= 16 or y >= 4 or len(data) != 16:
|
||||||
data = data[:16 - min(x, 16)]
|
return
|
||||||
page = self.vram[y * 2 + (row >= 8)]
|
bits_top, bits_bot = self._swizzle_bits(data)
|
||||||
bit = 1 << (row % 8)
|
|
||||||
pix_x = x * 8
|
pix_x = x * 8
|
||||||
for bits in data:
|
page_top = self.vram[y * 2]
|
||||||
for col in range(8):
|
page_bot = self.vram[y * 2 + 1]
|
||||||
if (bits << col) & 0x80:
|
for i in range(8):
|
||||||
page[pix_x] ^= bit
|
page_top[pix_x + i] ^= bits_top[i]
|
||||||
pix_x += 1
|
page_bot[pix_x + i] ^= bits_bot[i]
|
||||||
def set_glyphs(self, glyphs):
|
|
||||||
for glyph_name, glyph_data in glyphs.items():
|
|
||||||
data = glyph_data.get('icon16x16')
|
|
||||||
if data is not None:
|
|
||||||
top1, bot1 = self._swizzle_bits([d >> 8 for d in data])
|
|
||||||
top2, bot2 = self._swizzle_bits(data)
|
|
||||||
self.icons[glyph_name] = (top1 + top2, bot1 + bot2)
|
|
||||||
def write_glyph(self, x, y, glyph_name):
|
def write_glyph(self, x, y, glyph_name):
|
||||||
icon = self.icons.get(glyph_name)
|
icon = self.icons.get(glyph_name)
|
||||||
if icon is not None and x < 15:
|
if icon is not None and x < 15:
|
||||||
|
|
Loading…
Reference in New Issue