Skip to content

Vectorio Rectangle leaves behind graphical debris when moved #4478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kmatch98 opened this issue Mar 24, 2021 · 1 comment · Fixed by #4484
Closed

Vectorio Rectangle leaves behind graphical debris when moved #4478

kmatch98 opened this issue Mar 24, 2021 · 1 comment · Fixed by #4484
Labels

Comments

@kmatch98
Copy link

kmatch98 commented Mar 24, 2021

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);
}
@kmatch98 kmatch98 added the bug label Mar 24, 2021
@kvc0
Copy link

kvc0 commented Mar 25, 2021

Can you enable the VECTORIO_SHAPE_DEBUG macro and see if the rectangle shape is just computing the wrong width? It may be an issue with a transform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants