fb: cfb: support inverting with coordinates that do not align with the tile
Improve `cfb_invert_area()` able to invert even at a coordinate not on tile boundaries. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
This commit is contained in:
parent
5634691d8c
commit
7068587505
1 changed files with 49 additions and 4 deletions
|
|
@ -229,6 +229,7 @@ int cfb_invert_area(const struct device *dev, uint16_t x, uint16_t y,
|
|||
uint16_t width, uint16_t height)
|
||||
{
|
||||
const struct char_framebuffer *fb = &char_fb;
|
||||
const bool need_reverse = ((fb->screen_info & SCREEN_INFO_MONO_MSB_FIRST) != 0);
|
||||
|
||||
if (x >= fb->x_res || y >= fb->y_res) {
|
||||
LOG_ERR("Coordinates outside of framebuffer");
|
||||
|
|
@ -236,7 +237,15 @@ int cfb_invert_area(const struct device *dev, uint16_t x, uint16_t y,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((fb->screen_info & SCREEN_INFO_MONO_VTILED) && !(y % 8)) {
|
||||
if ((fb->screen_info & SCREEN_INFO_MONO_VTILED)) {
|
||||
if (x > fb->x_res) {
|
||||
x = fb->x_res;
|
||||
}
|
||||
|
||||
if (y > fb->y_res) {
|
||||
y = fb->y_res;
|
||||
}
|
||||
|
||||
if (x + width > fb->x_res) {
|
||||
width = fb->x_res - x;
|
||||
}
|
||||
|
|
@ -246,10 +255,46 @@ int cfb_invert_area(const struct device *dev, uint16_t x, uint16_t y,
|
|||
}
|
||||
|
||||
for (size_t i = x; i < x + width; i++) {
|
||||
for (size_t j = y / 8U; j < (y + height) / 8U; j++) {
|
||||
size_t index = (j * fb->x_res) + i;
|
||||
for (size_t j = y; j < (y + height); j++) {
|
||||
/*
|
||||
* Process inversion in the y direction
|
||||
* by separating per 8-line boundaries.
|
||||
*/
|
||||
|
||||
const size_t index = ((j / 8) * fb->x_res) + i;
|
||||
const uint8_t remains = y + height - j;
|
||||
|
||||
/*
|
||||
* Make mask to prevent overwriting the drawing contents that on
|
||||
* between the start line or end line and the 8-line boundary.
|
||||
*/
|
||||
if ((j % 8) > 0) {
|
||||
uint8_t m = BIT_MASK((j % 8));
|
||||
uint8_t b = fb->buf[index];
|
||||
|
||||
if (need_reverse) {
|
||||
m = byte_reverse(m);
|
||||
b = byte_reverse(b);
|
||||
}
|
||||
|
||||
fb->buf[index] = ~(b | m) | (b & m);
|
||||
j += 7 - (j % 8);
|
||||
} else if (remains >= 8) {
|
||||
/* No mask required if no start or end line is included */
|
||||
fb->buf[index] = ~fb->buf[index];
|
||||
j += 7;
|
||||
} else {
|
||||
uint8_t m = BIT_MASK(remains % 8) << (8 - (remains % 8));
|
||||
uint8_t b = fb->buf[index];
|
||||
|
||||
if (need_reverse) {
|
||||
m = byte_reverse(m);
|
||||
b = byte_reverse(b);
|
||||
}
|
||||
|
||||
fb->buf[index] = ~(b | m) | (b & m);
|
||||
j += (remains - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue