Make it not tied to a color scheme

This commit is contained in:
Rafael Caricio 2020-05-27 22:37:22 +02:00
parent 0129442513
commit 63a160d54e
4 changed files with 59 additions and 28 deletions

View file

@ -18,7 +18,7 @@
* - 16: RGB565
* - 32: ARGB8888
*/
#define LV_COLOR_DEPTH 32
#define LV_COLOR_DEPTH 16
/* Swap the 2 bytes of RGB565 color.
* Useful if the display has a 8 bit interface (e.g. SPI)*/

View file

@ -1,22 +1,21 @@
use embedded_graphics::prelude::*;
use embedded_graphics_simulator::{
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
};
use lvgl;
use lvgl::Object;
use lvgl_sys;
use std::sync::mpsc;
use std::time::Duration;
use embedded_graphics::pixelcolor::{Rgb565};
fn main() -> Result<(), String> {
let mut display = SimulatorDisplay::new(Size::new(
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(
lvgl_sys::LV_HOR_RES_MAX,
lvgl_sys::LV_VER_RES_MAX,
));
let output_settings = OutputSettingsBuilder::new()
.theme(BinaryColorTheme::OledBlue)
.build();
let output_settings = OutputSettingsBuilder::new().scale(4).build();
let mut window = Window::new("Hello World", &output_settings);
unsafe {

View file

@ -173,7 +173,7 @@ pub const WINT_MIN: u32 = 0;
pub const WINT_MAX: u32 = 4294967295;
pub const LV_HOR_RES_MAX: u32 = 240;
pub const LV_VER_RES_MAX: u32 = 240;
pub const LV_COLOR_DEPTH: u32 = 32;
pub const LV_COLOR_DEPTH: u32 = 16;
pub const LV_COLOR_16_SWAP: u32 = 0;
pub const LV_COLOR_SCREEN_TRANSP: u32 = 0;
pub const LV_INDEXED_CHROMA: u32 = 1;
@ -294,7 +294,7 @@ pub const LV_BEZIER_VAL_MAX: u32 = 1024;
pub const LV_BEZIER_VAL_SHIFT: u32 = 10;
pub const LV_OPA_MIN: u32 = 16;
pub const LV_OPA_MAX: u32 = 251;
pub const LV_COLOR_SIZE: u32 = 32;
pub const LV_COLOR_SIZE: u32 = 16;
pub const _STRING_H: u32 = 1;
pub const _BITS_TYPES_LOCALE_T_H: u32 = 1;
pub const _BITS_TYPES___LOCALE_T_H: u32 = 1;
@ -371,7 +371,7 @@ pub const LV_EXT_CLICK_AREA_FULL: u32 = 2;
pub const __GNUC_VA_LIST: u32 = 1;
pub const LV_TXT_ENC_UTF8: u32 = 1;
pub const LV_TXT_ENC_ASCII: u32 = 2;
pub const LV_IMG_PX_SIZE_ALPHA_BYTE: u32 = 4;
pub const LV_IMG_PX_SIZE_ALPHA_BYTE: u32 = 3;
pub const LV_DRAW_LABEL_NO_TXT_SEL: u32 = 65535;
pub const LV_LABEL_DOT_NUM: u32 = 3;
pub const LV_LABEL_POS_LAST: u32 = 65535;
@ -1086,8 +1086,8 @@ pub struct lv_color32_t__bindgen_ty_1 {
pub red: u8,
pub alpha: u8,
}
pub type lv_color_int_t = u32;
pub type lv_color_t = lv_color32_t;
pub type lv_color_int_t = u16;
pub type lv_color_t = lv_color16_t;
pub type lv_opa_t = u8;
#[repr(C)]
#[derive(Debug, Copy, Clone)]

View file

@ -3,24 +3,27 @@ use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::ptr;
use embedded_graphics;
use embedded_graphics::pixelcolor::raw::RawU16;
use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::pixelcolor::{Rgb565, Rgb888};
use embedded_graphics::prelude::*;
use embedded_graphics::{drawable, DrawTarget};
use lvgl_sys::lv_color_t;
pub struct DisplayDriver<'a, T>
pub struct DisplayDriver<'a, T, C>
where
T: DrawTarget<Rgb565>,
T: DrawTarget<C>,
C: PixelColor + From<ColorRgb>
{
raw: lvgl_sys::lv_disp_drv_t,
display_buffer: MaybeUninit<lvgl_sys::lv_disp_buf_t>,
refresh_buffer: [MaybeUninit<lvgl_sys::lv_color_t>; lvgl_sys::LV_HOR_RES_MAX as usize * 10],
phantom: &'a PhantomData<T>,
phantom2: PhantomData<C>,
}
impl<'a, T> DisplayDriver<'a, T>
impl<'a, T, C> DisplayDriver<'a, T, C>
where
T: DrawTarget<Rgb565>,
T: DrawTarget<C>,
C: PixelColor + From<ColorRgb>
{
pub fn new(device: &'a mut T) -> Self {
// Create a display buffer for LittlevGL
@ -44,7 +47,7 @@ where
// Basic initialization
lvgl_sys::lv_disp_drv_init(&mut disp_drv);
// Set your driver function
disp_drv.flush_cb = Some(display_callback_wrapper::<T>);
disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>);
disp_drv.user_data = device as *mut _ as *mut cty::c_void;
disp_drv
};
@ -59,6 +62,7 @@ where
display_buffer,
refresh_buffer,
phantom: &PhantomData,
phantom2: PhantomData,
}
}
@ -67,12 +71,43 @@ where
}
}
unsafe extern "C" fn display_callback_wrapper<T>(
pub struct ColorRgb(lv_color_t);
impl From<ColorRgb> for Rgb888 {
fn from(color: ColorRgb) -> Self {
// Convert Lvgl to embedded-graphics color
let raw_color = color.0;
unsafe {
Rgb888::new(
lvgl_sys::_LV_COLOR_GET_R(raw_color) as u8,
lvgl_sys::_LV_COLOR_GET_G(raw_color) as u8,
lvgl_sys::_LV_COLOR_GET_B(raw_color) as u8,
)
}
}
}
impl From<ColorRgb> for Rgb565 {
fn from(color: ColorRgb) -> Self {
// Convert Lvgl to embedded-graphics color
let raw_color = color.0;
unsafe {
Rgb565::new(
lvgl_sys::_LV_COLOR_GET_R(raw_color) as u8,
lvgl_sys::_LV_COLOR_GET_G(raw_color) as u8,
lvgl_sys::_LV_COLOR_GET_B(raw_color) as u8,
)
}
}
}
unsafe extern "C" fn display_callback_wrapper<T, C>(
disp_drv: *mut lvgl_sys::lv_disp_drv_t,
area: *const lvgl_sys::lv_area_t,
color_p: *mut lvgl_sys::lv_color_t,
) where
T: DrawTarget<Rgb565>,
T: DrawTarget<C>,
C: PixelColor + From<ColorRgb>
{
// We need to make sure panics can't escape across the FFI boundary.
//let _ = std::panic::catch_unwind(|| {
@ -82,17 +117,14 @@ unsafe extern "C" fn display_callback_wrapper<T>(
// Rust code closure reference
let device = &mut *(display_driver.user_data as *mut T);
// TODO: create a fixed image buffer iterator somehow, maybe a fixed size array
//let image_buffer =
for y in (*area).y1..=(*area).y2 {
for x in (*area).x1..=(*area).x2 {
let raw_color = *color_p.add(i);
let raw_color = ColorRgb(*color_p.add(i));
i = i + 1;
// Convert Lvgl to embedded-graphics color
let color = Rgb565::new(
lvgl_sys::_LV_COLOR_GET_R(raw_color) as u8,
lvgl_sys::_LV_COLOR_GET_G(raw_color) as u8,
lvgl_sys::_LV_COLOR_GET_B(raw_color) as u8,
);
let _ = device.draw_pixel(drawable::Pixel(Point::new(x as i32, y as i32), color));
// TODO: Use device.draw_iter
let _ = device.draw_pixel(drawable::Pixel(Point::new(x as i32, y as i32), raw_color.into()));
}
}