diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2020-05-12 18:22:57 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-12 18:22:57 -0700 |
| commit | 277e8d528bef84cefe854d527bf5f822e0ec8ceb (patch) | |
| tree | beaa452a5dacf21e663a884e358e2ac2d223b777 | |
| parent | bc40034a08a7c3b371a13610a896e1ca40c4a329 (diff) | |
| parent | 75f9969860870a4ae636c74ae210275413b13c2f (diff) | |
Merge branch 'master' into Optical-Encoder-Module
53 files changed, 1708 insertions, 43 deletions
diff --git a/locale/ID.po b/locale/ID.po index b93dc0cd5..e4420f046 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -70,13 +70,22 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c #, fuzzy msgid "%q must be >= 1" msgstr "buffers harus mempunyai panjang yang sama" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "" @@ -2022,6 +2031,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2124,6 +2137,10 @@ msgstr "" msgid "empty" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "heap kosong" @@ -2814,10 +2831,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3137,7 +3158,8 @@ msgstr "" msgid "unreadable attribute" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 13f62c728..d1f497805 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -70,12 +70,21 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "" @@ -1998,6 +2007,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2100,6 +2113,10 @@ msgstr "" msgid "empty" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "" @@ -2789,10 +2806,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3111,7 +3132,8 @@ msgstr "" msgid "unreadable attribute" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 3764fc193..797c095b8 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -79,12 +79,21 @@ msgstr "Der Index %q befindet sich außerhalb des Bereiches" msgid "%q indices must be integers, not %s" msgstr "%q Indizes müssen ganze Zahlen sein, nicht %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "%q muss >= 1 sein" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "%q sollte ein int sein" @@ -2033,6 +2042,10 @@ msgstr "chr() arg ist nicht in range(0x110000)" msgid "chr() arg not in range(256)" msgstr "chr() arg ist nicht in range(256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "Farbpuffer muss 3 Bytes (RGB) oder 4 Bytes (RGB + pad byte) sein" @@ -2136,6 +2149,10 @@ msgstr "Division durch Null" msgid "empty" msgstr "leer" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "leerer heap" @@ -2834,10 +2851,14 @@ msgstr "Pixelkoordinaten außerhalb der Grenzen" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader muss displayio.Palette oder displayio.ColorConverter sein" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3163,7 +3184,8 @@ msgstr "" msgid "unreadable attribute" msgstr "nicht lesbares Attribut" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Nicht unterstützter %q-Typ" diff --git a/locale/en_US.po b/locale/en_US.po index 8da659b92..d18ea1808 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -70,12 +70,21 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "" @@ -1998,6 +2007,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2100,6 +2113,10 @@ msgstr "" msgid "empty" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "" @@ -2789,10 +2806,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3111,7 +3132,8 @@ msgstr "" msgid "unreadable attribute" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index d9e207921..6515beaf9 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -77,12 +77,21 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "" @@ -2007,6 +2016,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2109,6 +2122,10 @@ msgstr "" msgid "empty" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "" @@ -2798,10 +2815,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3120,7 +3141,8 @@ msgstr "" msgid "unreadable attribute" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/es.po b/locale/es.po index 79462f67a..12ecb0c18 100644 --- a/locale/es.po +++ b/locale/es.po @@ -72,12 +72,21 @@ msgstr "%q indice fuera de rango" msgid "%q indices must be integers, not %s" msgstr "%q indices deben ser enteros, no %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "%q debe ser >= 1" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "%q debe ser un int" @@ -2027,6 +2036,10 @@ msgstr "El argumento de chr() esta fuera de rango(0x110000)" msgid "chr() arg not in range(256)" msgstr "El argumento de chr() no esta en el rango(256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "color buffer debe ser 3 bytes (RGB) ó 4 bytes (RGB + pad byte)" @@ -2131,6 +2144,10 @@ msgstr "división por cero" msgid "empty" msgstr "vacío" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "heap vacío" @@ -2827,10 +2844,14 @@ msgstr "coordenadas del pixel fuera de límites" msgid "pixel value requires too many bits" msgstr "valor del pixel require demasiado bits" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader debe ser displayio.Palette o displayio.ColorConverter" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3152,7 +3173,8 @@ msgstr "No coinciden '{' en format" msgid "unreadable attribute" msgstr "atributo no legible" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo de %q no soportado" diff --git a/locale/fil.po b/locale/fil.po index 9203fb5e1..2dd773eef 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -70,13 +70,22 @@ msgstr "%q indeks wala sa sakop" msgid "%q indices must be integers, not %s" msgstr "%q indeks ay dapat integers, hindi %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c #, fuzzy msgid "%q must be >= 1" msgstr "aarehas na haba dapat ang buffer slices" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c #, fuzzy msgid "%q should be an int" @@ -2038,6 +2047,10 @@ msgstr "chr() arg wala sa sakop ng range(0x110000)" msgid "chr() arg not in range(256)" msgstr "chr() arg wala sa sakop ng range(256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "color buffer ay dapat na 3 bytes (RGB) o 4 bytes (RGB + pad byte)" @@ -2144,6 +2157,10 @@ msgstr "dibisyon ng zero" msgid "empty" msgstr "walang laman" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "walang laman ang heap" @@ -2841,10 +2858,14 @@ msgstr "wala sa sakop ang address" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader ay dapat displayio.Palette o displayio.ColorConverter" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3167,7 +3188,8 @@ msgstr "hindi tugma ang '{' sa format" msgid "unreadable attribute" msgstr "hindi mabasa ang attribute" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Hindi supportadong tipo ng %q" diff --git a/locale/fr.po b/locale/fr.po index 227339c0f..b87e0cd21 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -81,12 +81,21 @@ msgstr "index %q hors gamme" msgid "%q indices must be integers, not %s" msgstr "les indices %q doivent être des entiers, pas %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "%q doit être >=1" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "%q doit être un entier (int)" @@ -2068,6 +2077,10 @@ msgstr "argument de chr() hors de la gamme range(0x11000)" msgid "chr() arg not in range(256)" msgstr "argument de chr() hors de la gamme range(256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "le tampon de couleur doit faire 3 octets (RVB) ou 4 (RVB + pad byte)" @@ -2176,6 +2189,10 @@ msgstr "division par zéro" msgid "empty" msgstr "vide" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "tas vide" @@ -2879,11 +2896,15 @@ msgstr "coordonnées de pixel hors limites" msgid "pixel value requires too many bits" msgstr "la valeur du pixel requiet trop de bits" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" "pixel_shader doit être un objet displayio.Palette ou displayio.ColorConverter" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3207,7 +3228,8 @@ msgstr "'{' sans correspondance dans le format" msgid "unreadable attribute" msgstr "attribut illisible" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c #, fuzzy msgid "unsupported %q type" msgstr "type de %q non supporté" diff --git a/locale/it_IT.po b/locale/it_IT.po index d282d84a3..61de76f54 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -70,13 +70,22 @@ msgstr "indice %q fuori intervallo" msgid "%q indices must be integers, not %s" msgstr "gli indici %q devono essere interi, non %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c #, fuzzy msgid "%q must be >= 1" msgstr "slice del buffer devono essere della stessa lunghezza" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c #, fuzzy msgid "%q should be an int" @@ -2038,6 +2047,10 @@ msgstr "argomento di chr() non è in range(0x110000)" msgid "chr() arg not in range(256)" msgstr "argomento di chr() non è in range(256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2145,6 +2158,10 @@ msgstr "divisione per zero" msgid "empty" msgstr "vuoto" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "heap vuoto" @@ -2848,10 +2865,14 @@ msgstr "indirizzo fuori limite" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader deve essere displayio.Palette o displayio.ColorConverter" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3174,7 +3195,8 @@ msgstr "'{' spaiato nella stringa di formattazione" msgid "unreadable attribute" msgstr "attributo non leggibile" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo di %q non supportato" diff --git a/locale/ko.po b/locale/ko.po index febd29fab..e6e386b30 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -72,12 +72,21 @@ msgstr "%q 인덱스 범위를 벗어났습니다" msgid "%q indices must be integers, not %s" msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "%q 는 >=1이어야합니다" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "%q 는 정수(int) 여야합니다" @@ -2003,6 +2012,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2105,6 +2118,10 @@ msgstr "" msgid "empty" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "" @@ -2794,10 +2811,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3116,7 +3137,8 @@ msgstr "" msgid "unreadable attribute" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/pl.po b/locale/pl.po index fc75ede7f..962c09005 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -71,12 +71,21 @@ msgstr "%q poza zakresem" msgid "%q indices must be integers, not %s" msgstr "%q indeks musi być liczbą całkowitą, a nie %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "%q musi być >= 1" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "%q powinno być typu int" @@ -2006,6 +2015,10 @@ msgstr "argument chr() poza zakresem range(0x110000)" msgid "chr() arg not in range(256)" msgstr "argument chr() poza zakresem range(256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "bufor kolorów musi nieć 3 bajty (RGB) lub 4 bajty (RGB + wypełnienie)" @@ -2109,6 +2122,10 @@ msgstr "dzielenie przez zero" msgid "empty" msgstr "puste" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "pusta sterta" @@ -2798,11 +2815,15 @@ msgstr "współrzędne piksela poza zakresem" msgid "pixel value requires too many bits" msgstr "wartość piksela wymaga zbyt wielu bitów" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" "pixel_shader musi być typu displayio.Palette lub dispalyio.ColorConverter" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3122,7 +3143,8 @@ msgstr "niepasujące '{' for formacie" msgid "unreadable attribute" msgstr "nieczytelny atrybut" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "zły typ %q" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index e22f1f124..e18355fa3 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -70,13 +70,22 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c #, fuzzy msgid "%q must be >= 1" msgstr "buffers devem ser o mesmo tamanho" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c #, fuzzy msgid "%q should be an int" @@ -2019,6 +2028,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2121,6 +2134,10 @@ msgstr "divisão por zero" msgid "empty" msgstr "vazio" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "heap vazia" @@ -2811,10 +2828,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3135,7 +3156,8 @@ msgstr "" msgid "unreadable attribute" msgstr "atributo ilegível" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/sv.po b/locale/sv.po index 1e909e812..493245dbf 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -70,12 +70,21 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "" @@ -1998,6 +2007,10 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2100,6 +2113,10 @@ msgstr "" msgid "empty" msgstr "" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "" @@ -2789,10 +2806,14 @@ msgstr "" msgid "pixel value requires too many bits" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3111,7 +3132,8 @@ msgstr "" msgid "unreadable attribute" msgstr "" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index e2b957acf..9d0bd392d 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -77,12 +77,21 @@ msgstr "%q suǒyǐn chāochū fànwéi" msgid "%q indices must be integers, not %s" msgstr "%q suǒyǐn bìxū shì zhěngshù, ér bùshì %s" +#: shared-bindings/vectorio/Polygon.c +msgid "%q list must be a list" +msgstr "" + #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/Shape.c +#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c +#: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" msgstr "%q bìxū dàyú huò děngyú 1" +#: shared-bindings/vectorio/Polygon.c +msgid "%q must be a tuple of length 2" +msgstr "" + #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" msgstr "%q yīnggāi shì yīgè int" @@ -2031,6 +2040,10 @@ msgstr "chr() cān shǔ bùzài fànwéi (0x110000)" msgid "chr() arg not in range(256)" msgstr "chr() cān shǔ bùzài fànwéi (256)" +#: shared-module/vectorio/Circle.c +msgid "circle can only be registered in one parent" +msgstr "" + #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" @@ -2137,6 +2150,10 @@ msgstr "bèi líng chú" msgid "empty" msgstr "kòngxián" +#: shared-bindings/vectorio/Polygon.c +msgid "empty %q list" +msgstr "" + #: extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" msgstr "kōng yīn yīnxiào" @@ -2828,10 +2845,14 @@ msgstr "xiàngsù zuòbiāo chāochū biānjiè" msgid "pixel value requires too many bits" msgstr "xiàngsù zhí xūyào tài duō wèi" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader bìxū shì displayio.Palette huò displayio.ColorConverter" +#: shared-module/vectorio/Polygon.c +msgid "polygon can only be registered in one parent" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/pulseio/PulseIn.c @@ -3152,7 +3173,8 @@ msgstr "géshì wèi pǐpèi '{'" msgid "unreadable attribute" msgstr "bùkě dú shǔxìng" -#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/Polygon.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "bù zhīchí %q lèixíng" diff --git a/ports/atmel-samd/boards/bdmicro_vina_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bdmicro_vina_m0/mpconfigboard.mk index 153754042..5a47a5890 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bdmicro_vina_m0/mpconfigboard.mk @@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk index 3587f1a33..19e5dd2ab 100755 --- a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk @@ -14,3 +14,5 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_VECTORIO = 0 + diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk index d65dc993f..4220aa77f 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk @@ -17,6 +17,8 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_PIXELBUF = 0 CIRCUITPY_RTC = 0 +# So not all of displayio, sorry! +CIRCUITPY_VECTORIO = 0 SUPEROPT_GC = 0 CFLAGS_INLINE_LIMIT = 55 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index cdee7b794..199cef362 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index cb13adb76..a94dd3c4e 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -14,6 +14,8 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 +# supersized, not ultra-supersized +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index 38dd47758..7cb53bd13 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -10,3 +10,6 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ + +CIRCUITPY_VECTORIO = 1 + diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk index 05c305b1a..3aa7c5721 100755 --- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk @@ -15,3 +15,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOBUSIO = 0 # No DAC on SAMR21G CIRCUITPY_AUDIOIO = 0 + +# Too much flash for Korean translations +CIRCUITPY_VECTORIO = 0 + diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 88555655f..a8390fd97 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -20,6 +20,8 @@ CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_COUNTIO = 0 +CIRCUITPY_VECTORIO = 0 + CFLAGS_INLINE_LIMIT = 55 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk index 4d516c75b..812c208cc 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -17,6 +17,8 @@ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_RTC = 0 +# too itsy bitsy for all of displayio +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index b52b1343f..588e50ee1 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk index f5b6ca389..87f92ae9e 100644 --- a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk @@ -34,6 +34,7 @@ CIRCUITPY_NETWORK = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_SAMD = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_AUDIOMIXER = 1 CIRCUITPY_AUDIOIO = 1 diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk index 4faa041b1..08f8d431e 100644 --- a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk +++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk @@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk index 6a2afc306..3f75d175c 100755 --- a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk @@ -13,5 +13,6 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOIO = 0 CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_VECTORIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk index f2d4eccad..7a9b44e4c 100755 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk index 20feabd18..c4b1f6d5a 100644 --- a/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk @@ -18,6 +18,7 @@ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_RTC = 0 +CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 60 SUPEROPT_GC = 0 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 797bbc46f..f26baec04 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -148,6 +148,9 @@ endif ifeq ($(CIRCUITPY_DISPLAYIO),1) SRC_PATTERNS += displayio/% terminalio/% fontio/% endif +ifeq ($(CIRCUITPY_VECTORIO),1) +SRC_PATTERNS += vectorio/% +endif ifeq ($(CIRCUITPY_FRAMEBUFFERIO),1) SRC_PATTERNS += framebufferio/% endif @@ -363,6 +366,11 @@ SRC_SHARED_MODULE_ALL = \ displayio/Shape.c \ displayio/TileGrid.c \ displayio/__init__.c \ + vectorio/Circle.c \ + vectorio/Rectangle.c \ + vectorio/Polygon.c \ + vectorio/VectorShape.c \ + vectorio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ framebufferio/FramebufferDisplay.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 4a1e4415c..6ea413216 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -359,6 +359,13 @@ extern const struct _mp_obj_module_t framebufferio_module; #define FRAMEBUFFERIO_MODULE #endif +#if CIRCUITPY_VECTORIO +extern const struct _mp_obj_module_t vectorio_module; +#define VECTORIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_vectorio), (mp_obj_t)&vectorio_module }, +#else +#define VECTORIO_MODULE +#endif + #if CIRCUITPY_FREQUENCYIO extern const struct _mp_obj_module_t frequencyio_module; #define FREQUENCYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_frequencyio), (mp_obj_t)&frequencyio_module }, @@ -650,6 +657,7 @@ extern const struct _mp_obj_module_t ustack_module; DISPLAYIO_MODULE \ FONTIO_MODULE \ TERMINALIO_MODULE \ + VECTORIO_MODULE \ ERRNO_MODULE \ FRAMEBUFFERIO_MODULE \ FREQUENCYIO_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 3033f119a..74ad7a2cc 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -97,6 +97,9 @@ CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) CIRCUITPY_FRAMEBUFFERIO ?= 0 CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO) +CIRCUITPY_VECTORIO ?= $(CIRCUITPY_DISPLAYIO) +CFLAGS += -DCIRCUITPY_VECTORIO=$(CIRCUITPY_VECTORIO) + CIRCUITPY_FREQUENCYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO) diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c new file mode 100644 index 000000000..260e80d0f --- /dev/null +++ b/shared-bindings/vectorio/Circle.c @@ -0,0 +1,81 @@ + +#include "shared-bindings/vectorio/Circle.h" + + +#include <stdint.h> + +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: vectorio +//| +//| :class:`Circle` -- Represents a circle by its radius +//| ========================================================================== +//| +//| .. class:: Circle(radius) +//| +//| Circle is positioned on screen by its center point. +//| +//| :param int radius: The radius of the circle in pixels +//| +static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_radius }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t radius = args[ARG_radius].u_int; + if (radius < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_radius); + } + + vectorio_circle_t *self = m_new_obj(vectorio_circle_t); + self->base.type = &vectorio_circle_type; + common_hal_vectorio_circle_construct(self, radius); + + return MP_OBJ_FROM_PTR(self); +} + + +//| .. attribute:: radius +//| +//| The radius of the circle in pixels. +//| +STATIC mp_obj_t vectorio_circle_obj_get_radius(mp_obj_t self_in) { + vectorio_circle_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(common_hal_vectorio_circle_get_radius(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_circle_get_radius_obj, vectorio_circle_obj_get_radius); + +STATIC mp_obj_t vectorio_circle_obj_set_radius(mp_obj_t self_in, mp_obj_t radius) { + vectorio_circle_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_vectorio_circle_set_radius(self, mp_obj_get_int(radius)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_circle_set_radius_obj, vectorio_circle_obj_set_radius); + +const mp_obj_property_t vectorio_circle_radius_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_circle_get_radius_obj, + (mp_obj_t)&vectorio_circle_set_radius_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_radius), MP_ROM_PTR(&vectorio_circle_radius_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(vectorio_circle_locals_dict, vectorio_circle_locals_dict_table); + +const mp_obj_type_t vectorio_circle_type = { + { &mp_type_type }, + .name = MP_QSTR_Circle, + .make_new = vectorio_circle_make_new, + .locals_dict = (mp_obj_dict_t*)&vectorio_circle_locals_dict, +}; + diff --git a/shared-bindings/vectorio/Circle.h b/shared-bindings/vectorio/Circle.h new file mode 100644 index 000000000..e8fc048eb --- /dev/null +++ b/shared-bindings/vectorio/Circle.h @@ -0,0 +1,22 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_CIRCLE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_CIRCLE_H + +#include "shared-module/vectorio/__init__.h" +#include "shared-module/vectorio/Circle.h" +#include "shared-module/displayio/area.h" + +extern const mp_obj_type_t vectorio_circle_type; + +void common_hal_vectorio_circle_construct(vectorio_circle_t *self, uint16_t radius); + +void common_hal_vectorio_circle_set_on_dirty(vectorio_circle_t *self, vectorio_event_t notification); + +uint32_t common_hal_vectorio_circle_get_pixel(void *circle, int16_t x, int16_t y); + +void common_hal_vectorio_circle_get_area(void *circle, displayio_area_t *out_area); + + +int16_t common_hal_vectorio_circle_get_radius(void *circle); +void common_hal_vectorio_circle_set_radius(void *circle, int16_t radius); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_CIRCLE_H diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c new file mode 100644 index 000000000..b8bb377ac --- /dev/null +++ b/shared-bindings/vectorio/Polygon.c @@ -0,0 +1,139 @@ + +#include "shared-module/vectorio/__init__.h" +#include "shared-bindings/vectorio/Polygon.h" + +#include <stdint.h> + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + + +#define VECTORIO_POLYGON_DEBUG(...) (void)0 +// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + + +// Converts a list of points tuples to a flat list of ints for speedier internal use. +// Also validates the points. +static mp_obj_t _to_points_list(mp_obj_t points_tuple_list) { + size_t len = 0; + mp_obj_t *items; + mp_obj_list_get(points_tuple_list, &len, &items); + VECTORIO_POLYGON_DEBUG("polygon_points_list len: %d\n", len); + + if ( len == 0 ) { + mp_raise_TypeError_varg(translate("empty %q list"), MP_QSTR_point); + } + + mp_obj_t points_list = mp_obj_new_list(0, NULL); + + for ( size_t i = 0; i < len; ++i) { + size_t tuple_len = 0; + mp_obj_t *tuple_items; + mp_obj_tuple_get(items[i], &tuple_len, &tuple_items); + + if (tuple_len != 2) { + mp_raise_ValueError_varg(translate("%q must be a tuple of length 2"), MP_QSTR_point); + } + int value; + if (!mp_obj_get_int_maybe(tuple_items[0], &value)) { + mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); + } + mp_obj_list_append(points_list, MP_OBJ_NEW_SMALL_INT(value)); + if (!mp_obj_get_int_maybe(tuple_items[1], &value)) { + mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); + } + mp_obj_list_append(points_list, MP_OBJ_NEW_SMALL_INT(value)); + } + return points_list; +} + + + +//| .. currentmodule:: vectorio +//| +//| :class:`Polygon` -- Represents a closed shape by ordered vertices +//| ========================================================================== +//| +//| .. class:: Polygon( List[ Tuple[ x, y ], ... ] ) +//| +//| :param [Point] points_array: Vertices for the polygon +//| +static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_points_list }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (!MP_OBJ_IS_TYPE(args[ARG_points_list].u_obj, &mp_type_list)) { + mp_raise_TypeError_varg(translate("%q list must be a list"), MP_QSTR_point); + } + mp_obj_t points_list = _to_points_list(args[ARG_points_list].u_obj); + + vectorio_polygon_t *self = m_new_obj(vectorio_polygon_t); + self->base.type = &vectorio_polygon_type; + + common_hal_vectorio_polygon_construct(self, points_list); + + return MP_OBJ_FROM_PTR(self); +} + + +//| .. attribute:: points +//| +//| Set a new look and shape for this polygon +//| +STATIC mp_obj_t vectorio_polygon_obj_get_points(mp_obj_t self_in) { + vectorio_polygon_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t list = mp_obj_new_list(0, NULL); + + size_t len = 0; + mp_obj_t *items; + mp_obj_list_get(common_hal_vectorio_polygon_get_points(self), &len, &items); + + for (size_t i = 0; i < len; i += 2) { + mp_obj_t tuple[] = { items[i], items[i+1] }; + mp_obj_list_append( + list, + mp_obj_new_tuple(2, tuple) + ); + } + return list; +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_polygon_get_points_obj, vectorio_polygon_obj_get_points); + +STATIC mp_obj_t vectorio_polygon_obj_set_points(mp_obj_t self_in, mp_obj_t points) { + vectorio_polygon_t *self = MP_OBJ_TO_PTR(self_in); + + mp_obj_t points_list = _to_points_list(points); + + common_hal_vectorio_polygon_set_points(self, points_list); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_polygon_set_points_obj, vectorio_polygon_obj_set_points); + +const mp_obj_property_t vectorio_polygon_points_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_polygon_get_points_obj, + (mp_obj_t)&vectorio_polygon_set_points_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + + +STATIC const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_points), MP_ROM_PTR(&vectorio_polygon_points_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(vectorio_polygon_locals_dict, vectorio_polygon_locals_dict_table); + +const mp_obj_type_t vectorio_polygon_type = { + { &mp_type_type }, + .name = MP_QSTR_Polygon, + .make_new = vectorio_polygon_make_new, + .locals_dict = (mp_obj_dict_t*)&vectorio_polygon_locals_dict, +}; + diff --git a/shared-bindings/vectorio/Polygon.h b/shared-bindings/vectorio/Polygon.h new file mode 100644 index 000000000..5594fbec4 --- /dev/null +++ b/shared-bindings/vectorio/Polygon.h @@ -0,0 +1,24 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_POLYGON_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_POLYGON_H + +#include "shared-module/vectorio/Polygon.h" +#include "shared-module/displayio/area.h" +#include "shared-module/vectorio/__init__.h" + +extern const mp_obj_type_t vectorio_polygon_type; + +void common_hal_vectorio_polygon_construct(vectorio_polygon_t *self, mp_obj_t points_list); +void common_hal_vectorio_polygon_set_on_dirty(vectorio_polygon_t *self, vectorio_event_t notification); + + +uint32_t common_hal_vectorio_polygon_get_pixel(void *polygon, int16_t x, int16_t y); + +void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *out_area); + + + +mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self); +void common_hal_vectorio_polygon_set_points(vectorio_polygon_t *self, mp_obj_t points_list); + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_POLYGON_H diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c new file mode 100644 index 000000000..ea468f788 --- /dev/null +++ b/shared-bindings/vectorio/Rectangle.c @@ -0,0 +1,56 @@ + +#include "shared-bindings/vectorio/Rectangle.h" + +#include <stdint.h> + +#include "py/objtype.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: vectorio +//| +//| :class:`Rectangle` -- Represents a rectangle by defining its bounds +//| ========================================================================== +//| +//| .. class:: Rectangle(width, height) +//| +//| :param int width: The number of pixels wide +//| :param int height: The number of pixels high +//| +static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_width, ARG_height }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t width = args[ARG_width].u_int; + if (width < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_width); + } + mp_int_t height = args[ARG_height].u_int; + if (height < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_height); + } + + vectorio_rectangle_t *self = m_new_obj(vectorio_rectangle_t); + self->base.type = &vectorio_rectangle_type; + common_hal_vectorio_rectangle_construct(self, width, height); + + return MP_OBJ_FROM_PTR(self); +} + + +STATIC const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = { +}; +STATIC MP_DEFINE_CONST_DICT(vectorio_rectangle_locals_dict, vectorio_rectangle_locals_dict_table); + +const mp_obj_type_t vectorio_rectangle_type = { + { &mp_type_type }, + .name = MP_QSTR_Rectangle, + .make_new = vectorio_rectangle_make_new, + .locals_dict = (mp_obj_dict_t*)&vectorio_rectangle_locals_dict, +}; diff --git a/shared-bindings/vectorio/Rectangle.h b/shared-bindings/vectorio/Rectangle.h new file mode 100644 index 000000000..bb461ed9d --- /dev/null +++ b/shared-bindings/vectorio/Rectangle.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_RECTANGLE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_RECTANGLE_H + +#include "shared-module/vectorio/Rectangle.h" +#include "shared-module/displayio/area.h" + +extern const mp_obj_type_t vectorio_rectangle_type; + +void common_hal_vectorio_rectangle_construct(vectorio_rectangle_t *self, uint32_t width, uint32_t height); + +uint32_t common_hal_vectorio_rectangle_get_pixel(void *rectangle, int16_t x, int16_t y); + +void common_hal_vectorio_rectangle_get_area(void *rectangle, displayio_area_t *out_area); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_RECTANGLE_H diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c new file mode 100644 index 000000000..4b39ec996 --- /dev/null +++ b/shared-bindings/vectorio/VectorShape.c @@ -0,0 +1,195 @@ + +#include "shared-module/vectorio/__init__.h" +#include "shared-bindings/vectorio/VectorShape.h" +#include "shared-bindings/vectorio/Circle.h" +#include "shared-bindings/vectorio/Polygon.h" +#include "shared-bindings/vectorio/Rectangle.h" + +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Palette.h" + +#include <stdint.h> + +#include "lib/utils/context_manager_helpers.h" + +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: vectorio +//| +//| :class:`VectorShape` -- Binds a vector shape to a location and pixel color +//| ========================================================================== +//| +//| .. class:: VectorShape( shape, pixel_shader, x=0, y=0) +//| +//| :param vectorio.Polygon shape: The shape to draw. +//| :param displayio.Palette pixel_shader: The pixel shader that produces colors from values +//| :param int x: Initial x position of the center axis of the shape within the parent. +//| :param int y: Initial y position of the center axis of the shape within the parent. +//| +STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_shape, ARG_pixel_shader, ARG_x, ARG_y }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_shape, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type) && + !MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type)) { + mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader); + } + + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + + mp_obj_t shape = args[ARG_shape].u_obj; + vectorio_ishape_t ishape; + // Wire up shape functions + if (MP_OBJ_IS_TYPE(shape, &vectorio_polygon_type)) { + ishape.shape = shape; + ishape.get_area = &common_hal_vectorio_polygon_get_area; + ishape.get_pixel = &common_hal_vectorio_polygon_get_pixel; + } else if (MP_OBJ_IS_TYPE(shape, &vectorio_rectangle_type)) { + ishape.shape = shape; + ishape.get_area = &common_hal_vectorio_rectangle_get_area; + ishape.get_pixel = &common_hal_vectorio_rectangle_get_pixel; + } else if (MP_OBJ_IS_TYPE(shape, &vectorio_circle_type)) { + ishape.shape = shape; + ishape.get_area = &common_hal_vectorio_circle_get_area; + ishape.get_pixel = &common_hal_vectorio_circle_get_pixel; + } else { + mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_shape); + } + + vectorio_vector_shape_t *self = m_new_obj(vectorio_vector_shape_t); + self->base.type = &vectorio_vector_shape_type; + common_hal_vectorio_vector_shape_construct(self, + ishape, pixel_shader, x, y + ); + + // Wire up event callbacks + vectorio_event_t on_dirty = { + .obj = self, + .event = &common_hal_vectorio_vector_shape_set_dirty + }; + + if (MP_OBJ_IS_TYPE(shape, &vectorio_polygon_type)) { + common_hal_vectorio_polygon_set_on_dirty(self->ishape.shape, on_dirty); + } else if (MP_OBJ_IS_TYPE(shape, &vectorio_rectangle_type)) { + } else if (MP_OBJ_IS_TYPE(shape, &vectorio_circle_type)) { + common_hal_vectorio_circle_set_on_dirty(self->ishape.shape, on_dirty); + } else { + mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_shape); + } + + return MP_OBJ_FROM_PTR(self); +} + + +//| .. attribute:: x +//| +//| X position of the center point of the shape in the parent. +//| +STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t self_in) { + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_x(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_x_obj, vectorio_vector_shape_obj_get_x); + +STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) { + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t x = mp_obj_get_int(x_obj); + common_hal_vectorio_vector_shape_set_x(self, x); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_vector_shape_set_x_obj, vectorio_vector_shape_obj_set_x); + +const mp_obj_property_t vectorio_vector_shape_x_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_vector_shape_get_x_obj, + (mp_obj_t)&vectorio_vector_shape_set_x_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: y +//| +//| Y position of the center point of the shape in the parent. +//| +STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t self_in) { + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_y(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_y_obj, vectorio_vector_shape_obj_get_y); + +STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) { + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t y = mp_obj_get_int(y_obj); + common_hal_vectorio_vector_shape_set_y(self, y); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_vector_shape_set_y_obj, vectorio_vector_shape_obj_set_y); + +const mp_obj_property_t vectorio_vector_shape_y_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_vector_shape_get_y_obj, + (mp_obj_t)&vectorio_vector_shape_set_y_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: pixel_shader +//| +//| The pixel shader of the shape. +//| +STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t self_in) { + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_vectorio_vector_shape_get_pixel_shader(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_pixel_shader_obj, vectorio_vector_shape_obj_get_pixel_shader); + +STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); + if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type) && !MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type)) { + mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); + } + + common_hal_vectorio_vector_shape_set_pixel_shader(self, pixel_shader); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_vector_shape_set_pixel_shader_obj, vectorio_vector_shape_obj_set_pixel_shader); + +const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_vector_shape_get_pixel_shader_obj, + (mp_obj_t)&vectorio_vector_shape_set_pixel_shader_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t vectorio_vector_shape_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(vectorio_vector_shape_locals_dict, vectorio_vector_shape_locals_dict_table); + +const mp_obj_type_t vectorio_vector_shape_type = { + { &mp_type_type }, + .name = MP_QSTR_VectorShape, + .make_new = vectorio_vector_shape_make_new, + .locals_dict = (mp_obj_dict_t*)&vectorio_vector_shape_locals_dict, +}; diff --git a/shared-bindings/vectorio/VectorShape.h b/shared-bindings/vectorio/VectorShape.h new file mode 100644 index 000000000..d098504e9 --- /dev/null +++ b/shared-bindings/vectorio/VectorShape.h @@ -0,0 +1,27 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H + +#include "shared-module/vectorio/VectorShape.h" +#include "shared-module/displayio/area.h" + +extern const mp_obj_type_t vectorio_vector_shape_type; + +void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self, + vectorio_ishape_t ishape, + mp_obj_t pixel_shader, uint16_t x, uint16_t y); + +void common_hal_vectorio_vector_shape_set_dirty(void *self); + +mp_int_t common_hal_vectorio_vector_shape_get_x(vectorio_vector_shape_t *self); +void common_hal_vectorio_vector_shape_set_x(vectorio_vector_shape_t *self, mp_int_t x); + +mp_int_t common_hal_vectorio_vector_shape_get_y(vectorio_vector_shape_t *self); +void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_int_t y); + +mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self); +void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *self, mp_obj_t pixel_shader); + + +void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c new file mode 100644 index 000000000..b9e3828bd --- /dev/null +++ b/shared-bindings/vectorio/__init__.c @@ -0,0 +1,46 @@ +#include <stdint.h> + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/vectorio/Circle.h" +#include "shared-bindings/vectorio/Polygon.h" +#include "shared-bindings/vectorio/Rectangle.h" +#include "shared-bindings/vectorio/VectorShape.h" + +//| :mod:`vectorio` --- Lightweight 2d shapes for displays +//| ========================================================================= +//| +//| .. module:: vectorio +//| :synopsis: Adds vector graphics to displayio +//| :platform: SAMD21, SAMD51, nRF52 +//| +//| The `vectorio` module contains classes to construct shapes +//| by describing their points rather than providing them in bitmaps. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Circle +//| Polygon +//| Rectangle +//| VectorShape +//| + + +STATIC const mp_rom_map_elem_t vectorio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_vectorio) }, + { MP_ROM_QSTR(MP_QSTR_Circle), MP_ROM_PTR(&vectorio_circle_type) }, + { MP_ROM_QSTR(MP_QSTR_Polygon), MP_ROM_PTR(&vectorio_polygon_type) }, + { MP_ROM_QSTR(MP_QSTR_Rectangle), MP_ROM_PTR(&vectorio_rectangle_type) }, + { MP_ROM_QSTR(MP_QSTR_VectorShape), MP_ROM_PTR(&vectorio_vector_shape_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(vectorio_module_globals, vectorio_module_globals_table); + +const mp_obj_module_t vectorio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&vectorio_module_globals, +}; diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index d69e9f585..15cf5b8e4 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -29,6 +29,11 @@ #include "py/runtime.h" #include "shared-bindings/displayio/TileGrid.h" +#if CIRCUITPY_VECTORIO +#include "shared-bindings/vectorio/VectorShape.h" +#endif + + void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) { displayio_group_child_t* children = m_new(displayio_group_child_t, max_size); displayio_group_construct(self, children, max_size, scale, x, y); @@ -117,6 +122,12 @@ static void _update_child_transforms(displayio_group_t* self) { } for (size_t i = 0; i < self->size; i++) { mp_obj_t layer = self->children[i].native; +#if CIRCUITPY_VECTORIO + if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + vectorio_vector_shape_update_transform(layer, &self->absolute_transform); + } + else +#endif if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { displayio_tilegrid_update_transform(layer, &self->absolute_transform); } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { @@ -200,7 +211,15 @@ void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) { } static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) { - mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); + mp_obj_t native_layer; +#if CIRCUITPY_VECTORIO + native_layer = mp_instance_cast_to_native_base(layer, &vectorio_vector_shape_type); + if (native_layer != MP_OBJ_NULL) { + vectorio_vector_shape_update_transform(native_layer, &self->absolute_transform); + return native_layer; + } +#endif + native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); if (native_layer == MP_OBJ_NULL) { native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); if (native_layer == MP_OBJ_NULL) { @@ -229,6 +248,14 @@ static void _remove_layer(displayio_group_t* self, size_t index) { mp_obj_t layer = self->children[index].native; displayio_area_t layer_area; bool rendered_last_frame = false; +#if CIRCUITPY_VECTORIO + if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + bool has_dirty_area = vectorio_vector_shape_get_dirty_area(layer, &layer_area); + rendered_last_frame = has_dirty_area; + vectorio_vector_shape_update_transform(layer, NULL); + } + else +#endif if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { displayio_tilegrid_t* tilegrid = layer; rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area); @@ -317,6 +344,15 @@ bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorsp bool full_coverage = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; +#if CIRCUITPY_VECTORIO + if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + if (vectorio_vector_shape_fill_area(layer, colorspace, area, mask, buffer)) { + full_coverage = true; + break; + } + } + else +#endif if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { if (displayio_tilegrid_fill_area(layer, colorspace, area, mask, buffer)) { full_coverage = true; @@ -336,6 +372,12 @@ void displayio_group_finish_refresh(displayio_group_t *self) { self->item_removed = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; +#if CIRCUITPY_VECTORIO + if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + vectorio_vector_shape_finish_refresh(layer); + } + else +#endif if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { displayio_tilegrid_finish_refresh(layer); } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { @@ -352,6 +394,12 @@ displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, dis for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; +#if CIRCUITPY_VECTORIO + if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + tail = vectorio_vector_shape_get_refresh_areas(layer, tail); + } + else +#endif if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { tail = displayio_tilegrid_get_refresh_areas(layer, tail); } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c index d01100f7f..43f2d1937 100644 --- a/shared-module/displayio/display_core.c +++ b/shared-module/displayio/display_core.c @@ -40,6 +40,9 @@ #include <stdint.h> #include <string.h> +#define DISPLAYIO_CORE_DEBUG(...) (void)0 +// #define DISPLAYIO_CORE_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + void displayio_display_core_construct(displayio_display_core_t* self, mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word) { @@ -298,6 +301,7 @@ void displayio_display_core_start_refresh(displayio_display_core_t* self) { void displayio_display_core_finish_refresh(displayio_display_core_t* self) { if (self->current_group != NULL) { + DISPLAYIO_CORE_DEBUG("displayiocore group_finish_refresh\n"); displayio_group_finish_refresh(self->current_group); } self->full_refresh = false; diff --git a/shared-module/vectorio/Circle.c b/shared-module/vectorio/Circle.c new file mode 100644 index 000000000..999d62512 --- /dev/null +++ b/shared-module/vectorio/Circle.c @@ -0,0 +1,56 @@ + +#include "shared-bindings/vectorio/Circle.h" +#include "shared-module/vectorio/__init__.h" +#include "shared-module/displayio/area.h" + +#include "py/runtime.h" +#include "stdlib.h" + + +void common_hal_vectorio_circle_construct(vectorio_circle_t *self, uint16_t radius) { + self->radius = radius; + self->on_dirty.obj = NULL; +} + +void common_hal_vectorio_circle_set_on_dirty(vectorio_circle_t *self, vectorio_event_t on_dirty) { + if (self->on_dirty.obj != NULL) { + mp_raise_TypeError(translate("circle can only be registered in one parent")); + } + self->on_dirty = on_dirty; +} + + +uint32_t common_hal_vectorio_circle_get_pixel(void *obj, int16_t x, int16_t y) { + vectorio_circle_t *self = obj; + int16_t radius = abs(self->radius); + x = abs(x); + y = abs(y); + if (x+y <= radius) return 1; + if (x > radius) return 0; + if (y > radius) return 0; + const bool pythagorasSmallerThanRadius = (int32_t)x*x + (int32_t)y*y <= (int32_t)radius*radius; + return pythagorasSmallerThanRadius ? 1 : 0; +} + + +void common_hal_vectorio_circle_get_area(void *circle, displayio_area_t *out_area) { + vectorio_circle_t *self = circle; + out_area->x1 = -1 * self->radius - 1; + out_area->y1 = -1 * self->radius - 1; + out_area->x2 = self->radius + 1; + out_area->y2 = self->radius + 1; +} + +int16_t common_hal_vectorio_circle_get_radius(void *obj) { + vectorio_circle_t *self = obj; + return self->radius; +} + +void common_hal_vectorio_circle_set_radius(void *obj, int16_t radius) { + vectorio_circle_t *self = obj; + self->radius = abs(radius); + if (self->on_dirty.obj != NULL) { + self->on_dirty.event(self->on_dirty.obj); + } +} + diff --git a/shared-module/vectorio/Circle.h b/shared-module/vectorio/Circle.h new file mode 100644 index 000000000..4b43d767e --- /dev/null +++ b/shared-module/vectorio/Circle.h @@ -0,0 +1,17 @@ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_CIRCLE_H +#define MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_CIRCLE_H + +#include <stdint.h> + +#include "py/obj.h" + +#include "shared-module/vectorio/__init__.h" + +typedef struct { + mp_obj_base_t base; + uint16_t radius; + vectorio_event_t on_dirty; +} vectorio_circle_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_CIRCLE_H + diff --git a/shared-module/vectorio/Polygon.c b/shared-module/vectorio/Polygon.c new file mode 100644 index 000000000..6722912c2 --- /dev/null +++ b/shared-module/vectorio/Polygon.c @@ -0,0 +1,110 @@ + +#include "shared-module/vectorio/__init__.h" +#include "shared-bindings/vectorio/Polygon.h" +#include "shared-module/displayio/area.h" + +#include "py/runtime.h" +#include "stdlib.h" +#include <stdio.h> + + +#define VECTORIO_POLYGON_DEBUG(...) (void)0 +// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + + +void common_hal_vectorio_polygon_construct(vectorio_polygon_t *self, mp_obj_t points_list) { + VECTORIO_POLYGON_DEBUG("%p polygon_construct\n", self); + self->points_list = points_list; + self->on_dirty.obj = NULL; +} + + +mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self) { + return self->points_list; +} +void common_hal_vectorio_polygon_set_points(vectorio_polygon_t *self, mp_obj_t points_list) { + self->points_list = points_list; + if (self->on_dirty.obj != NULL) { + self->on_dirty.event(self->on_dirty.obj); + } +} + +void common_hal_vectorio_polygon_set_on_dirty(vectorio_polygon_t *self, vectorio_event_t notification) { + if ( self->on_dirty.obj != NULL ) { + mp_raise_TypeError(translate("polygon can only be registered in one parent")); + } + self->on_dirty = notification; +} + + +void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *area) { + VECTORIO_POLYGON_DEBUG("%p polygon get_area", polygon); + vectorio_polygon_t *self = polygon; + size_t len; + mp_obj_t *points; + mp_obj_list_get(self->points_list, &len, &points); + VECTORIO_POLYGON_DEBUG(" len: %2d, points: %d\n", len, len/2); + + area->x1 = SHRT_MAX; + area->y1 = SHRT_MAX; + area->x2 = SHRT_MIN; + area->y2 = SHRT_MIN; + for (size_t i=0; i < len; ++i) { + mp_int_t x = mp_obj_get_int(points[i]); + ++i; + mp_int_t y = mp_obj_get_int(points[i]); + if (x <= area->x1) area->x1 = x-1; + if (y <= area->y1) area->y1 = y-1; + if (x >= area->x2) area->x2 = x+1; + if (y >= area->y2) area->y2 = y+1; + } +} + + +// <0 if the point is to the left of the line vector +// 0 if the point is on the line +// >0 if the point is to the right of the line vector +__attribute__((always_inline)) static inline int line_side( mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, int16_t px, int16_t py ) { + return (px - x1) * (y2 - y1) + - (py - y1) * (x2 - x1); +} + + +uint32_t common_hal_vectorio_polygon_get_pixel(void *obj, int16_t x, int16_t y) { + VECTORIO_POLYGON_DEBUG("%p polygon get_pixel %d, %d\n", obj, x, y); + vectorio_polygon_t *self = obj; + size_t len; + mp_obj_t *points; + mp_obj_list_get(self->points_list, &len, &points); + + if (len == 0) { + return 0; + } + + int winding_number = 0; + mp_int_t x1 = mp_obj_get_int(points[0]); + mp_int_t y1 = mp_obj_get_int(points[1]); + for (size_t i=2; i <= len + 1; ++i) { + VECTORIO_POLYGON_DEBUG(" {(%3d, %3d),", x1, y1); + mp_int_t x2 = mp_obj_get_int(points[i % len]); + ++i; + mp_int_t y2 = mp_obj_get_int(points[i % len]); + VECTORIO_POLYGON_DEBUG(" (%3d, %3d)}\n", x2, y2); + if ( y1 <= y ) { + if ( y2 > y && line_side(x1, y1, x2, y2, x, y) > 0 ) { + // Wind up, point is to the right of the edge vector + ++winding_number; + VECTORIO_POLYGON_DEBUG(" wind:%2d winding_number:%2d\n", 1, winding_number); + } + } else if ( y2 <= y && line_side(x1, y1, x2, y2, x, y) < 0 ) { + // Wind down, point is to the left of the edge vector + --winding_number; + VECTORIO_POLYGON_DEBUG(" wind:%2d winding_number:%2d\n", -1, winding_number); + } + + x1 = x2; + y1 = y2; + } + return winding_number == 0 ? 0 : 1; +} + diff --git a/shared-module/vectorio/Polygon.h b/shared-module/vectorio/Polygon.h new file mode 100644 index 000000000..1aef854a7 --- /dev/null +++ b/shared-module/vectorio/Polygon.h @@ -0,0 +1,16 @@ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_POLYGON_H +#define MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_POLYGON_H + +#include <stdint.h> + +#include "py/obj.h" +#include "shared-module/vectorio/__init__.h" + +typedef struct { + mp_obj_base_t base; + // A micropython List[ x, y, ... ] + mp_obj_t points_list; + vectorio_event_t on_dirty; +} vectorio_polygon_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_POLYGON_H diff --git a/shared-module/vectorio/Rectangle.c b/shared-module/vectorio/Rectangle.c new file mode 100644 index 000000000..7fabe6ff9 --- /dev/null +++ b/shared-module/vectorio/Rectangle.c @@ -0,0 +1,35 @@ +#include "shared-bindings/vectorio/Rectangle.h" +#include "shared-module/displayio/area.h" + +#include "py/runtime.h" + + +void common_hal_vectorio_rectangle_construct(vectorio_rectangle_t *self, uint32_t width, uint32_t height) { + self->width = width; + self->height = height; +} + + +uint32_t common_hal_vectorio_rectangle_get_pixel(void *obj, int16_t x, int16_t y) { + vectorio_rectangle_t *self = obj; + if (x < 0 || x > self->width || y > self->height || y < 0) { + return 0; + } + return 1; +} + + +void common_hal_vectorio_rectangle_get_area(void *rectangle, displayio_area_t *out_area) { + vectorio_rectangle_t *self = rectangle; + out_area->x1 = -1; + out_area->y1 = -1; + out_area->x2 = self->width; + out_area->y2 = self->height; +} + + +uint32_t common_hal_vectorio_rectangle_get_height(void *rectangle) { + vectorio_rectangle_t *self = rectangle; + return self->height; +} + diff --git a/shared-module/vectorio/Rectangle.h b/shared-module/vectorio/Rectangle.h new file mode 100644 index 000000000..c1f2a7a64 --- /dev/null +++ b/shared-module/vectorio/Rectangle.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_RECTANGLE_H +#define MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_RECTANGLE_H + +#include <stdint.h> + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint16_t width; + uint16_t height; +} vectorio_rectangle_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_RECTANGLE_H + diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c new file mode 100644 index 000000000..4fb353aae --- /dev/null +++ b/shared-module/vectorio/VectorShape.c @@ -0,0 +1,336 @@ + +#include "stdlib.h" + +#include "shared-module/vectorio/__init__.h" +#include "shared-bindings/vectorio/VectorShape.h" + +#include "py/runtime.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Palette.h" + +#include "shared-bindings/vectorio/Circle.h" +#include "shared-bindings/vectorio/Polygon.h" +#include "shared-bindings/vectorio/Rectangle.h" + +// Lifecycle actions. +#define VECTORIO_SHAPE_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + + +// Used in both logging and ifdefs, for extra variables +// #define VECTORIO_PERF(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + + +// Really verbose. +#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + + +inline __attribute__((always_inline)) +static int32_t max(int32_t a, int32_t b) { + return a > b ? a : b; +} + + +inline __attribute__((always_inline)) +static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { + VECTORIO_SHAPE_DEBUG("%p get_screen_area tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", self, + self->absolute_transform->x, self->absolute_transform->y, self->absolute_transform->dx, self->absolute_transform->dy, self->absolute_transform->scale, + self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy + ); + self->ishape.get_area(self->ishape.shape, out_area); + VECTORIO_SHAPE_DEBUG(" in:{(%5d,%5d), (%5d,%5d)}", out_area->x1, out_area->y1, out_area->x2, out_area->y2); + if (self->absolute_transform->transpose_xy) { + int16_t swap = out_area->x1; + out_area->x1 = (out_area->y1 + self->y) * self->absolute_transform->dx + self->absolute_transform->x; + out_area->y1 = (swap + self->x) * self->absolute_transform->dy + self->absolute_transform->y; + swap = out_area->x2; + out_area->x2 = (out_area->y2 + self->y) * self->absolute_transform->dx + self->absolute_transform->x; + out_area->y2 = (swap + self->x) * self->absolute_transform->dy + self->absolute_transform->y; + } else { + out_area->x1 = (out_area->x1 + self->x) * self->absolute_transform->dx + self->absolute_transform->x; + out_area->y1 = (out_area->y1 + self->y) * self->absolute_transform->dy + self->absolute_transform->y; + out_area->x2 = (out_area->x2 + self->x) * self->absolute_transform->dx + self->absolute_transform->x; + out_area->y2 = (out_area->y2 + self->y) * self->absolute_transform->dy + self->absolute_transform->y; + } + // We might have mirrored due to dx + if (out_area->x2 < out_area->x1) { + int16_t swap = out_area->x1; + out_area->x1 = out_area->x2; + out_area->x2 = swap; + } + if (out_area->y2 < out_area->y1) { + int16_t swap = out_area->y1; + out_area->y1 = out_area->y2; + out_area->y2 = swap; + } + VECTORIO_SHAPE_DEBUG(" out:{(%5d,%5d), (%5d,%5d)}\n", out_area->x1, out_area->y1, out_area->x2, out_area->y2); +} + + +// For use by Group to know where it needs to redraw on layer removal. +bool vectorio_vector_shape_get_dirty_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { + displayio_area_copy(&self->ephemeral_dirty_area, out_area); + return true; // For now just always redraw. +} + + +// This must be invoked each time a shape changes its position or its shape in any way. +void common_hal_vectorio_vector_shape_set_dirty(void *vector_shape) { + vectorio_vector_shape_t *self = vector_shape; + // In screen space. Need to offset the shape space. + displayio_area_t current_area; + _get_screen_area(self, ¤t_area); + VECTORIO_SHAPE_DEBUG("%p shape_dirty current:{(%3d,%3d), (%3d,%3d)} dirty:{(%3d,%3d), (%3d,%3d)}", + self, + current_area.x1, current_area.y1, current_area.x2, current_area.y2, + self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + self->dirty = true; + // Dirty area tracks the shape's footprint between draws. It's reset on refresh finish, + displayio_area_expand(&self->ephemeral_dirty_area, ¤t_area); + VECTORIO_SHAPE_DEBUG(" -> expanded:{(%3d,%3d), (%3d,%3d)}\n", self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); +} + + +static displayio_buffer_transform_t null_transform = { + .x = 0, + .y = 0, + .dx = 1, + .dy = 1, + .scale = 1, + .width = 0, + .height = 0, + .mirror_x = false, + .mirror_y = false, + .transpose_xy = false +}; + + +void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self, + vectorio_ishape_t ishape, + mp_obj_t pixel_shader, uint16_t x, uint16_t y) { + VECTORIO_SHAPE_DEBUG("%p vector_shape_construct x:%3d, y:%3d\n", self, x, y); + self->x = x; + self->y = y; + self->pixel_shader = pixel_shader; + self->ishape = ishape; + self->dirty = true; + self->absolute_transform = &null_transform; // Critical to have a valid transform before getting screen area. + _get_screen_area(self, &self->ephemeral_dirty_area); + self->ephemeral_dirty_area.next = NULL; +} + + +mp_int_t common_hal_vectorio_vector_shape_get_x(vectorio_vector_shape_t *self) { + VECTORIO_SHAPE_DEBUG("%p get_x\n", self); + return self->x; +} + + +void common_hal_vectorio_vector_shape_set_x(vectorio_vector_shape_t *self, mp_int_t x) { + VECTORIO_SHAPE_DEBUG("%p set_x %d\n", self, x); + if (self->x == x) { + return; + } + self->x = x; + common_hal_vectorio_vector_shape_set_dirty(self); +} + + +mp_int_t common_hal_vectorio_vector_shape_get_y(vectorio_vector_shape_t *self) { + VECTORIO_SHAPE_DEBUG("%p get_y\n", self); + return self->y; +} + + +void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_int_t y) { + VECTORIO_SHAPE_DEBUG("%p set_y %d\n", self, y); + if (self->y == y) { + return; + } + self->y = y; + common_hal_vectorio_vector_shape_set_dirty(self); +} + + +mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self) { + VECTORIO_SHAPE_DEBUG("%p get_pixel_shader\n", self); + return self->pixel_shader; +} + +void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *self, mp_obj_t pixel_shader) { + VECTORIO_SHAPE_DEBUG("%p set_pixel_shader\n", self); + self->pixel_shader = pixel_shader; + common_hal_vectorio_vector_shape_set_dirty(self); +} + + +bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { + // Shape areas are relative to 0,0. This will allow rotation about a known axis. + // The consequence is that the area reported by the shape itself is _relative_ to 0,0. + // To make it relative to the VectorShape position, we must shift it. + // Pixels are drawn on the screen_area (shifted) coordinate space, while pixels are _determined_ from + // the shape_area (unshifted) space. +#ifdef VECTORIO_PERF + uint64_t start = common_hal_time_monotonic_ns(); + uint64_t pixel_time = 0; +#endif + displayio_area_t overlap; + VECTORIO_SHAPE_DEBUG("%p fill_area dirty:%d fill: {(%5d,%5d), (%5d,%5d)} dirty: {(%5d,%5d), (%5d,%5d)}", + self, self->dirty, + area->x1, area->y1, area->x2, area->y2, + self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2 + ); + if (!displayio_area_compute_overlap(area, &self->ephemeral_dirty_area, &overlap)) { + VECTORIO_SHAPE_DEBUG(" no overlap\n"); + return false; + } + VECTORIO_SHAPE_DEBUG(", overlap: {(%3d,%3d), (%3d,%3d)}", overlap.x1, overlap.y1, overlap.x2, overlap.y2); + + bool full_coverage = displayio_area_equal(area, &overlap); + + uint8_t pixels_per_byte = 8 / colorspace->depth; + + uint32_t linestride_px = displayio_area_width(area); + uint32_t line_dirty_offset_px = (overlap.y1 - area->y1) * linestride_px; + uint32_t column_dirty_offset_px = overlap.x1 - area->x1; + VECTORIO_SHAPE_DEBUG(", linestride:%3d line_offset:%3d col_offset:%3d depth:%2d ppb:%2d shape:%s", + linestride_px, line_dirty_offset_px, column_dirty_offset_px, colorspace->depth, pixels_per_byte, mp_obj_get_type_str(self->ishape.shape)); + + displayio_input_pixel_t input_pixel; + displayio_output_pixel_t output_pixel; + + uint32_t mask_start_px = line_dirty_offset_px; + for (input_pixel.y = overlap.y1; input_pixel.y < overlap.y2; ++input_pixel.y) { + mask_start_px += column_dirty_offset_px; + for (input_pixel.x = overlap.x1; input_pixel.x < overlap.x2; ++input_pixel.x) { + // Check the mask first to see if the pixel has already been set. + uint32_t pixel_index = mask_start_px + (input_pixel.x - overlap.x1); + uint32_t *mask_doubleword = &(mask[pixel_index / 32]); + uint8_t mask_bit = pixel_index % 32; + VECTORIO_SHAPE_PIXEL_DEBUG("%p pixel_index: %5u mask_bit: %2u", self, pixel_index, mask_bit); + if ((*mask_doubleword & (1u << mask_bit)) != 0) { + VECTORIO_SHAPE_PIXEL_DEBUG(" masked\n"); + continue; + } + output_pixel.pixel = 0; + + // Get the target pixel based on the shape's coordinate space + int16_t pixel_to_get_x; + int16_t pixel_to_get_y; + if (self->absolute_transform->transpose_xy) { + pixel_to_get_x = (input_pixel.y - self->absolute_transform->dy * self->x - self->absolute_transform->y) / self->absolute_transform->dy; + pixel_to_get_y = (input_pixel.x - self->absolute_transform->dx * self->y - self->absolute_transform->x) / self->absolute_transform->dx; + } else { + pixel_to_get_x = (input_pixel.x - self->absolute_transform->dx * self->x) / self->absolute_transform->dx; + pixel_to_get_y = (input_pixel.y - self->absolute_transform->dy * self->y) / self->absolute_transform->dy; + } + VECTORIO_SHAPE_PIXEL_DEBUG(" get_pixel %p (%3d, %3d) -> ( %3d, %3d )", self->ishape.shape, input_pixel.x, input_pixel.y, pixel_to_get_x, pixel_to_get_y); +#ifdef VECTORIO_PERF + uint64_t pre_pixel = common_hal_time_monotonic_ns(); +#endif + input_pixel.pixel = self->ishape.get_pixel(self->ishape.shape, pixel_to_get_x, pixel_to_get_y); +#ifdef VECTORIO_PERF + uint64_t post_pixel = common_hal_time_monotonic_ns(); + pixel_time += post_pixel - pre_pixel; +#endif + VECTORIO_SHAPE_PIXEL_DEBUG(" -> %d", input_pixel.pixel); + + output_pixel.opaque = true; + if (self->pixel_shader == mp_const_none) { + output_pixel.pixel = input_pixel.pixel; + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); + } + if (!output_pixel.opaque) { + VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)\n"); + full_coverage = false; + } else { + *mask_doubleword |= 1u << mask_bit; + if (colorspace->depth == 16) { + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16\n", output_pixel.pixel); + *(((uint16_t*) buffer) + pixel_index) = output_pixel.pixel; + } else if (colorspace->depth == 8) { + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %02x 8\n", output_pixel.pixel); + *(((uint8_t*) buffer) + pixel_index) = output_pixel.pixel; + } else if (colorspace->depth < 8) { + // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). + if (!colorspace->pixels_in_byte_share_row) { + uint16_t width = linestride_px; + uint16_t row = pixel_index / width; + uint16_t col = pixel_index % width; + pixel_index = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * width + row % pixels_per_byte; + } + uint8_t shift = (pixel_index % pixels_per_byte) * colorspace->depth; + if (colorspace->reverse_pixels_in_byte) { + // Reverse the shift by subtracting it from the leftmost shift. + shift = (pixels_per_byte - 1) * colorspace->depth - shift; + } + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %2d %d\n", output_pixel.pixel, colorspace->depth); + ((uint8_t*)buffer)[pixel_index / pixels_per_byte] |= output_pixel.pixel << shift; + } + } + } + mask_start_px += linestride_px - column_dirty_offset_px; + } +#ifdef VECTORIO_PERF + uint64_t end = common_hal_time_monotonic_ns(); + uint32_t pixels = (overlap.x2 - overlap.x1) * (overlap.y2 - overlap.y1); + VECTORIO_PERF("draw %16s -> shape:{%4dpx, %4.1fms,%9.1fpps fill} shape_pixels:{%6.1fus total, %4.1fus/px}\n", + mp_obj_get_type_str(self->ishape.shape), + (overlap.x2 - overlap.x1) * (overlap.y2 - overlap.y1), + (double)((end - start) / 1000000.0), + (double)(max(1, pixels * (1000000000.0 / (end - start)))), + (double)(pixel_time / 1000.0), + (double)(pixel_time / 1000.0 / pixels) + ); +#endif + VECTORIO_SHAPE_DEBUG(" -> pixels:%4d\n"); + return full_coverage; +} + + +void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { + if ( !self->dirty ) { + return; + } + VECTORIO_SHAPE_DEBUG("%p finish_refresh was:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + self->dirty = false; + // Reset dirty area tracking to current footprint + _get_screen_area(self, &self->ephemeral_dirty_area); + self->ephemeral_dirty_area.next = NULL; + VECTORIO_SHAPE_DEBUG("%p finish_refresh now:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + + if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + displayio_palette_finish_refresh(self->pixel_shader); + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_finish_refresh(self->pixel_shader); + } +} + + +// Assembles a singly linked list of dirty areas from all components on the display. +displayio_area_t* vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t* tail) { + if (self->dirty + || (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) + || (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)) + ) { + VECTORIO_SHAPE_DEBUG("%p get_refresh_area dirty:%d {(%3d,%3d), (%3d,%3d)}", self, self->dirty, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + common_hal_vectorio_vector_shape_set_dirty(self); + // vector.add_to_head + self->ephemeral_dirty_area.next = tail; + VECTORIO_SHAPE_DEBUG(" this_area: %p next: %p after: %p\n", &self->ephemeral_dirty_area, tail, tail == NULL ? NULL : tail->next); + return &self->ephemeral_dirty_area; + } + return tail; +} + +void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform) { + self->absolute_transform = group_transform == NULL ? &null_transform : group_transform; + common_hal_vectorio_vector_shape_set_dirty(self); +} + + diff --git a/shared-module/vectorio/VectorShape.h b/shared-module/vectorio/VectorShape.h new file mode 100644 index 000000000..56eb3d8a5 --- /dev/null +++ b/shared-module/vectorio/VectorShape.h @@ -0,0 +1,53 @@ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_SHAPE_H +#define MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_SHAPE_H + +#include <stdbool.h> +#include <stdint.h> + +#include "py/obj.h" +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" + +typedef void get_area_function(mp_obj_t shape, displayio_area_t *out_area); +typedef uint32_t get_pixel_function(mp_obj_t shape, int16_t x, int16_t y); + +// This struct binds a shape's common Shape support functions (its vector shape interface) +// to its instance pointer. We only check at construction time what the type of the +// associated shape is and link the correct functions up. +// Later when using the shape for drawing logic these functions may be invoked +// unconditionally. This simplifies the addition of new types and restricts the +// respective responsibilities of VectorShape and actual shape implementations. +typedef struct { + mp_obj_t shape; + get_area_function *get_area; + get_pixel_function *get_pixel; +} vectorio_ishape_t; + +typedef struct { + mp_obj_base_t base; + vectorio_ishape_t ishape; + mp_obj_t pixel_shader; + int16_t x; + int16_t y; + displayio_buffer_transform_t *absolute_transform; + bool dirty; // True if we need to draw + // Tracks current shape footprint and expands outward as the shape dirties and changes. + // This is suboptimal if you move your shape far. Could add more state to only redraw + // exactly what we left behind. + displayio_area_t ephemeral_dirty_area; +} vectorio_vector_shape_t; + +displayio_area_t* vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail); + +bool vectorio_vector_shape_get_dirty_area(vectorio_vector_shape_t *self, displayio_area_t *current_dirty_area); + +// Area is always in absolute screen coordinates. +bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displayio_colorspace_t *colorspace, const displayio_area_t *area, uint32_t *mask, uint32_t *buffer); + +// Fills in out_area with the maximum bounds of all related pixels in the last rendered frame. Returns +// false if the vector shape wasn't rendered in the last frame. +bool vectorio_vector_shape_get_previous_area(vectorio_vector_shape_t *self, displayio_area_t *out_area); +void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_SHAPE_H diff --git a/shared-module/vectorio/__init__.c b/shared-module/vectorio/__init__.c new file mode 100644 index 000000000..473c509c3 --- /dev/null +++ b/shared-module/vectorio/__init__.c @@ -0,0 +1,3 @@ + +// Don't need anything in here yet + diff --git a/shared-module/vectorio/__init__.h b/shared-module/vectorio/__init__.h new file mode 100644 index 000000000..6ae381f06 --- /dev/null +++ b/shared-module/vectorio/__init__.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_INIT_H +#define MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_INIT_H + +#include "py/obj.h" + +typedef void event_function(mp_obj_t obj); + +typedef struct { + mp_obj_t obj; + event_function *event; +} vectorio_event_t; + + +#endif + |
