mirror of
https://github.com/jtgans/g13gui.git
synced 2025-06-20 00:14:09 -04:00
g13gui: Add LPBM image conversion and tests
This is the first step to actually rendering to the G13's display by way of the g13d daemon. The bitmap format is kinda weird: it's actually 860 bytes of useable pixel data, but padded out to 960. Each byte corresponds with one vertical column of 8-pixels, going from top to bottom. The tests for this effectively check to make sure the length is correct, and also dumps it out to a running g13d (if there is one). This should probably be automated a bit more by checking the bytes directly, but given that this is a visual task anyway, I'm being a bit lazy.
This commit is contained in:
parent
a38048ea9f
commit
aeced13908
@ -1,3 +1,4 @@
|
||||
from g13gui.bitwidgets.display import Fonts
|
||||
from g13gui.bitwidgets.display import FontManager
|
||||
from g13gui.bitwidgets.fonts import Fonts
|
||||
from g13gui.bitwidgets.fonts import FontManager
|
||||
from g13gui.bitwidgets.display import Display
|
||||
from g13gui.bitwidgets.display import DisplayMetrics
|
||||
|
@ -1,12 +1,51 @@
|
||||
import struct
|
||||
import PIL.ImageDraw
|
||||
import PIL.PyAccess
|
||||
import sys
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
from PIL.ImageDraw import ImageDraw
|
||||
from g13gui.observer import Subject
|
||||
from g13gui.observer import ChangeType
|
||||
|
||||
|
||||
class DisplayMetrics(object):
|
||||
WIDTH_PIXELS = 160
|
||||
HEIGHT_PIXELS = 48
|
||||
HEIGHT_PIXELS = 43
|
||||
|
||||
|
||||
LPBM_LENGTH = 960
|
||||
|
||||
|
||||
def ImageToLPBM(image):
|
||||
i = PIL.PyAccess.new(image, readonly=True)
|
||||
bio = BytesIO()
|
||||
|
||||
maxBytes = (DisplayMetrics.WIDTH_PIXELS * DisplayMetrics.HEIGHT_PIXELS // 8)
|
||||
row = 0
|
||||
col = 0
|
||||
|
||||
for byteNum in range(0, maxBytes):
|
||||
b = int()
|
||||
|
||||
if row == 40:
|
||||
maxSubrow = 3
|
||||
else:
|
||||
maxSubrow = 8
|
||||
|
||||
for subrow in range(0, maxSubrow):
|
||||
b |= i[col, row + subrow] << subrow
|
||||
|
||||
bio.write(struct.pack('<B', b))
|
||||
|
||||
col += 1
|
||||
if (col % 160) == 0:
|
||||
col = 0
|
||||
row += 8
|
||||
|
||||
# padding? lpbm files are always 960 bytes, the last bytes are filled with garbage.
|
||||
bio.write(bytes(LPBM_LENGTH - maxBytes))
|
||||
|
||||
return bio.getvalue()
|
||||
|
||||
|
||||
class Display(Subject):
|
||||
@ -17,7 +56,7 @@ class Display(Subject):
|
||||
DisplayMetrics.HEIGHT_PIXELS))
|
||||
|
||||
def getContext(self):
|
||||
return ImageDraw.Draw(self._bitmap)
|
||||
return PIL.ImageDraw.Draw(self._bitmap)
|
||||
|
||||
def commit(self):
|
||||
# convert to LPBM
|
||||
|
@ -1,20 +1,29 @@
|
||||
import unittest
|
||||
|
||||
import PIL.Image
|
||||
|
||||
from g13gui.bitwidgets.display import LPBM_LENGTH
|
||||
from g13gui.bitwidgets.display import ImageToLPBM
|
||||
from g13gui.bitwidgets import Fonts
|
||||
from g13gui.bitwidgets import FontManager
|
||||
from g13gui.bitwidgets import Display
|
||||
from g13gui.bitwidgets import DisplayMetrics
|
||||
|
||||
|
||||
d = Display()
|
||||
ctx = d.getContext()
|
||||
ctx.text((0, 0), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.TINY),
|
||||
fill=(1))
|
||||
ctx.text((0, 6), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.MEDIUM),
|
||||
fill=(1))
|
||||
ctx.text((0, 11), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.LARGE),
|
||||
fill=(1))
|
||||
ctx.text((0, 19), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.HUGE),
|
||||
fill=(1))
|
||||
d.debug()
|
||||
class DisplayTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.d = Display()
|
||||
|
||||
def testConversion(self):
|
||||
ctx = self.d.getContext()
|
||||
ctx.text((0, 0), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.HUGE), fill=1)
|
||||
result = ImageToLPBM(self.d._bitmap)
|
||||
|
||||
self.assertEqual(len(result), LPBM_LENGTH)
|
||||
|
||||
with open('/run/g13d/in', 'wb') as fp:
|
||||
fp.write(result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -26,9 +26,10 @@ X11_FONT_PATH = pathlib.Path('/usr/share/fonts/X11/misc')
|
||||
|
||||
class Fonts(enum.Enum):
|
||||
TINY = X11_FONT_PATH / '4x6.pcf.gz'
|
||||
MEDIUM = X11_FONT_PATH / '5x7.pcf.gz'
|
||||
LARGE = X11_FONT_PATH / '8x13.pcf.gz'
|
||||
HUGE = X11_FONT_PATH / '9x18.pcf.gz'
|
||||
SMALL = X11_FONT_PATH / '5x7.pcf.gz'
|
||||
MEDIUM = X11_FONT_PATH / '8x13.pcf.gz'
|
||||
LARGE = X11_FONT_PATH / '9x18.pcf.gz'
|
||||
HUGE = X11_FONT_PATH / '10x20.pcf.gz'
|
||||
|
||||
|
||||
class PcfFontConverter(PcfFontFile):
|
||||
|
33
g13gui/g13gui/bitwidgets/fonts_tests.py
Normal file
33
g13gui/g13gui/bitwidgets/fonts_tests.py
Normal file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import unittest
|
||||
|
||||
from g13gui.bitwidgets import Fonts
|
||||
from g13gui.bitwidgets import FontManager
|
||||
from g13gui.bitwidgets import Display
|
||||
|
||||
|
||||
class FontsTests(unittest.TestCase):
|
||||
def testFontDrawing(self):
|
||||
d = Display()
|
||||
ctx = d.getContext()
|
||||
ctx.text((0, 0), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.TINY),
|
||||
fill=(1))
|
||||
ctx.text((0, 6), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.SMALL),
|
||||
fill=(1))
|
||||
ctx.text((0, 11), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.MEDIUM),
|
||||
fill=(1))
|
||||
ctx.text((0, 19), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.LARGE),
|
||||
fill=(1))
|
||||
ctx.text((0, 31), "Hello world!",
|
||||
font=FontManager.getFont(Fonts.HUGE),
|
||||
fill=(1))
|
||||
d.debug()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user