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.fonts import Fonts
|
||||||
from g13gui.bitwidgets.display import FontManager
|
from g13gui.bitwidgets.fonts import FontManager
|
||||||
from g13gui.bitwidgets.display import Display
|
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 import Image
|
||||||
from PIL.ImageDraw import ImageDraw
|
|
||||||
from g13gui.observer import Subject
|
from g13gui.observer import Subject
|
||||||
from g13gui.observer import ChangeType
|
from g13gui.observer import ChangeType
|
||||||
|
|
||||||
|
|
||||||
class DisplayMetrics(object):
|
class DisplayMetrics(object):
|
||||||
WIDTH_PIXELS = 160
|
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):
|
class Display(Subject):
|
||||||
@ -17,7 +56,7 @@ class Display(Subject):
|
|||||||
DisplayMetrics.HEIGHT_PIXELS))
|
DisplayMetrics.HEIGHT_PIXELS))
|
||||||
|
|
||||||
def getContext(self):
|
def getContext(self):
|
||||||
return ImageDraw.Draw(self._bitmap)
|
return PIL.ImageDraw.Draw(self._bitmap)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
# convert to LPBM
|
# 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 Fonts
|
||||||
from g13gui.bitwidgets import FontManager
|
from g13gui.bitwidgets import FontManager
|
||||||
from g13gui.bitwidgets import Display
|
from g13gui.bitwidgets import Display
|
||||||
|
from g13gui.bitwidgets import DisplayMetrics
|
||||||
|
|
||||||
|
|
||||||
d = Display()
|
class DisplayTests(unittest.TestCase):
|
||||||
ctx = d.getContext()
|
def setUp(self):
|
||||||
ctx.text((0, 0), "Hello world!",
|
self.d = Display()
|
||||||
font=FontManager.getFont(Fonts.TINY),
|
|
||||||
fill=(1))
|
def testConversion(self):
|
||||||
ctx.text((0, 6), "Hello world!",
|
ctx = self.d.getContext()
|
||||||
font=FontManager.getFont(Fonts.MEDIUM),
|
ctx.text((0, 0), "Hello world!",
|
||||||
fill=(1))
|
font=FontManager.getFont(Fonts.HUGE), fill=1)
|
||||||
ctx.text((0, 11), "Hello world!",
|
result = ImageToLPBM(self.d._bitmap)
|
||||||
font=FontManager.getFont(Fonts.LARGE),
|
|
||||||
fill=(1))
|
self.assertEqual(len(result), LPBM_LENGTH)
|
||||||
ctx.text((0, 19), "Hello world!",
|
|
||||||
font=FontManager.getFont(Fonts.HUGE),
|
with open('/run/g13d/in', 'wb') as fp:
|
||||||
fill=(1))
|
fp.write(result)
|
||||||
d.debug()
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
@ -26,9 +26,10 @@ X11_FONT_PATH = pathlib.Path('/usr/share/fonts/X11/misc')
|
|||||||
|
|
||||||
class Fonts(enum.Enum):
|
class Fonts(enum.Enum):
|
||||||
TINY = X11_FONT_PATH / '4x6.pcf.gz'
|
TINY = X11_FONT_PATH / '4x6.pcf.gz'
|
||||||
MEDIUM = X11_FONT_PATH / '5x7.pcf.gz'
|
SMALL = X11_FONT_PATH / '5x7.pcf.gz'
|
||||||
LARGE = X11_FONT_PATH / '8x13.pcf.gz'
|
MEDIUM = X11_FONT_PATH / '8x13.pcf.gz'
|
||||||
HUGE = X11_FONT_PATH / '9x18.pcf.gz'
|
LARGE = X11_FONT_PATH / '9x18.pcf.gz'
|
||||||
|
HUGE = X11_FONT_PATH / '10x20.pcf.gz'
|
||||||
|
|
||||||
|
|
||||||
class PcfFontConverter(PcfFontFile):
|
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