138 lines
3.8 KiB
C++
138 lines
3.8 KiB
C++
#include "uDisplay.h"
|
|
#include "uDisplay_config.h"
|
|
|
|
// ===== Basic Drawing Primitives =====
|
|
|
|
static constexpr uint16_t RGB16_TO_MONO = 0x8410;
|
|
static constexpr uint16_t RGB16_SWAP_TO_MONO = 0x1084;
|
|
|
|
void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
|
if (universal_panel->drawPixel(x, y, color)) {
|
|
return; // Handled by universal panel
|
|
}
|
|
|
|
if (framebuffer) {
|
|
Renderer::drawPixel(x, y, color);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void uDisplay::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
|
|
// Rudimentary clipping
|
|
if((x >= _width) || (y >= _height)) return;
|
|
if((x + w - 1) >= _width) w = _width - x;
|
|
|
|
if (universal_panel->drawFastHLine(x, y, w, color)) {
|
|
return;
|
|
}
|
|
|
|
if (framebuffer) {
|
|
Renderer::drawFastHLine(x, y, w, color);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
|
|
if (framebuffer) {
|
|
Renderer::drawFastVLine(x, y, h, color);
|
|
return;
|
|
}
|
|
|
|
// Rudimentary clipping
|
|
if ((x >= _width) || (y >= _height)) return;
|
|
if ((y + h - 1) >= _height) h = _height - y;
|
|
|
|
if (universal_panel->drawFastVLine(x, y, h, color)) {
|
|
return;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
|
|
if (universal_panel->fillRect(x, y, w, h, color)) {
|
|
return;
|
|
}
|
|
|
|
if (framebuffer) {
|
|
Renderer::fillRect(x, y, w, h, color);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void uDisplay::fillScreen(uint16_t color) {
|
|
fillRect(0, 0, width(), height(), color);
|
|
}
|
|
|
|
static inline void lvgl_color_swap(uint16_t *data, uint16_t len) { for (uint32_t i = 0; i < len; i++) (data[i] = data[i] << 8 | data[i] >> 8); }
|
|
|
|
void uDisplay::pushColors(uint16_t *data, uint16_t len, boolean not_swapped) { //not_swapped is always true in call form LVGL driver!!!!
|
|
|
|
if (lvgl_param.swap_color) {
|
|
not_swapped = !not_swapped;
|
|
}
|
|
universal_panel->pushColors(data, len, not_swapped);
|
|
}
|
|
|
|
// convert to mono, these are framebuffer based
|
|
void uDisplay::pushColorsMono(uint16_t *data, uint16_t len, bool rgb16_swap) {
|
|
// pixel is white if at least one of the 3 components is above 50%
|
|
// this is tested with a simple mask, swapped if needed
|
|
uint16_t rgb16_to_mono_mask = rgb16_swap ? RGB16_SWAP_TO_MONO : RGB16_TO_MONO;
|
|
|
|
for (uint32_t y = seta_yp1; y < seta_yp2; y++) {
|
|
seta_yp1++;
|
|
if (lvgl_param.invert_bw) {
|
|
for (uint32_t x = seta_xp1; x < seta_xp2; x++) {
|
|
uint16_t color = *data++;
|
|
if (bpp == 1) color = (color & rgb16_to_mono_mask) ? 0 : 1;
|
|
drawPixel(x, y, color); // todo - inline the method to save speed
|
|
len--;
|
|
if (!len) return; // failsafe - exist if len (pixel number) is exhausted
|
|
}
|
|
} else {
|
|
for (uint32_t x = seta_xp1; x < seta_xp2; x++) {
|
|
uint16_t color = *data++;
|
|
if (bpp == 1) color = (color & rgb16_to_mono_mask) ? 1 : 0;
|
|
drawPixel(x, y, color); // todo - inline the method to save speed
|
|
len--;
|
|
if (!len) return; // failsafe - exist if len (pixel number) is exhausted
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
|
universal_panel->setAddrWindow(x0, y0, x1, y1);
|
|
}
|
|
|
|
void uDisplay::setRotation(uint8_t rotation) {
|
|
cur_rot = rotation;
|
|
if (universal_panel->setRotation(rotation)) {
|
|
// Update Renderer dimensions based on rotation
|
|
switch (rotation) {
|
|
case 0:
|
|
case 2:
|
|
_width = gxs;
|
|
_height = gys;
|
|
break;
|
|
case 1:
|
|
case 3:
|
|
_width = gys;
|
|
_height = gxs;
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (framebuffer) {
|
|
Renderer::setRotation(cur_rot);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void uDisplay::Updateframe(void) {
|
|
universal_panel->updateFrame();
|
|
}
|