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)
|
uint16_t width, uint16_t height)
|
||||||
{
|
{
|
||||||
const struct char_framebuffer *fb = &char_fb;
|
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) {
|
if (x >= fb->x_res || y >= fb->y_res) {
|
||||||
LOG_ERR("Coordinates outside of framebuffer");
|
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;
|
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) {
|
if (x + width > fb->x_res) {
|
||||||
width = fb->x_res - x;
|
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 i = x; i < x + width; i++) {
|
||||||
for (size_t j = y / 8U; j < (y + height) / 8U; j++) {
|
for (size_t j = y; j < (y + height); j++) {
|
||||||
size_t index = (j * fb->x_res) + i;
|
/*
|
||||||
|
* Process inversion in the y direction
|
||||||
|
* by separating per 8-line boundaries.
|
||||||
|
*/
|
||||||
|
|
||||||
fb->buf[index] = ~fb->buf[index];
|
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