extmod/modframebuf: Add support for monochrome horizontal format.
MHLSB and MHMSB formats are added to the framebuf module, which have 8 adjacent horizontal pixels represented in a single byte.
This commit is contained in:
parent
fb981107eb
commit
231cfc84a7
@ -53,6 +53,41 @@ typedef struct _mp_framebuf_p_t {
|
|||||||
fill_rect_t fill_rect;
|
fill_rect_t fill_rect;
|
||||||
} mp_framebuf_p_t;
|
} mp_framebuf_p_t;
|
||||||
|
|
||||||
|
// constants for formats
|
||||||
|
#define FRAMEBUF_MVLSB (0)
|
||||||
|
#define FRAMEBUF_RGB565 (1)
|
||||||
|
#define FRAMEBUF_GS4_HMSB (2)
|
||||||
|
#define FRAMEBUF_MHLSB (3)
|
||||||
|
#define FRAMEBUF_MHMSB (4)
|
||||||
|
|
||||||
|
// Functions for MHLSB and MHMSB
|
||||||
|
|
||||||
|
STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
||||||
|
size_t index = (x + y * fb->stride) >> 3;
|
||||||
|
int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
|
||||||
|
((uint8_t*)fb->buf)[index] = (((uint8_t*)fb->buf)[index] & ~(0x01 << offset)) | ((color != 0) << offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
|
||||||
|
size_t index = (x + y * fb->stride) >> 3;
|
||||||
|
int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
|
||||||
|
return (((uint8_t*)fb->buf)[index] >> (offset)) & 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
|
||||||
|
int reverse = fb->format == FRAMEBUF_MHMSB;
|
||||||
|
int advance = fb->stride >> 3;
|
||||||
|
while (w--) {
|
||||||
|
uint8_t *b = &((uint8_t*)fb->buf)[(x >> 3) + y * advance];
|
||||||
|
int offset = reverse ? x & 7 : 7 - (x & 7);
|
||||||
|
for (int hh = h; hh; --hh) {
|
||||||
|
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
|
||||||
|
b += advance;
|
||||||
|
}
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Functions for MVLSB format
|
// Functions for MVLSB format
|
||||||
|
|
||||||
STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
||||||
@ -148,15 +183,12 @@ STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// constants for formats
|
|
||||||
#define FRAMEBUF_MVLSB (0)
|
|
||||||
#define FRAMEBUF_RGB565 (1)
|
|
||||||
#define FRAMEBUF_GS4_HMSB (2)
|
|
||||||
|
|
||||||
STATIC mp_framebuf_p_t formats[] = {
|
STATIC mp_framebuf_p_t formats[] = {
|
||||||
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
||||||
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
||||||
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
||||||
|
[FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
||||||
|
[FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
||||||
@ -207,6 +239,10 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
case FRAMEBUF_RGB565:
|
case FRAMEBUF_RGB565:
|
||||||
case FRAMEBUF_GS4_HMSB:
|
case FRAMEBUF_GS4_HMSB:
|
||||||
break;
|
break;
|
||||||
|
case FRAMEBUF_MHLSB:
|
||||||
|
case FRAMEBUF_MHMSB:
|
||||||
|
o->stride = (o->stride + 7) & ~7;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||||
"invalid format"));
|
"invalid format"));
|
||||||
@ -545,6 +581,8 @@ STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB) },
|
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565) },
|
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB) },
|
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_MHLSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_MHMSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB) },
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
|
STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
|
||||||
|
@ -7,87 +7,96 @@ except ImportError:
|
|||||||
|
|
||||||
w = 5
|
w = 5
|
||||||
h = 16
|
h = 16
|
||||||
buf = bytearray(w * h // 8)
|
size = w * h // 8
|
||||||
fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.MVLSB)
|
buf = bytearray(size)
|
||||||
|
maps = {framebuf.MVLSB : 'MVLSB',
|
||||||
|
framebuf.MHLSB : 'MHLSB',
|
||||||
|
framebuf.MHMSB : 'MHMSB'}
|
||||||
|
|
||||||
# access as buffer
|
for mapping in maps.keys():
|
||||||
print(memoryview(fbuf)[0])
|
for x in range(size):
|
||||||
|
buf[x] = 0
|
||||||
|
fbuf = framebuf.FrameBuffer(buf, w, h, mapping)
|
||||||
|
print(maps[mapping])
|
||||||
|
# access as buffer
|
||||||
|
print(memoryview(fbuf)[0])
|
||||||
|
|
||||||
# fill
|
# fill
|
||||||
fbuf.fill(1)
|
fbuf.fill(1)
|
||||||
print(buf)
|
print(buf)
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
print(buf)
|
print(buf)
|
||||||
|
|
||||||
# put pixel
|
# put pixel
|
||||||
fbuf.pixel(0, 0, 1)
|
fbuf.pixel(0, 0, 1)
|
||||||
fbuf.pixel(4, 0, 1)
|
fbuf.pixel(4, 0, 1)
|
||||||
fbuf.pixel(0, 15, 1)
|
fbuf.pixel(0, 15, 1)
|
||||||
fbuf.pixel(4, 15, 1)
|
fbuf.pixel(4, 15, 1)
|
||||||
print(buf)
|
print(buf)
|
||||||
|
|
||||||
# clear pixel
|
# clear pixel
|
||||||
fbuf.pixel(4, 15, 0)
|
fbuf.pixel(4, 15, 0)
|
||||||
print(buf)
|
print(buf)
|
||||||
|
|
||||||
# get pixel
|
# get pixel
|
||||||
print(fbuf.pixel(0, 0), fbuf.pixel(1, 1))
|
print(fbuf.pixel(0, 0), fbuf.pixel(1, 1))
|
||||||
|
|
||||||
# hline
|
# hline
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.hline(0, 1, w, 1)
|
fbuf.hline(0, 1, w, 1)
|
||||||
print('hline', buf)
|
print('hline', buf)
|
||||||
|
|
||||||
# vline
|
# vline
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.vline(1, 0, h, 1)
|
fbuf.vline(1, 0, h, 1)
|
||||||
print('vline', buf)
|
print('vline', buf)
|
||||||
|
|
||||||
# rect
|
# rect
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.rect(1, 1, 3, 3, 1)
|
fbuf.rect(1, 1, 3, 3, 1)
|
||||||
print('rect', buf)
|
print('rect', buf)
|
||||||
|
|
||||||
#fill rect
|
#fill rect
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.fill_rect(0, 0, 0, 3, 1) # zero width, no-operation
|
fbuf.fill_rect(0, 0, 0, 3, 1) # zero width, no-operation
|
||||||
fbuf.fill_rect(1, 1, 3, 3, 1)
|
fbuf.fill_rect(1, 1, 3, 3, 1)
|
||||||
print('fill_rect', buf)
|
print('fill_rect', buf)
|
||||||
|
|
||||||
# line
|
# line
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.line(1, 1, 3, 3, 1)
|
fbuf.line(1, 1, 3, 3, 1)
|
||||||
print('line', buf)
|
print('line', buf)
|
||||||
|
|
||||||
# line steep negative gradient
|
# line steep negative gradient
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.line(3, 3, 2, 1, 1)
|
fbuf.line(3, 3, 2, 1, 1)
|
||||||
print('line', buf)
|
print('line', buf)
|
||||||
|
|
||||||
# scroll
|
# scroll
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.pixel(2, 7, 1)
|
fbuf.pixel(2, 7, 1)
|
||||||
fbuf.scroll(0, 1)
|
fbuf.scroll(0, 1)
|
||||||
print(buf)
|
print(buf)
|
||||||
fbuf.scroll(0, -2)
|
fbuf.scroll(0, -2)
|
||||||
print(buf)
|
print(buf)
|
||||||
fbuf.scroll(1, 0)
|
fbuf.scroll(1, 0)
|
||||||
print(buf)
|
print(buf)
|
||||||
fbuf.scroll(-1, 0)
|
fbuf.scroll(-1, 0)
|
||||||
print(buf)
|
print(buf)
|
||||||
fbuf.scroll(2, 2)
|
fbuf.scroll(2, 2)
|
||||||
print(buf)
|
print(buf)
|
||||||
|
|
||||||
# print text
|
# print text
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
fbuf.text("hello", 0, 0, 1)
|
fbuf.text("hello", 0, 0, 1)
|
||||||
print(buf)
|
print(buf)
|
||||||
fbuf.text("hello", 0, 0, 0) # clear
|
fbuf.text("hello", 0, 0, 0) # clear
|
||||||
print(buf)
|
print(buf)
|
||||||
|
|
||||||
# char out of font range set to chr(127)
|
# char out of font range set to chr(127)
|
||||||
fbuf.text(str(chr(31)), 0, 0)
|
fbuf.text(str(chr(31)), 0, 0)
|
||||||
print(buf)
|
print(buf)
|
||||||
|
print()
|
||||||
|
|
||||||
# test invalid constructor, and stride argument
|
# test invalid constructor, and stride argument
|
||||||
try:
|
try:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
MVLSB
|
||||||
0
|
0
|
||||||
bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
|
bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
|
||||||
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
@ -18,4 +19,49 @@ bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
|
|||||||
bytearray(b'\x00\x7f\x7f\x04\x04\x00\x00\x00\x00\x00')
|
bytearray(b'\x00\x7f\x7f\x04\x04\x00\x00\x00\x00\x00')
|
||||||
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
bytearray(b'\xaaU\xaaU\xaa\x00\x00\x00\x00\x00')
|
bytearray(b'\xaaU\xaaU\xaa\x00\x00\x00\x00\x00')
|
||||||
|
|
||||||
|
MHLSB
|
||||||
|
0
|
||||||
|
bytearray(b'\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
1 0
|
||||||
|
hline bytearray(b'\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
vline bytearray(b'@@@@@@@@@@')
|
||||||
|
rect bytearray(b'\x00pPp\x00\x00\x00\x00\x00\x00')
|
||||||
|
fill_rect bytearray(b'\x00ppp\x00\x00\x00\x00\x00\x00')
|
||||||
|
line bytearray(b'\x00@ \x10\x00\x00\x00\x00\x00\x00')
|
||||||
|
line bytearray(b'\x00 \x10\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00 \x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00')
|
||||||
|
bytearray(b'``x````\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'P\xa8P\xa8P\xa8P\xa8\x00\x00')
|
||||||
|
|
||||||
|
MHMSB
|
||||||
|
0
|
||||||
|
bytearray(b'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
1 0
|
||||||
|
hline bytearray(b'\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
vline bytearray(b'\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02')
|
||||||
|
rect bytearray(b'\x00\x0e\n\x0e\x00\x00\x00\x00\x00\x00')
|
||||||
|
fill_rect bytearray(b'\x00\x0e\x0e\x0e\x00\x00\x00\x00\x00\x00')
|
||||||
|
line bytearray(b'\x00\x02\x04\x08\x00\x00\x00\x00\x00\x00')
|
||||||
|
line bytearray(b'\x00\x04\x04\x08\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00')
|
||||||
|
bytearray(b'\x06\x06\x1e\x06\x06\x06\x06\x00\x00\x00')
|
||||||
|
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
bytearray(b'\n\x15\n\x15\n\x15\n\x15\x00\x00')
|
||||||
|
|
||||||
ValueError
|
ValueError
|
||||||
|
Loading…
x
Reference in New Issue
Block a user