* Removes VectorShape from user python interactions
* Re-integrates vectorio with displayio behind draw protocol implementations
* Implements draw protocol with VectorShape
* Composes VectorShape behaviors into Rectangle, Circle and Polygon
* Fixes terrible pixel garbage being left behind
* Improves redraw performance (heuristically) by tracking dirty area separately from current area.
Known Issues:
It does not work with transposed views.
Before, when an OnDiskBitmap was a paletted bitmap type, the palette
was internal to the OnDiskBitmap, and it internally performed the palette
conversion itself. When using with a tilegrid, a ColorConverter() object
always had to be passed.
Now, an OnDiskBitmap has a "pixel_shader" property. If the bitmap is
a paletted bitmap type, it is a (modifiable) Palette object. Otherwise,
it is a ColorConverter() object as before. This allows palette effects
to be applied to paletted OnDiskBitmaps.
Code that used to say:
```python
face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter())
```
must be updated to say:
```python
face = displayio.TileGrid(odb, pixel_shader=odb.pixel_shader)
```
Compatible code for 6.x and 7.x can say
```python
face = displayio.TileGrid(odb, pixel_shader=getattr(odb, 'pixel_shader', ColorConverter())
```
We can't handle rgbmatrix's interrupts from here until the display is
reinitialized, so set the display as paused.
With this change, I can survive multiple cycles with wifi+rgbmatrix
on an esp32s2. Before, it usually failed.
This also removes the need to pin share because we don't use the
status LED while user code is running.
The status flashes fallback to the HW_STATUS LED if no RGB LED is
present. Each status has a unique blink pattern as well.
One caveat is the REPL state. In order to not pin share, we set the
RGB color once. PWM and single color will be shutoff immediately but
DotStars and NeoPixels will hold the color until the user overrides
it.
Fixes#4133
It is required to call .dirty() with appropriate arguments after modifications through the buffer protocol, or the display might not be updated correctly.
This is a modest code savings, but more importantly it reduces
boilerplate in bitmap-modifying routines.
Callers need only ensure they call displayio_bitmap_set_dirty_area in
advance of the bitmap modifications they perform.
(note that this assumes that no bitmap operation can enter background
tasks. If an operation COULD enter background tasks, it MUST re-dirty
the area it touches when it exits, simply by a fresh call to
set_dirty_area with the same area as before)
.. simplifying code in the process. For instance, now fill_region
uses area routines to order and constrain its coordinates.
Happily, this change also frees a modest amount of code space.
.. and simplify the implmentation of displayio_area_union
This _slightly_ changes the behavior of displayio_area_union:
Formerly, if one of the areas was empty, its coordinates were still
used in the min/max calculations.
Now, if one of the areas is empty, the result gets the other area's coords
In particular, taking the union of the empty area with coords (0,0,0,0)
with the non-empty area (x1,y1,x2,y2) would give the area (0,0,x2,y2)
before, and (x1,y1,x2,y2) after the change.
This is a first go at it, done by naive replacing of all array
operations with corresponding operations on the list. Note that
there is a lot of unnecessary type conversions, here. Also, list_pop
has been copied, because it's decalerd STATIC in py/objlist.h
Since we want to expose the list of group's children to the user,
we should only have the original objects in it, without any other
additional data, and compute the native object as needed.