diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2019-02-06 12:13:17 -0800 |
|---|---|---|
| committer | Scott Shawcroft <scott@tannewt.org> | 2019-02-11 20:55:05 -0800 |
| commit | c17f147be95e7490e5207c747add2da1cc8b167f (patch) | |
| tree | 90abe0fad90920415ae4f1e118854cf56e8dfe04 /shared-module | |
| parent | 1a6ad209439e0c8b0d01701b76195f9761949e31 (diff) | |
A variety of displayio improvements
This changes a number of things in displayio:
* Introduces BuiltinFont and Glyph so the built in font can be used by libraries. For boards with
a font it is available as board.TERMINAL_FONT. Fixes #1172
* Remove _load_row from Bitmap in favor of bitmap[] access. Index can be x/y tuple or overall index. Fixes #1191
* Add width and height properties to Bitmap.
* Add insert and [] access to Group. Fixes #1518
* Add index param to pop on Group.
* Terminal no longer takes unicode character info. It takes a BuiltinFont instead.
* Fix Terminal's handling of [###D vt100 commands used when up arrowing into repl history.
* Add x and y positions to Group plus scale as well.
* Add bitmap accessor for BuiltinFont
Diffstat (limited to 'shared-module')
| -rw-r--r-- | shared-module/displayio/Bitmap.c | 33 | ||||
| -rw-r--r-- | shared-module/displayio/Bitmap.h | 1 | ||||
| -rw-r--r-- | shared-module/displayio/BuiltinFont.c | 79 | ||||
| -rw-r--r-- | shared-module/displayio/BuiltinFont.h | 47 | ||||
| -rw-r--r-- | shared-module/displayio/Group.c | 68 | ||||
| -rw-r--r-- | shared-module/displayio/Group.h | 6 | ||||
| -rw-r--r-- | shared-module/displayio/TileGrid.c | 8 | ||||
| -rw-r--r-- | shared-module/terminalio/Terminal.c | 32 | ||||
| -rw-r--r-- | shared-module/terminalio/Terminal.h | 4 |
9 files changed, 240 insertions, 38 deletions
diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index addc341a7..2b2c70ab6 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -42,7 +42,7 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi self->width = width; self->height = height; self->data = m_malloc(self->stride * height * sizeof(uint32_t), false); - + self->read_only = false; self->bits_per_value = bits_per_value; if (bits_per_value > 8) { @@ -64,6 +64,18 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi self->bitmask = (1 << bits_per_value) - 1; } +uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self) { + return self->height; +} + +uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self) { + return self->width; +} + +uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self) { + return self->bits_per_value; +} + void common_hal_displayio_bitmap_load_row(displayio_bitmap_t *self, uint16_t y, uint8_t* data, uint16_t len) { if (len != self->stride * sizeof(uint32_t)) { mp_raise_ValueError(translate("row must be packed and word aligned")); @@ -85,6 +97,7 @@ void common_hal_displayio_bitmap_load_row(displayio_bitmap_t *self, uint16_t y, row_value++; } } + uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t x, int16_t y) { if (x >= self->width || x < 0 || y >= self->height || y < 0) { return 0; @@ -99,3 +112,21 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t return self->data[row_start + x * bytes_per_value]; } } + +void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + int32_t row_start = y * self->stride; + if (self->bits_per_value < 8) { + uint32_t bit_position = (32 - ((x & self->x_mask) + 1) * self->bits_per_value); + uint32_t index = row_start + (x >> self->x_shift); + uint32_t word = self->data[index]; + word &= ~(self->bitmask << bit_position); + word |= (value & self->bitmask) << bit_position; + self->data[index] = word; + } else { + uint32_t bytes_per_value = self->bits_per_value / 8; + self->data[row_start + x * bytes_per_value] = value; + } +} diff --git a/shared-module/displayio/Bitmap.h b/shared-module/displayio/Bitmap.h index 781a4d12a..485b57daf 100644 --- a/shared-module/displayio/Bitmap.h +++ b/shared-module/displayio/Bitmap.h @@ -42,6 +42,7 @@ typedef struct { uint8_t x_shift; uint8_t x_mask; uint16_t bitmask; + bool read_only; } displayio_bitmap_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BITMAP_H diff --git a/shared-module/displayio/BuiltinFont.c b/shared-module/displayio/BuiltinFont.c new file mode 100644 index 000000000..ee69b423c --- /dev/null +++ b/shared-module/displayio/BuiltinFont.c @@ -0,0 +1,79 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/displayio/BuiltinFont.h" + + +#include "shared-bindings/displayio/Glyph.h" + +#include "py/objnamedtuple.h" + +mp_obj_t common_hal_displayio_builtinfont_get_bitmap(const displayio_builtinfont_t *self) { + return MP_OBJ_FROM_PTR(self->bitmap); +} + +mp_obj_t common_hal_displayio_builtinfont_get_bounding_box(const displayio_builtinfont_t *self) { + mp_obj_t *items = m_new(mp_obj_t, 2); + items[0] = MP_OBJ_NEW_SMALL_INT(self->width); + items[1] = MP_OBJ_NEW_SMALL_INT(self->height); + return mp_obj_new_tuple(2, items); +} + +uint8_t displayio_builtinfont_get_glyph_index(const displayio_builtinfont_t *self, mp_uint_t codepoint) { + if (codepoint >= 0x20 && codepoint <= 0x7e) { + return codepoint - 0x20; + } + // Do a linear search of the mapping for unicode. + const byte* j = self->unicode_characters; + uint8_t k = 0; + while (j < self->unicode_characters + self->unicode_characters_len) { + unichar potential_c = utf8_get_char(j); + j = utf8_next_char(j); + if (codepoint == potential_c) { + return 0x7f - 0x20 + k; + } + k++; + } + return 0xff; +} + +mp_obj_t common_hal_displayio_builtinfont_get_glyph(const displayio_builtinfont_t *self, mp_uint_t codepoint) { + uint8_t glyph_index = displayio_builtinfont_get_glyph_index(self, codepoint); + if (glyph_index == 0xff) { + return mp_const_none; + } + mp_obj_t field_values[8] = { + MP_OBJ_FROM_PTR(self->bitmap), + MP_OBJ_NEW_SMALL_INT(glyph_index), + MP_OBJ_NEW_SMALL_INT(self->width), + MP_OBJ_NEW_SMALL_INT(self->height), + MP_OBJ_NEW_SMALL_INT(0), + MP_OBJ_NEW_SMALL_INT(0), + MP_OBJ_NEW_SMALL_INT(self->width), + MP_OBJ_NEW_SMALL_INT(0) + }; + return namedtuple_make_new((const mp_obj_type_t*) &displayio_glyph_type, 8, field_values, NULL); +} diff --git a/shared-module/displayio/BuiltinFont.h b/shared-module/displayio/BuiltinFont.h new file mode 100644 index 000000000..ac69ef9da --- /dev/null +++ b/shared-module/displayio/BuiltinFont.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BUILTINFONT_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BUILTINFONT_H + +#include <stdbool.h> +#include <stdint.h> + +#include "py/obj.h" +#include "shared-bindings/displayio/Bitmap.h" + +typedef struct { + mp_obj_base_t base; + const displayio_bitmap_t* bitmap; + uint8_t width; + uint8_t height; + const byte* unicode_characters; + uint16_t unicode_characters_len; +} displayio_builtinfont_t; + +uint8_t displayio_builtinfont_get_glyph_index(const displayio_builtinfont_t *self, mp_uint_t codepoint); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BUILTINFONT_H diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 95043e4f3..e40b5a7ea 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -29,12 +29,39 @@ #include "py/runtime.h" #include "shared-bindings/displayio/TileGrid.h" -void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size) { +void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale) { mp_obj_t* children = m_new(mp_obj_t, max_size); - displayio_group_construct(self, children, max_size); + displayio_group_construct(self, children, max_size, scale); } -void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer) { +uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) { + return self->scale; +} + +void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale) { + self->scale = scale; + self->needs_refresh = true; +} + +mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self) { + return self->x; +} + +void common_hal_displayio_group_set_x(displayio_group_t* self, mp_int_t x) { + self->x = x; + self->needs_refresh = true; +} + +mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self) { + return self->y; +} + +void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) { + self->y = y; + self->needs_refresh = true; +} + +void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) { if (self->size == self->max_size) { mp_raise_RuntimeError(translate("Group full")); } @@ -45,29 +72,47 @@ void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer) if (native_layer == MP_OBJ_NULL) { mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); } - self->children[self->size] = layer; + // Shift everything right. + for (size_t i = index; i < self->size; i++) { + self->children[i + 1] = self->children[i]; + } + self->children[index] = native_layer; self->size++; self->needs_refresh = true; } -mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self) { - if (self->size == 0) { - mp_raise_IndexError(translate("Group empty")); - } +mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) { self->size--; - mp_obj_t item = self->children[self->size]; + mp_obj_t item = self->children[index]; + // Shift everything left. + for (size_t i = index; i < self->size; i++) { + self->children[i] = self->children[i + 1]; + } self->children[self->size] = NULL; self->needs_refresh = true; return item; } -void displayio_group_construct(displayio_group_t* self, mp_obj_t* child_array, uint32_t max_size) { +size_t common_hal_displayio_group_get_len(displayio_group_t* self) { + return self->size; +} + +mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) { + return self->children[index]; +} + +void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) { + self->children[index] = layer; + self->needs_refresh = true; +} + +void displayio_group_construct(displayio_group_t* self, mp_obj_t* child_array, uint32_t max_size, uint32_t scale) { self->x = 0; self->y = 0; self->children = child_array; self->max_size = max_size; self->needs_refresh = false; - self->scale = 1; + self->scale = scale; } bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, uint16_t* pixel) { @@ -86,7 +131,6 @@ bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, ui return true; } } - // TODO: Tiled layer } return false; } diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h index 60f573ff6..265cb4e22 100644 --- a/shared-module/displayio/Group.h +++ b/shared-module/displayio/Group.h @@ -43,11 +43,7 @@ typedef struct { bool needs_refresh; } displayio_group_t; - -void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size); -void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer); - -void displayio_group_construct(displayio_group_t* self, mp_obj_t* child_array, uint32_t max_size); +void displayio_group_construct(displayio_group_t* self, mp_obj_t* child_array, uint32_t max_size, uint32_t scale); bool displayio_group_get_pixel(displayio_group_t *group, int16_t x, int16_t y, uint16_t *pixel); bool displayio_group_needs_refresh(displayio_group_t *self); void displayio_group_finish_refresh(displayio_group_t *self); diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index b90603afe..e4f40a5f7 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -40,9 +40,17 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ // Sprites will only have one tile so save a little memory by inlining values in the pointer. uint8_t inline_tiles = sizeof(uint8_t*); if (total_tiles <= inline_tiles) { + self->tiles = 0; + // Pack values into the pointer since there are only a few. + for (uint32_t i = 0; i < inline_tiles; i++) { + ((uint8_t*) &self->tiles)[i] = default_tile; + } self->inline_tiles = true; } else { self->tiles = (uint8_t*) m_malloc(total_tiles, false); + for (uint32_t i = 0; i < total_tiles; i++) { + self->tiles[i] = default_tile; + } self->inline_tiles = false; } self->bitmap_width_in_tiles = bitmap_width_in_tiles; diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index 6734fa30e..85bbee293 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -27,14 +27,14 @@ #include "shared-module/terminalio/Terminal.h" #include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/BuiltinFont.h" #include "shared-bindings/displayio/TileGrid.h" -void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const uint8_t* unicode_characters, size_t unicode_characters_len) { +void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const displayio_builtinfont_t* font) { self->cursor_x = 0; self->cursor_y = 0; + self->font = font; self->tilegrid = tilegrid; - self->unicode_characters = unicode_characters; - self->unicode_characters_len = unicode_characters_len; self->first_row = 0; } @@ -47,10 +47,10 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con // Always handle ASCII. if (c < 128) { if (c >= 0x20 && c <= 0x7e) { - common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, c - 0x20); + uint8_t tile_index = displayio_builtinfont_get_glyph_index(self->font, c); + common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, tile_index); self->cursor_x++; - } - if (c == '\r') { + } else if (c == '\r') { self->cursor_x = 0; } else if (c == '\n') { self->cursor_y++; @@ -76,6 +76,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con n = n * 10 + (i[j] - '0'); } else { c = i[j]; + break; } } if (c == 'D') { @@ -84,23 +85,18 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con } else { self->cursor_x -= n; } - i += j; } + i += j + 1; + continue; } } } } else { - // Do a linear search of the mapping for unicode. - const byte* j = self->unicode_characters; - uint8_t k = 0; - while (j < self->unicode_characters + self->unicode_characters_len) { - unichar potential_c = utf8_get_char(j); - j = utf8_next_char(j); - if (c == potential_c) { - common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, 0x7f - 0x20 + k); - self->cursor_x++; - break; - } + uint8_t tile_index = displayio_builtinfont_get_glyph_index(self->font, c); + if (tile_index != 0xff) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, tile_index); + self->cursor_x++; + } } if (self->cursor_x >= self->tilegrid->width_in_tiles) { diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h index fe9dcf0c4..145b42f3f 100644 --- a/shared-module/terminalio/Terminal.h +++ b/shared-module/terminalio/Terminal.h @@ -31,15 +31,15 @@ #include <stdbool.h> #include "py/obj.h" +#include "shared-module/displayio/BuiltinFont.h" #include "shared-module/displayio/TileGrid.h" typedef struct { mp_obj_base_t base; + const displayio_builtinfont_t* font; uint16_t cursor_x; uint16_t cursor_y; displayio_tilegrid_t* tilegrid; - const byte* unicode_characters; - uint16_t unicode_characters_len; uint16_t first_row; } terminalio_terminal_obj_t; |
