1 /*
2 * This file is part of the MicroPython project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2016 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26 // Modified bt HaaS begin
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "py/runtime.h"
31
32 #include "py/objstr.h"
33
34 #include "ulog/ulog.h"
35
36 #if MICROPY_PY_FRAMEBUF
37
38 #include "./font_petme128_8x8.h"
39
40 #define LOG_TAG "MOD_FRAMEBUF"
41
42
43 typedef struct _mp_obj_framebuf_t {
44 mp_obj_base_t base;
45 mp_obj_t buf_obj; // need to store this to prevent GC from reclaiming buf
46 void *buf;
47 uint16_t width, height, stride;
48 uint8_t format;
49 } mp_obj_framebuf_t;
50
51 typedef struct {
52 char *font_path;
53 FILE* fp;
54 unsigned char font_height;
55 unsigned char font_width;
56 unsigned char is_cn;
57 } font_t;
58
59 // #if !MICROPY_ENABLE_DYNRUNTIME
60 STATIC const mp_obj_type_t mp_type_framebuf;
61 // #endif
62
63 typedef void (*setpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, uint32_t);
64 typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int);
65 typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, unsigned int, unsigned int, uint32_t);
66
67 typedef struct _mp_framebuf_p_t {
68 setpixel_t setpixel;
69 getpixel_t getpixel;
70 fill_rect_t fill_rect;
71 } mp_framebuf_p_t;
72
73 // constants for formats
74 #define FRAMEBUF_MVLSB (0)
75 #define FRAMEBUF_RGB565 (1)
76 #define FRAMEBUF_GS2_HMSB (5)
77 #define FRAMEBUF_GS4_HMSB (2)
78 #define FRAMEBUF_GS8 (6)
79 #define FRAMEBUF_MHLSB (3)
80 #define FRAMEBUF_MHMSB (4)
81
82 // constants for fonts
83 // 支持中英文 12-32
84 #define FONT_ASC8_8 (808)
85 #define FONT_ASC12_8 (1208)
86 #define FONT_PATH_ASC12_8 "/data/font/ASC12_8"
87 #define FONT_ASC16_8 (1608)
88 #define FONT_PATH_ASC16_8 "/data/font/ASC16_8"
89 #define FONT_ASC24_12 (2412)
90 #define FONT_PATH_ASC24_12 "/data/font/ASC24_12"
91 #define FONT_ASC32_16 (3216)
92 #define FONT_PATH_ASC32_16 "/data/font/ASC32_16"
93 // #define FONT_ASC48_24 (48)
94 // #define FONT_PATH_ASC48_24 "./font/ASC48_24"
95 #define FONT_HZK12 (1212)
96 #define FONT_PATH_HZK12 "/data/font/HZK12"
97 #define FONT_HZK16 (1616)
98 #define FONT_PATH_HZK16 "/data/font/HZK16"
99 #define FONT_HZK24 (2424)
100 #define FONT_PATH_HZK24 "/data/font/HZK24"
101 #define FONT_HZK32 (3232)
102 #define FONT_PATH_HZK32 "/data/font/HZK32"
103
104 static font_t ASC8_8 = {NULL, NULL, 8, 8, 0};
105 static font_t ASC12_8 = {FONT_PATH_ASC12_8, NULL, 12, 8, 0};
106 static font_t ASC16_8 = {FONT_PATH_ASC16_8, NULL, 16, 8, 0};
107 static font_t ASC24_12 = {FONT_PATH_ASC24_12, NULL, 24, 12, 0};
108 static font_t ASC32_16 = {FONT_PATH_ASC32_16, NULL, 32, 16, 0};
109
110 static font_t HZK12 = {FONT_PATH_HZK12, NULL, 12, 12, 1};
111 static font_t HZK16 = {FONT_PATH_HZK16, NULL, 16, 16, 1};
112 static font_t HZK24 = {FONT_PATH_HZK24, NULL, 24, 24, 1};
113 static font_t HZK32 = {FONT_PATH_HZK32, NULL, 32, 32, 1};
114
115 // Functions for MHLSB and MHMSB
116
mono_horiz_setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)117 STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
118 size_t index = (x + y * fb->stride) >> 3;
119 unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
120 ((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
121 }
122
mono_horiz_getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)123 STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
124 size_t index = (x + y * fb->stride) >> 3;
125 unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
126 return (((uint8_t *)fb->buf)[index] >> (offset)) & 0x01;
127 }
128
mono_horiz_fill_rect(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,unsigned int w,unsigned int h,uint32_t col)129 STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
130 unsigned int reverse = fb->format == FRAMEBUF_MHMSB;
131 unsigned int advance = fb->stride >> 3;
132 while (w--) {
133 uint8_t *b = &((uint8_t *)fb->buf)[(x >> 3) + y * advance];
134 unsigned int offset = reverse ? x & 7 : 7 - (x & 7);
135 for (unsigned int hh = h; hh; --hh) {
136 *b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
137 b += advance;
138 }
139 ++x;
140 }
141 }
142
143 // Functions for MVLSB format
144
mvlsb_setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)145 STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
146 size_t index = (y >> 3) * fb->stride + x;
147 uint8_t offset = y & 0x07;
148 ((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
149 }
150
mvlsb_getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)151 STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
152 return (((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01;
153 }
154
mvlsb_fill_rect(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,unsigned int w,unsigned int h,uint32_t col)155 STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
156 while (h--) {
157 uint8_t *b = &((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x];
158 uint8_t offset = y & 0x07;
159 for (unsigned int ww = w; ww; --ww) {
160 *b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
161 ++b;
162 }
163 ++y;
164 }
165 }
166
167 // Functions for RGB565 format
168
rgb565_setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)169 STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
170 ((uint16_t *)fb->buf)[x + y * fb->stride] = col;
171 }
172
rgb565_getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)173 STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
174 return ((uint16_t *)fb->buf)[x + y * fb->stride];
175 }
176
rgb565_fill_rect(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,unsigned int w,unsigned int h,uint32_t col)177 STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
178 uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride];
179 while (h--) {
180 for (unsigned int ww = w; ww; --ww) {
181 *b++ = col;
182 }
183 b += fb->stride - w;
184 }
185 }
186
187 // Functions for GS2_HMSB format
188
gs2_hmsb_setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)189 STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
190 uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
191 uint8_t shift = (x & 0x3) << 1;
192 uint8_t mask = 0x3 << shift;
193 uint8_t color = (col & 0x3) << shift;
194 *pixel = color | (*pixel & (~mask));
195 }
196
gs2_hmsb_getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)197 STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
198 uint8_t pixel = ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
199 uint8_t shift = (x & 0x3) << 1;
200 return (pixel >> shift) & 0x3;
201 }
202
gs2_hmsb_fill_rect(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,unsigned int w,unsigned int h,uint32_t col)203 STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
204 for (unsigned int xx = x; xx < x + w; xx++) {
205 for (unsigned int yy = y; yy < y + h; yy++) {
206 gs2_hmsb_setpixel(fb, xx, yy, col);
207 }
208 }
209 }
210
211 // Functions for GS4_HMSB format
212
gs4_hmsb_setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)213 STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
214 uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
215
216 if (x % 2) {
217 *pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0);
218 } else {
219 *pixel = ((uint8_t)col << 4) | (*pixel & 0x0f);
220 }
221 }
222
gs4_hmsb_getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)223 STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
224 if (x % 2) {
225 return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f;
226 }
227
228 return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] >> 4;
229 }
230
gs4_hmsb_fill_rect(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,unsigned int w,unsigned int h,uint32_t col)231 STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
232 col &= 0x0f;
233 uint8_t *pixel_pair = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
234 uint8_t col_shifted_left = col << 4;
235 uint8_t col_pixel_pair = col_shifted_left | col;
236 unsigned int pixel_count_till_next_line = (fb->stride - w) >> 1;
237 bool odd_x = (x % 2 == 1);
238
239 while (h--) {
240 unsigned int ww = w;
241
242 if (odd_x && ww > 0) {
243 *pixel_pair = (*pixel_pair & 0xf0) | col;
244 pixel_pair++;
245 ww--;
246 }
247
248 memset(pixel_pair, col_pixel_pair, ww >> 1);
249 pixel_pair += ww >> 1;
250
251 if (ww % 2) {
252 *pixel_pair = col_shifted_left | (*pixel_pair & 0x0f);
253 if (!odd_x) {
254 pixel_pair++;
255 }
256 }
257
258 pixel_pair += pixel_count_till_next_line;
259 }
260 }
261
262 // Functions for GS8 format
263
gs8_setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)264 STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
265 uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
266 *pixel = col & 0xff;
267 }
268
gs8_getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)269 STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
270 return ((uint8_t *)fb->buf)[(x + y * fb->stride)];
271 }
272
gs8_fill_rect(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,unsigned int w,unsigned int h,uint32_t col)273 STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
274 uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
275 while (h--) {
276 memset(pixel, col, w);
277 pixel += fb->stride;
278 }
279 }
280
281 STATIC mp_framebuf_p_t formats[] = {
282 [FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
283 [FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
284 [FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
285 [FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
286 [FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect},
287 [FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
288 [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
289 };
290
setpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y,uint32_t col)291 static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
292 formats[fb->format].setpixel(fb, x, y, col);
293 }
294
getpixel(const mp_obj_framebuf_t * fb,unsigned int x,unsigned int y)295 static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
296 return formats[fb->format].getpixel(fb, x, y);
297 }
298
fill_rect(const mp_obj_framebuf_t * fb,int x,int y,int w,int h,uint32_t col)299 STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
300 if (h < 1 || w < 1 || x + w <= 0 || y + h <= 0 || y >= fb->height || x >= fb->width) {
301 // No operation needed.
302 return;
303 }
304
305 // clip to the framebuffer
306 int xend = MIN(fb->width, x + w);
307 int yend = MIN(fb->height, y + h);
308 x = MAX(x, 0);
309 y = MAX(y, 0);
310
311 formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col);
312 }
313
framebuf_make_new(const mp_obj_type_t * type,size_t n_args,size_t n_kw,const mp_obj_t * args)314 STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
315 mp_arg_check_num(n_args, n_kw, 4, 5, false);
316
317 mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
318 o->base.type = type;
319 o->buf_obj = args[0];
320
321 mp_buffer_info_t bufinfo;
322 mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE);
323 o->buf = bufinfo.buf;
324
325 o->width = mp_obj_get_int(args[1]);
326 o->height = mp_obj_get_int(args[2]);
327 o->format = mp_obj_get_int(args[3]);
328 if (n_args >= 5) {
329 o->stride = mp_obj_get_int(args[4]);
330 } else {
331 o->stride = o->width;
332 }
333
334 switch (o->format) {
335 case FRAMEBUF_MVLSB:
336 case FRAMEBUF_RGB565:
337 break;
338 case FRAMEBUF_MHLSB:
339 case FRAMEBUF_MHMSB:
340 o->stride = (o->stride + 7) & ~7;
341 break;
342 case FRAMEBUF_GS2_HMSB:
343 o->stride = (o->stride + 3) & ~3;
344 break;
345 case FRAMEBUF_GS4_HMSB:
346 o->stride = (o->stride + 1) & ~1;
347 break;
348 case FRAMEBUF_GS8:
349 break;
350 default:
351 mp_raise_ValueError(MP_ERROR_TEXT("invalid format"));
352 }
353
354 return MP_OBJ_FROM_PTR(o);
355 }
356
framebuf_get_buffer(mp_obj_t self_in,mp_buffer_info_t * bufinfo,mp_uint_t flags)357 STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
358 (void)flags;
359 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
360 bufinfo->buf = self->buf;
361 bufinfo->len = self->stride * self->height * (self->format == FRAMEBUF_RGB565 ? 2 : 1);
362 bufinfo->typecode = 'B'; // view framebuf as bytes
363 return 0;
364 }
365
framebuf_fill(mp_obj_t self_in,mp_obj_t col_in)366 STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) {
367 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
368 mp_int_t col = mp_obj_get_int(col_in);
369 formats[self->format].fill_rect(self, 0, 0, self->width, self->height, col);
370 return mp_const_none;
371 }
372 STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill);
373
framebuf_fill_rect(size_t n_args,const mp_obj_t * args)374 STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
375 (void)n_args;
376
377 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
378 mp_int_t x = mp_obj_get_int(args[1]);
379 mp_int_t y = mp_obj_get_int(args[2]);
380 mp_int_t width = mp_obj_get_int(args[3]);
381 mp_int_t height = mp_obj_get_int(args[4]);
382 mp_int_t col = mp_obj_get_int(args[5]);
383
384 fill_rect(self, x, y, width, height, col);
385
386 return mp_const_none;
387 }
388 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect);
389
framebuf_pixel(size_t n_args,const mp_obj_t * args)390 STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) {
391 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
392 mp_int_t x = mp_obj_get_int(args[1]);
393 mp_int_t y = mp_obj_get_int(args[2]);
394 if (0 <= x && x < self->width && 0 <= y && y < self->height) {
395 if (n_args == 3) {
396 // get
397 return MP_OBJ_NEW_SMALL_INT(getpixel(self, x, y));
398 } else {
399 // set
400 setpixel(self, x, y, mp_obj_get_int(args[3]));
401 }
402 }
403 return mp_const_none;
404 }
405 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pixel);
406
framebuf_hline(size_t n_args,const mp_obj_t * args)407 STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) {
408 (void)n_args;
409
410 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
411 mp_int_t x = mp_obj_get_int(args[1]);
412 mp_int_t y = mp_obj_get_int(args[2]);
413 mp_int_t w = mp_obj_get_int(args[3]);
414 mp_int_t col = mp_obj_get_int(args[4]);
415
416 fill_rect(self, x, y, w, 1, col);
417
418 return mp_const_none;
419 }
420 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hline);
421
framebuf_vline(size_t n_args,const mp_obj_t * args)422 STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) {
423 (void)n_args;
424
425 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
426 mp_int_t x = mp_obj_get_int(args[1]);
427 mp_int_t y = mp_obj_get_int(args[2]);
428 mp_int_t h = mp_obj_get_int(args[3]);
429 mp_int_t col = mp_obj_get_int(args[4]);
430
431 fill_rect(self, x, y, 1, h, col);
432
433 return mp_const_none;
434 }
435 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vline);
436
framebuf_rect(size_t n_args,const mp_obj_t * args)437 STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) {
438 (void)n_args;
439
440 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
441 mp_int_t x = mp_obj_get_int(args[1]);
442 mp_int_t y = mp_obj_get_int(args[2]);
443 mp_int_t w = mp_obj_get_int(args[3]);
444 mp_int_t h = mp_obj_get_int(args[4]);
445 mp_int_t col = mp_obj_get_int(args[5]);
446
447 fill_rect(self, x, y, w, 1, col);
448 fill_rect(self, x, y + h - 1, w, 1, col);
449 fill_rect(self, x, y, 1, h, col);
450 fill_rect(self, x + w - 1, y, 1, h, col);
451
452 return mp_const_none;
453 }
454 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rect);
455
framebuf_line(size_t n_args,const mp_obj_t * args)456 STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
457 (void)n_args;
458
459 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
460 mp_int_t x1 = mp_obj_get_int(args[1]);
461 mp_int_t y1 = mp_obj_get_int(args[2]);
462 mp_int_t x2 = mp_obj_get_int(args[3]);
463 mp_int_t y2 = mp_obj_get_int(args[4]);
464 mp_int_t col = mp_obj_get_int(args[5]);
465
466 mp_int_t dx = x2 - x1;
467 mp_int_t sx;
468 if (dx > 0) {
469 sx = 1;
470 } else {
471 dx = -dx;
472 sx = -1;
473 }
474
475 mp_int_t dy = y2 - y1;
476 mp_int_t sy;
477 if (dy > 0) {
478 sy = 1;
479 } else {
480 dy = -dy;
481 sy = -1;
482 }
483
484 bool steep;
485 if (dy > dx) {
486 mp_int_t temp;
487 temp = x1;
488 x1 = y1;
489 y1 = temp;
490 temp = dx;
491 dx = dy;
492 dy = temp;
493 temp = sx;
494 sx = sy;
495 sy = temp;
496 steep = true;
497 } else {
498 steep = false;
499 }
500
501 mp_int_t e = 2 * dy - dx;
502 for (mp_int_t i = 0; i < dx; ++i) {
503 if (steep) {
504 if (0 <= y1 && y1 < self->width && 0 <= x1 && x1 < self->height) {
505 setpixel(self, y1, x1, col);
506 }
507 } else {
508 if (0 <= x1 && x1 < self->width && 0 <= y1 && y1 < self->height) {
509 setpixel(self, x1, y1, col);
510 }
511 }
512 while (e >= 0) {
513 y1 += sy;
514 e -= 2 * dx;
515 }
516 x1 += sx;
517 e += 2 * dy;
518 }
519
520 if (0 <= x2 && x2 < self->width && 0 <= y2 && y2 < self->height) {
521 setpixel(self, x2, y2, col);
522 }
523
524 return mp_const_none;
525 }
526 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line);
527
framebuf_blit(size_t n_args,const mp_obj_t * args)528 STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
529 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
530 mp_obj_t source_in = mp_obj_cast_to_native_base(args[1], MP_OBJ_FROM_PTR(&mp_type_framebuf));
531 if (source_in == MP_OBJ_NULL) {
532 mp_raise_TypeError(NULL);
533 }
534 mp_obj_framebuf_t *source = MP_OBJ_TO_PTR(source_in);
535
536 mp_int_t x = mp_obj_get_int(args[2]);
537 mp_int_t y = mp_obj_get_int(args[3]);
538 mp_int_t key = -1;
539 if (n_args > 4) {
540 key = mp_obj_get_int(args[4]);
541 }
542
543 if (
544 (x >= self->width) ||
545 (y >= self->height) ||
546 (-x >= source->width) ||
547 (-y >= source->height)
548 ) {
549 // Out of bounds, no-op.
550 return mp_const_none;
551 }
552
553 // Clip.
554 int x0 = MAX(0, x);
555 int y0 = MAX(0, y);
556 int x1 = MAX(0, -x);
557 int y1 = MAX(0, -y);
558 int x0end = MIN(self->width, x + source->width);
559 int y0end = MIN(self->height, y + source->height);
560
561 for (; y0 < y0end; ++y0) {
562 int cx1 = x1;
563 for (int cx0 = x0; cx0 < x0end; ++cx0) {
564 uint32_t col = getpixel(source, cx1, y1);
565 if (col != (uint32_t)key) {
566 setpixel(self, cx0, y0, col);
567 }
568 ++cx1;
569 }
570 ++y1;
571 }
572 return mp_const_none;
573 }
574 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 5, framebuf_blit);
575
framebuf_scroll(mp_obj_t self_in,mp_obj_t xstep_in,mp_obj_t ystep_in)576 STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) {
577 mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
578 mp_int_t xstep = mp_obj_get_int(xstep_in);
579 mp_int_t ystep = mp_obj_get_int(ystep_in);
580 int sx, y, xend, yend, dx, dy;
581 if (xstep < 0) {
582 sx = 0;
583 xend = self->width + xstep;
584 dx = 1;
585 } else {
586 sx = self->width - 1;
587 xend = xstep - 1;
588 dx = -1;
589 }
590 if (ystep < 0) {
591 y = 0;
592 yend = self->height + ystep;
593 dy = 1;
594 } else {
595 y = self->height - 1;
596 yend = ystep - 1;
597 dy = -1;
598 }
599 for (; y != yend; y += dy) {
600 for (int x = sx; x != xend; x += dx) {
601 setpixel(self, x, y, getpixel(self, x - xstep, y - ystep));
602 }
603 }
604 return mp_const_none;
605 }
606 STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll);
607
hz_get_mat(font_t * font,char * chr,unsigned char * mat)608 STATIC unsigned char hz_get_mat(font_t* font, char * chr, unsigned char * mat) {
609
610 unsigned char font_width;
611 if(font == &HZK12){
612 font_width = 16;
613 }else{
614 font_width = font->font_width;
615 }
616
617 unsigned char size = font->font_height;
618 unsigned char offset_step = (font->font_height * font_width / 8);
619 unsigned long offset = 0;
620
621 int t1 = (int) (*(chr) & 0xff);
622 int t2 = (int) (*(chr + 1) & 0xff);
623
624 if (t1 > 0xa0) {
625 if (size == 40 || size == 48) {
626 offset = ((t1 - 0xa1 - 0x0f) * 94 + (t2 - 0xa1)) * offset_step;
627 } else if (size == 12 || size == 16 || size == 24 || size == 32) {
628 offset = ((t1 - 0xa1) * 94 + (t2 - 0xa1)) * offset_step;
629 }
630 } else {
631 offset = (t1 + 156 - 1) * offset_step;
632 }
633
634 if(font->fp == NULL){
635 font->fp = fopen(font->font_path , "rb");
636 if(font->fp == NULL){
637 LOGE(LOG_TAG,"error no font file %s\n", font->font_path);
638 memset(mat, 0, offset_step);
639 return 0;
640 }
641 }
642
643 fseek(font->fp, offset, SEEK_SET);
644 fread(mat, offset_step, 1, font->fp);
645
646 return 1;
647 }
648
hz_print_mat(mp_obj_framebuf_t * self,mp_int_t x,mp_int_t y,mp_int_t col,font_t * font,unsigned char * mat,mp_int_t zoom)649 STATIC void hz_print_mat(mp_obj_framebuf_t *self, mp_int_t x, mp_int_t y, mp_int_t col, font_t* font, unsigned char * mat, mp_int_t zoom) {
650 char key[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
651 if (font->font_height == 40 || font->font_height == 48) {
652 for (int i = 0; i < font->font_height; i++) {
653 for (int j = 0; j < font->font_width; j++) {
654 int index = i * font->font_width + j;
655 int flag = mat[index / 8] & key[index % 8];
656 if(flag > 0){
657 for(int r = 0; r < zoom; r++) {
658 setpixel(self, x + j * zoom + r, y + i * zoom, col);
659 for(int r = 0; r < zoom; r++) {
660 setpixel(self, x + j * zoom, y + i * zoom + r, col);
661 }
662 }
663 }
664 }
665 }
666 } else if (font->font_height == 16 || font->font_height == 24 || font->font_height == 32) {
667 for (int i = 0; i < font->font_height; i++) {
668 for (int j = 0; j < font->font_width; j++) {
669 int index = j * font->font_width + i;
670 int flag = mat[index / 8] & key[index % 8];
671 if(flag > 0){
672 for(int r = 0; r < zoom; r++) {
673 setpixel(self, x + j * zoom + r, y + i * zoom, col);
674 for(int r = 0; r < zoom; r++) {
675 setpixel(self, x + j * zoom, y + i * zoom + r, col);
676 }
677 }
678 }
679 }
680 }
681 } else if (font->font_height == 12) {
682 for (int i = 0; i < 12; i++) {
683 for (int j = 0; j < 12; j++) {
684 int index = j * 16 + i;
685 int flag = mat[index / 8] & key[index % 8];
686 if(flag > 0){
687 for(int r = 0; r < zoom; r++) {
688 setpixel(self, x + j * zoom + r, y + i * zoom, col);
689 for(int r = 0; r < zoom; r++) {
690 setpixel(self, x + j * zoom, y + i * zoom + r, col);
691 }
692 }
693 }
694 }
695 }
696 }
697 }
698
asc_get_mat(font_t * font,char * chr,unsigned char * mat)699 STATIC unsigned char asc_get_mat(font_t* font, char * chr, unsigned char * mat){
700 int ascii = (int) (*chr);
701 if (ascii > 127 || ascii < 32) {
702 LOGE(LOG_TAG,"error : input char is invaild!");
703 return;
704 }
705
706 unsigned char offset_step = (font->font_width * font->font_height / 8);
707 long offset = (ascii - 32) * offset_step;
708
709 if(font->fp == NULL){
710 font->fp = fopen(font->font_path , "rb");
711 if(font->fp == NULL){
712 LOGE(LOG_TAG,"error no font file %s\n", font->font_path);
713 memset(mat, 0, offset_step);
714 return 0;
715 }
716 }
717
718 fseek(font->fp, offset, SEEK_SET);
719 fread(mat, offset_step, 1, font->fp);
720
721 return 1;
722 }
723
asc_print_mat(mp_obj_framebuf_t * self,mp_int_t x,mp_int_t y,mp_int_t col,font_t * font,unsigned char * mat,mp_int_t zoom)724 STATIC void asc_print_mat(mp_obj_framebuf_t *self, mp_int_t x, mp_int_t y, mp_int_t col, font_t* font, unsigned char * mat, mp_int_t zoom) {
725 char key[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
726 if (font->font_height == 12 || font->font_height == 48) {
727 for (int i = 0; i < font->font_height; i++) {
728 for (int j = 0; j < font->font_width; j++) {
729 int index = i * font->font_width + j;
730 int flag = mat[index / 8] & key[index % 8];
731 if(flag > 0){
732 for(int r = 0; r < zoom; r++) {
733 setpixel(self, x + j * zoom + r, y + i * zoom, col);
734 for(int r = 0; r < zoom; r++) {
735 setpixel(self, x + j * zoom, y + i * zoom + r, col);
736 }
737 }
738 }
739 }
740 }
741 } else {
742 for (int i = 0; i < font->font_height; i++) {
743 for (int j = 0; j < font->font_width; j++) {
744 int index = j * font->font_height + i;
745 int flag = mat[index / 8] & key[index % 8];
746 if(flag > 0){
747 for(int r = 0; r < zoom; r++) {
748 setpixel(self, x + j * zoom + r, y + i * zoom, col);
749 for(int r = 0; r < zoom; r++) {
750 setpixel(self, x + j * zoom, y + i * zoom + r, col);
751 }
752 }
753 }
754 }
755 }
756 }
757 }
758
framebuf_text_helper(mp_obj_framebuf_t * self,size_t n_args,const mp_obj_t * pos_args,mp_map_t * kw_args)759 STATIC mp_obj_t framebuf_text_helper(mp_obj_framebuf_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
760 // extract arguments
761 enum { ARG_s, ARG_x, ARG_y, ARG_c, ARG_size, ARG_zoom, ARG_space, ARG_font};
762 static const mp_arg_t allowed_args[] = {
763 { MP_QSTR_s, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE}},
764 { MP_QSTR_x, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0}},
765 { MP_QSTR_y, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0}},
766 { MP_QSTR_c, MP_ARG_INT, {.u_int = 1}},
767 { MP_QSTR_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1}},
768 { MP_QSTR_zoom, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1}},
769 { MP_QSTR_space, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0}},
770 { MP_QSTR_font, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1}},
771 };
772
773 // parse args
774 mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
775 mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
776
777 mp_int_t x0 = args[ARG_x].u_int;
778 mp_int_t y0 = args[ARG_y].u_int;
779 mp_int_t font = args[ARG_font].u_int;
780 mp_int_t size = args[ARG_size].u_int;
781 mp_int_t col = args[ARG_c].u_int;
782 mp_int_t space = args[ARG_space].u_int;
783 mp_int_t zoom = args[ARG_zoom].u_int;
784
785 mp_check_self(mp_obj_is_str_or_bytes(args[ARG_s].u_obj));
786 GET_STR_DATA_LEN(args[ARG_s].u_obj, str, str_len);
787
788 if(str_len == 0)
789 return mp_const_none;
790
791 font_t *cn_font;
792 font_t *en_font;
793
794 if(font != -1){
795 switch (font)
796 {
797 case FONT_ASC8_8:
798 cn_font = NULL;
799 en_font = NULL;
800 break;
801
802 case FONT_ASC12_8:
803 cn_font = NULL;
804 en_font = &ASC12_8;
805 break;
806 case FONT_ASC16_8:
807 cn_font = NULL;
808 en_font = &ASC16_8;
809 break;
810 case FONT_ASC24_12:
811 cn_font = NULL;
812 en_font = &ASC24_12;
813 break;
814 case FONT_ASC32_16:
815 cn_font = NULL;
816 en_font = &ASC32_16;
817 break;
818
819 case FONT_HZK12:
820 cn_font = &HZK12;
821 en_font = NULL;
822 break;
823 case FONT_HZK16:
824 cn_font = &HZK16;
825 en_font = NULL;
826 break;
827 case FONT_HZK24:
828 cn_font = &HZK24;
829 en_font = NULL;
830 break;
831 case FONT_HZK32:
832 cn_font = &HZK32;
833 en_font = NULL;
834 break;
835 default:
836 LOGE(LOG_TAG,"error wrong font\n");
837 break;
838 }
839 }
840
841 if(size != -1){
842 switch(size){
843 case 8:
844 cn_font = NULL;
845 en_font = NULL;
846 break;
847 case 12:
848 cn_font = &HZK12;
849 en_font = &ASC12_8;
850 break;
851 case 16:
852 cn_font = &HZK16;
853 en_font = &ASC16_8;
854 break;
855 case 24:
856 cn_font = &HZK24;
857 en_font = &ASC24_12;
858 break;
859 case 32:
860 cn_font = &HZK32;
861 en_font = &ASC32_16;
862 break;
863 default:
864 LOGE(LOG_TAG,"error wrong size. only support 12 16 24 32\n");
865 }
866 }
867
868 if(font == -1 && size == -1){
869 cn_font = &HZK12;
870 en_font = &ASC8_8;
871 }
872
873 int x = x0;
874
875 // loop over chars
876 for (int i=0; *(str+i); ++i) {
877 int chr = *(uint8_t *)(str+i);
878 if(chr > 127){
879 // cn
880 if(cn_font == NULL){
881 LOGE(LOG_TAG,"error wrong chr. no cn font selected\n");
882 continue;
883 }
884
885 unsigned char * chr_data;
886
887 if(cn_font == &HZK12){
888 chr_data = (unsigned char *)malloc(16 * cn_font->font_height/8);
889 }else{
890 chr_data = (unsigned char *)malloc(cn_font->font_width*cn_font->font_height/8);
891 }
892
893 if(hz_get_mat(cn_font, str+i, chr_data))
894 hz_print_mat(self, x, y0, col, cn_font, chr_data, zoom);
895 ++i;
896 x += cn_font->font_width * zoom + space;
897 free(chr_data);
898 }
899 if (chr >= 32 && chr <= 127) {
900 // en
901 if (en_font == &ASC8_8) {
902 // get char data
903 const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8];
904
905 for (int j = 0; j < 8; j++, x++) {
906 if (0 <= x && x < self->width) {
907 uint vline_data = chr_data[j];
908 for (int y = y0; vline_data; vline_data >>= 1, y++) {
909 if (vline_data & 1) {
910 if (0 <= y && y < self->height) {
911 setpixel(self, x, y, col);
912 }
913 }
914 }
915 }
916 }
917
918 x += space;
919
920 }else if(en_font== NULL){
921 LOGE(LOG_TAG,"error wrong chr. no en font selected\n");
922 continue;
923 }else{
924 unsigned char * chr_data = (unsigned char *)malloc(cn_font->font_width*cn_font->font_height/8);
925 if(asc_get_mat(en_font, str+i, chr_data))
926 asc_print_mat(self, x, y0, col, en_font, chr_data, zoom);
927 x += en_font->font_width * zoom + space;
928 free(chr_data);
929 }
930 }
931 }
932
933 if(cn_font && cn_font->fp){
934 fclose(cn_font->fp);
935 cn_font->fp = NULL;
936 }
937 if(en_font && en_font->fp){
938 fclose(en_font->fp);
939 en_font->fp = NULL;
940 }
941
942 return mp_const_none;
943 }
944
framebuf_text(size_t n_args,const mp_obj_t * args,mp_map_t * kw_args)945 STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
946 framebuf_text_helper(args[0], n_args - 1, args + 1, kw_args);
947 return mp_const_none;
948 }
949 MP_DEFINE_CONST_FUN_OBJ_KW(framebuf_text_obj, 1, framebuf_text);
950
951 // #if !MICROPY_ENABLE_DYNRUNTIME
952 STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = {
953 { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&framebuf_fill_obj) },
954 { MP_ROM_QSTR(MP_QSTR_fill_rect), MP_ROM_PTR(&framebuf_fill_rect_obj) },
955 { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&framebuf_pixel_obj) },
956 { MP_ROM_QSTR(MP_QSTR_hline), MP_ROM_PTR(&framebuf_hline_obj) },
957 { MP_ROM_QSTR(MP_QSTR_vline), MP_ROM_PTR(&framebuf_vline_obj) },
958 { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&framebuf_rect_obj) },
959 { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&framebuf_line_obj) },
960 { MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&framebuf_blit_obj) },
961 { MP_ROM_QSTR(MP_QSTR_scroll), MP_ROM_PTR(&framebuf_scroll_obj) },
962 { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&framebuf_text_obj) },
963 };
964 STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table);
965
966 STATIC const mp_obj_type_t mp_type_framebuf = {
967 { &mp_type_type },
968 .name = MP_QSTR_FrameBuffer,
969 .make_new = framebuf_make_new,
970 .buffer_p = { .get_buffer = framebuf_get_buffer },
971 .locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict,
972 };
973 // #endif
974
975 // this factory function is provided for backwards compatibility with old FrameBuffer1 class
legacy_framebuffer1(size_t n_args,const mp_obj_t * args)976 STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) {
977 mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
978 o->base.type = &mp_type_framebuf;
979
980 mp_buffer_info_t bufinfo;
981 mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE);
982 o->buf = bufinfo.buf;
983
984 o->width = mp_obj_get_int(args[1]);
985 o->height = mp_obj_get_int(args[2]);
986 o->format = FRAMEBUF_MVLSB;
987 if (n_args >= 4) {
988 o->stride = mp_obj_get_int(args[3]);
989 } else {
990 o->stride = o->width;
991 }
992
993 return MP_OBJ_FROM_PTR(o);
994 }
995 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(legacy_framebuffer1_obj, 3, 4, legacy_framebuffer1);
996
997 // #if !MICROPY_ENABLE_DYNRUNTIME
998 STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
999 { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebuf) },
1000 { MP_ROM_QSTR(MP_QSTR_FrameBuffer), MP_ROM_PTR(&mp_type_framebuf) },
1001 { MP_ROM_QSTR(MP_QSTR_FrameBuffer1), MP_ROM_PTR(&legacy_framebuffer1_obj) },
1002 { MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
1003 { MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
1004 { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) },
1005 { MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) },
1006 { MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) },
1007 { MP_ROM_QSTR(MP_QSTR_GS8), MP_ROM_INT(FRAMEBUF_GS8) },
1008 { MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) },
1009 { MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) },
1010
1011 { MP_ROM_QSTR(MP_QSTR_ASC8_8), MP_ROM_INT(FONT_ASC8_8) },
1012 { MP_ROM_QSTR(MP_QSTR_ASC12_8), MP_ROM_INT(FONT_ASC12_8) },
1013 { MP_ROM_QSTR(MP_QSTR_ASC16_8), MP_ROM_INT(FONT_ASC16_8) },
1014 { MP_ROM_QSTR(MP_QSTR_ASC24_12), MP_ROM_INT(FONT_ASC24_12) },
1015 { MP_ROM_QSTR(MP_QSTR_ASC32_16), MP_ROM_INT(FONT_ASC32_16) },
1016
1017 { MP_ROM_QSTR(MP_QSTR_HZK12), MP_ROM_INT(FONT_HZK12) },
1018 { MP_ROM_QSTR(MP_QSTR_HZK16), MP_ROM_INT(FONT_HZK16) },
1019 { MP_ROM_QSTR(MP_QSTR_HZK24), MP_ROM_INT(FONT_HZK24) },
1020 { MP_ROM_QSTR(MP_QSTR_HZK32), MP_ROM_INT(FONT_HZK32) },
1021 };
1022
1023 STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
1024
1025 const mp_obj_module_t mp_module_framebuf = {
1026 .base = { &mp_type_module },
1027 .globals = (mp_obj_dict_t *)&framebuf_module_globals,
1028 };
1029 // #endif
1030
1031 #endif // MICROPY_PY_FRAMEBUF
1032
1033 // Modified bt HaaS end
1034