forked from micropython/micropython
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed
Labels
Description
This was raised by user "cake" on the discord chat on 24 March 2021 at 1:43 pm central.
@WarriorOfWire your insights are appreciated on this one.
Firmware
Adafruit CircuitPython 6.2.0-beta.4-84-gc81007afb-dirty on 2021-03-24; Adafruit PyPortal with samd51j20
Code/REPL
import board
import displayio
import vectorio
import time
display = board.DISPLAY
rect_palette = displayio.Palette(color_count = 2)
rect_palette[0] = 0xffffff
rect_palette[1] = 0x00ff00
rect_palette.make_transparent(0)
HEIGHT = 40
WIDTH = 60
rectangle = vectorio.VectorShape(
shape = vectorio.Rectangle(WIDTH, HEIGHT),
pixel_shader = rect_palette,
x = 120,
y = 120
)
group = displayio.Group()
group.append(rectangle)
dx = 7
dy = 3
display.show(group)
count=0
while True:
rectangle.x -= dy
if rectangle.x < -WIDTH:
rectangle.x += 240+WIDTH
rectangle.y += dx
if rectangle.y > 240:
rectangle.y -= 240 + HEIGHT
if count < 1:
time.sleep(0.1)
else:
time.sleep(10000)
count +=1
Behavior
Leaves behind extra lines when the rectangle is moved.
Description
It looks like an off-by-one error in the dirty-rectangle tracking. The dirty rectangle tracking is "exclusive" so whatever dirty rectangle must be larger than the rectangle pixel dimensions by +1 in both x and y.
I hacked the vectorio _get_screen_area
and this solved the issue, but I'm unsure if it's the correct approach. The last two lines were added to expand the dirty rectangle.
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;
}
out_area->x2 = out_area->x2 + 1;
out_area->y2 = out_area->y2 + 1;
VECTORIO_SHAPE_DEBUG(" out:{(%5d,%5d), (%5d,%5d)}\n", out_area->x1, out_area->y1, out_area->x2, out_area->y2);
}