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 * - 16: RGB565
* - 32: ARGB8888 * - 32: ARGB8888
*/ */
#define LV_COLOR_DEPTH 32 #define LV_COLOR_DEPTH 16
/* Swap the 2 bytes of RGB565 color. /* Swap the 2 bytes of RGB565 color.
* Useful if the display has a 8 bit interface (e.g. SPI)*/ * 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::prelude::*;
use embedded_graphics_simulator::{ use embedded_graphics_simulator::{
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
}; };
use lvgl; use lvgl;
use lvgl::Object; use lvgl::Object;
use lvgl_sys; use lvgl_sys;
use std::sync::mpsc; use std::sync::mpsc;
use std::time::Duration; use std::time::Duration;
use embedded_graphics::pixelcolor::{Rgb565};
fn main() -> Result<(), String> { 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_HOR_RES_MAX,
lvgl_sys::LV_VER_RES_MAX, lvgl_sys::LV_VER_RES_MAX,
)); ));
let output_settings = OutputSettingsBuilder::new() let output_settings = OutputSettingsBuilder::new().scale(4).build();
.theme(BinaryColorTheme::OledBlue)
.build();
let mut window = Window::new("Hello World", &output_settings); let mut window = Window::new("Hello World", &output_settings);
unsafe { unsafe {

View file

@ -173,7 +173,7 @@ pub const WINT_MIN: u32 = 0;
pub const WINT_MAX: u32 = 4294967295; pub const WINT_MAX: u32 = 4294967295;
pub const LV_HOR_RES_MAX: u32 = 240; pub const LV_HOR_RES_MAX: u32 = 240;
pub const LV_VER_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_16_SWAP: u32 = 0;
pub const LV_COLOR_SCREEN_TRANSP: u32 = 0; pub const LV_COLOR_SCREEN_TRANSP: u32 = 0;
pub const LV_INDEXED_CHROMA: u32 = 1; 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_BEZIER_VAL_SHIFT: u32 = 10;
pub const LV_OPA_MIN: u32 = 16; pub const LV_OPA_MIN: u32 = 16;
pub const LV_OPA_MAX: u32 = 251; 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 _STRING_H: u32 = 1;
pub const _BITS_TYPES_LOCALE_T_H: u32 = 1; pub const _BITS_TYPES_LOCALE_T_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 __GNUC_VA_LIST: u32 = 1;
pub const LV_TXT_ENC_UTF8: u32 = 1; pub const LV_TXT_ENC_UTF8: u32 = 1;
pub const LV_TXT_ENC_ASCII: u32 = 2; 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_DRAW_LABEL_NO_TXT_SEL: u32 = 65535;
pub const LV_LABEL_DOT_NUM: u32 = 3; pub const LV_LABEL_DOT_NUM: u32 = 3;
pub const LV_LABEL_POS_LAST: u32 = 65535; pub const LV_LABEL_POS_LAST: u32 = 65535;
@ -1086,8 +1086,8 @@ pub struct lv_color32_t__bindgen_ty_1 {
pub red: u8, pub red: u8,
pub alpha: u8, pub alpha: u8,
} }
pub type lv_color_int_t = u32; pub type lv_color_int_t = u16;
pub type lv_color_t = lv_color32_t; pub type lv_color_t = lv_color16_t;
pub type lv_opa_t = u8; pub type lv_opa_t = u8;
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]

View file

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