vectorio: palettes don't color dirty rectangles
This is a breaking change with previous palette semantic with respect to python code that uses vectorio. Displayio has breaking changes in cpy 7 for Group's removal of max_size parameter so this is as good a time as any to break everything. Currently: To color vectorio shapes correctly you have to pass in a palette with length 2. Palette[0] must be set transparent and palette[1] must be the color you want. New: To color vectorio shapes correctly you pass in a palette with length >= 1. Palette[0] will be the color of the shape. Also improves pixels per second when skipping areas that aren't covered by the shape.
This commit is contained in:
parent
98cd989c16
commit
0afd863224
@ -21,7 +21,7 @@
|
||||
|
||||
//| class VectorShape:
|
||||
//| def __init__(self, shape: Union[Polygon, Rectangle, Circle], pixel_shader: Union[displayio.ColorConverter, displayio.Palette], x: int=0, y: int=0) -> None:
|
||||
//| """Binds a vector shape to a location and pixel color
|
||||
//| """Binds a vector shape to a location and pixel shader. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0.
|
||||
//|
|
||||
//| :param shape: The shape to draw.
|
||||
//| :param pixel_shader: The pixel shader that produces colors from values
|
||||
|
@ -214,18 +214,30 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ
|
||||
#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 shapes use 0 to mean "area is not covered."
|
||||
// We can skip all the rest of the work for this pixel if it's not currently covered by the shape.
|
||||
if (input_pixel.pixel == 0) {
|
||||
VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)\n");
|
||||
full_coverage = false;
|
||||
} else {
|
||||
// Pixel is not transparent. Let's pull the pixel value index down to 0-base for more error-resistant palettes.
|
||||
input_pixel.pixel -= 1;
|
||||
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);
|
||||
}
|
||||
|
||||
// We double-check this to fast-path the case when a pixel is not covered by the shape & not call the color converter unnecessarily.
|
||||
if (output_pixel.opaque) {
|
||||
VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)\n");
|
||||
full_coverage = false;
|
||||
}
|
||||
|
||||
*mask_doubleword |= 1u << mask_bit;
|
||||
if (colorspace->depth == 16) {
|
||||
VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16\n", output_pixel.pixel);
|
||||
|
Loading…
Reference in New Issue
Block a user