summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2019-02-12 19:04:37 -0500
committerGitHub <noreply@github.com>2019-02-12 19:04:37 -0500
commita61f68f0fe8fa38a7a843bdd54bde15a75fcecef (patch)
tree428ba7b2ca9ab7e4896c81d2d0bb7faac0e2ad3b /shared-module
parentf34360bba7f1870edf9b0d15cf219786bb60e762 (diff)
parentdf00d74db862204d16d73dfb4fd0c46456d4350f (diff)
Merge pull request #1535 from tannewt/group_sequence_and_font
A variety of displayio improvements
Diffstat (limited to 'shared-module')
-rw-r--r--shared-module/displayio/Bitmap.c33
-rw-r--r--shared-module/displayio/Bitmap.h1
-rw-r--r--shared-module/displayio/BuiltinFont.c79
-rw-r--r--shared-module/displayio/BuiltinFont.h47
-rw-r--r--shared-module/displayio/Group.c68
-rw-r--r--shared-module/displayio/Group.h6
-rw-r--r--shared-module/displayio/TileGrid.c8
-rw-r--r--shared-module/terminalio/Terminal.c32
-rw-r--r--shared-module/terminalio/Terminal.h4
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..adaad1505 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->needs_refresh = self->scale != scale;
+ self->scale = scale;
+}
+
+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->needs_refresh = self->x != x;
+ self->x = x;
+}
+
+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->needs_refresh = self->y != y;
+ self->y = y;
+}
+
+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;