diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index 85d906b27e..71955710c2 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -342,23 +342,10 @@ fn generate_trezorhal_bindings() { .allowlist_function("translations_erase") .allowlist_function("translations_area_bytesize") // display - .allowlist_function("display_clear") - .allowlist_function("display_offset") .allowlist_function("display_refresh") - .allowlist_function("display_backlight") - .allowlist_function("display_text") - .allowlist_function("display_text_render_buffer") - .allowlist_function("display_pixeldata") - .allowlist_function("display_pixeldata_dirty") - .allowlist_function("display_set_window") - .allowlist_function("display_sync") - .allowlist_function("display_get_fb_addr") - .allowlist_function("display_get_wr_addr") - .allowlist_var("DISPLAY_DATA_ADDRESS") - .allowlist_var("DISPLAY_FRAMEBUFFER_WIDTH") - .allowlist_var("DISPLAY_FRAMEBUFFER_HEIGHT") - .allowlist_var("DISPLAY_FRAMEBUFFER_OFFSET_X") - .allowlist_var("DISPLAY_FRAMEBUFFER_OFFSET_Y") + .allowlist_function("display_set_backlight") + .allowlist_function("display_get_backlight") + .allowlist_function("display_wait_for_sync") .allowlist_var("DISPLAY_RESX") .allowlist_var("DISPLAY_RESY") .allowlist_type("display_fb_info_t") diff --git a/core/embed/rust/src/trezorhal/bitblt.rs b/core/embed/rust/src/trezorhal/bitblt.rs index dea82a0ea6..c2b0414922 100644 --- a/core/embed/rust/src/trezorhal/bitblt.rs +++ b/core/embed/rust/src/trezorhal/bitblt.rs @@ -205,7 +205,6 @@ impl BitBltFill { } /// Fills a rectangle on the display with the specified color. - #[cfg(feature = "new_rendering")] pub fn display_fill(&self) { assert!(self.bitblt.dst_x + self.bitblt.width <= ffi::DISPLAY_RESX as u16); assert!(self.bitblt.dst_y + self.bitblt.height <= ffi::DISPLAY_RESY as u16); @@ -426,7 +425,6 @@ impl<'a> BitBltCopy<'a> { /// Copies a part of the source bitmap to the display. /// /// - The source bitmap uses the RGB565 format. - #[cfg(feature = "new_rendering")] pub fn display_copy(&self) { assert!(self.bitblt.dst_x + self.bitblt.width <= ffi::DISPLAY_RESX as u16); assert!(self.bitblt.dst_y + self.bitblt.height <= ffi::DISPLAY_RESY as u16); diff --git a/core/embed/rust/src/trezorhal/buffers.rs b/core/embed/rust/src/trezorhal/buffers.rs deleted file mode 100644 index 7ae36c2702..0000000000 --- a/core/embed/rust/src/trezorhal/buffers.rs +++ /dev/null @@ -1,101 +0,0 @@ -use core::{ - ops::{Deref, DerefMut}, - ptr, -}; - -use super::ffi; - -pub use ffi::TEXT_BUFFER_HEIGHT; - -macro_rules! buffer_wrapper { - ($rust_name: ident, $type: ident, $get: ident, $free: ident) => { - pub struct $rust_name(ptr::NonNull); - - impl $rust_name { - pub fn get() -> Self { - unsafe { - let ptr = ffi::$get(false); - Self(unwrap!(ptr::NonNull::new(ptr))) - } - } - - pub fn get_cleared() -> Self { - unsafe { - let ptr = ffi::$get(true); - Self(unwrap!(ptr::NonNull::new(ptr))) - } - } - } - - impl Deref for $rust_name { - type Target = ffi::$type; - - fn deref(&self) -> &Self::Target { - // SAFETY: The lifetime of the pointer is 'static and the C API - // promises that we are the sole owner. - unsafe { self.0.as_ref() } - } - } - - impl DerefMut for $rust_name { - fn deref_mut(&mut self) -> &mut Self::Target { - // SAFETY: The lifetime of the pointer is 'static and the C API - // promises that we are the sole owner, and we have borrowed mutably. - unsafe { self.0.as_mut() } - } - } - - impl Drop for $rust_name { - fn drop(&mut self) { - unsafe { - ffi::$free(self.0.as_mut()); - } - } - } - }; -} - -buffer_wrapper!( - BufferLine16bpp, - buffer_line_16bpp_t, - buffers_get_line_16bpp, - buffers_free_line_16bpp -); -buffer_wrapper!( - BufferLine4bpp, - buffer_line_4bpp_t, - buffers_get_line_4bpp, - buffers_free_line_4bpp -); -buffer_wrapper!( - BufferText, - buffer_text_t, - buffers_get_text, - buffers_free_text -); -buffer_wrapper!( - BufferBlurring, - buffer_blurring_t, - buffers_get_blurring, - buffers_free_blurring -); -buffer_wrapper!( - BufferBlurringTotals, - buffer_blurring_totals_t, - buffers_get_blurring_totals, - buffers_free_blurring_totals -); -#[cfg(feature = "jpeg")] -buffer_wrapper!( - BufferJpeg, - buffer_jpeg_t, - buffers_get_jpeg, - buffers_free_jpeg -); -#[cfg(feature = "jpeg")] -buffer_wrapper!( - BufferJpegWork, - buffer_jpeg_work_t, - buffers_get_jpeg_work, - buffers_free_jpeg_work -); diff --git a/core/embed/rust/src/trezorhal/display.rs b/core/embed/rust/src/trezorhal/display.rs index a798b3de12..be2220d445 100644 --- a/core/embed/rust/src/trezorhal/display.rs +++ b/core/embed/rust/src/trezorhal/display.rs @@ -1,52 +1,12 @@ use super::ffi; -use core::{ops::DerefMut, ptr}; -use cty::c_int; -use crate::trezorhal::buffers::BufferText; +#[cfg(feature = "xframebuffer")] +use core::ptr; pub use ffi::{DISPLAY_RESX, DISPLAY_RESY}; -#[cfg(feature = "framebuffer")] -pub use ffi::{ - DISPLAY_FRAMEBUFFER_OFFSET_X, DISPLAY_FRAMEBUFFER_OFFSET_Y, DISPLAY_FRAMEBUFFER_WIDTH, -}; - -#[cfg(all(feature = "framebuffer", not(feature = "framebuffer32bit")))] -#[derive(Copy, Clone)] -pub struct FrameBuffer(pub *mut u16); - -#[cfg(all(feature = "framebuffer", feature = "framebuffer32bit"))] -#[derive(Copy, Clone)] -pub struct FrameBuffer(pub *mut u32); - pub fn backlight(val: i32) -> i32 { - unsafe { ffi::display_backlight(val) } -} - -pub fn text(baseline_x: i16, baseline_y: i16, text: &str, font: i32, fgcolor: u16, bgcolor: u16) { - unsafe { - ffi::display_text( - baseline_x.into(), - baseline_y.into(), - text.as_ptr() as _, - text.len() as _, - font, - fgcolor, - bgcolor, - ) - } -} - -pub fn text_into_buffer(text: &str, font: i32, buffer: &mut BufferText, x_offset: i16) { - unsafe { - ffi::display_text_render_buffer( - text.as_ptr() as _, - text.len() as _, - font, - buffer.deref_mut(), - x_offset.into(), - ) - } + unsafe { ffi::display_set_backlight(val) } } pub fn text_width(text: &str, font: i32) -> i16 { @@ -79,95 +39,10 @@ pub fn text_baseline(font: i32) -> i16 { unsafe { ffi::font_baseline(font).try_into().unwrap_or(i16::MAX) } } -#[inline(always)] -#[cfg(all( - not(feature = "framebuffer"), - feature = "disp_i8080_16bit_dw", - not(feature = "disp_i8080_8bit_dw") -))] -#[allow(unused_variables)] -pub fn pixeldata(c: u16) { - #[cfg(not(feature = "new_rendering"))] - unsafe { - ffi::DISPLAY_DATA_ADDRESS.write_volatile(c); - } -} - -#[cfg(feature = "framebuffer")] -pub fn get_fb_addr() -> FrameBuffer { - unsafe { FrameBuffer(ffi::display_get_fb_addr() as _) } -} - -#[inline(always)] -#[cfg(all(not(feature = "framebuffer"), feature = "disp_i8080_8bit_dw"))] -#[allow(unused_variables)] -pub fn pixeldata(c: u16) { - #[cfg(not(feature = "new_rendering"))] - unsafe { - ffi::DISPLAY_DATA_ADDRESS.write_volatile((c & 0xff) as u8); - ffi::DISPLAY_DATA_ADDRESS.write_volatile((c >> 8) as u8); - } -} - -#[inline(always)] -#[cfg(all(feature = "framebuffer", not(feature = "framebuffer32bit")))] -pub fn pixel(fb: FrameBuffer, x: i16, y: i16, c: u16) { - unsafe { - let addr = fb.0.offset( - ((y as u32 + DISPLAY_FRAMEBUFFER_OFFSET_Y) * DISPLAY_FRAMEBUFFER_WIDTH - + (x as u32 + DISPLAY_FRAMEBUFFER_OFFSET_X)) as isize, - ); - addr.write_volatile(c); - } -} - -#[inline(always)] -#[cfg(all(feature = "framebuffer", feature = "framebuffer32bit"))] -pub fn pixel(fb: FrameBuffer, x: i16, y: i16, c: u32) { - unsafe { - let addr = fb.0.offset( - ((y as u32 + DISPLAY_FRAMEBUFFER_OFFSET_Y) * DISPLAY_FRAMEBUFFER_WIDTH - + (x as u32 + DISPLAY_FRAMEBUFFER_OFFSET_X)) as isize, - ); - addr.write_volatile(c); - } -} - -#[inline(always)] -#[cfg(any( - feature = "framebuffer", - not(any(feature = "disp_i8080_16bit_dw", feature = "disp_i8080_8bit_dw")) -))] -pub fn pixeldata(c: u16) { - unsafe { - ffi::display_pixeldata(c); - } -} - -pub fn pixeldata_dirty() { - unsafe { - ffi::display_pixeldata_dirty(); - } -} - -pub fn set_window(x0: u16, y0: u16, x1: u16, y1: u16) { - unsafe { - ffi::display_set_window(x0, y0, x1, y1); - } -} - -pub fn get_offset() -> (i16, i16) { - unsafe { - let mut x: c_int = 0; - let mut y: c_int = 0; - ffi::display_offset(ptr::null_mut(), &mut x, &mut y); - (x as i16, y as i16) - } -} - pub fn sync() { + #[cfg(not(feature = "framebuffer"))] unsafe { - ffi::display_sync(); + ffi::display_wait_for_sync(); } } @@ -177,12 +52,6 @@ pub fn refresh() { } } -pub fn clear() { - unsafe { - ffi::display_clear(); - } -} - #[cfg(feature = "xframebuffer")] pub fn get_frame_buffer() -> (&'static mut [u8], usize) { let mut fb_info = ffi::display_fb_info_t { diff --git a/core/embed/rust/src/trezorhal/dma2d.rs b/core/embed/rust/src/trezorhal/dma2d.rs deleted file mode 100644 index e219ca61f1..0000000000 --- a/core/embed/rust/src/trezorhal/dma2d.rs +++ /dev/null @@ -1,103 +0,0 @@ -use super::ffi; - -#[allow(dead_code)] - -pub fn dma2d_setup_const() { - unsafe { ffi::dma2d_setup_const() } -} -pub fn dma2d_setup_4bpp(fg_color: u16, bg_color: u16) { - unsafe { ffi::dma2d_setup_4bpp(fg_color, bg_color) } -} - -pub fn dma2d_setup_16bpp() { - unsafe { ffi::dma2d_setup_16bpp() } -} - -pub fn dma2d_setup_4bpp_over_4bpp(fg_color: u16, bg_color: u16, overlay_color: u16) { - unsafe { ffi::dma2d_setup_4bpp_over_4bpp(fg_color, bg_color, overlay_color) } -} - -pub fn dma2d_setup_4bpp_over_16bpp(overlay_color: u16) { - unsafe { ffi::dma2d_setup_4bpp_over_16bpp(overlay_color) } -} - -/// Starts dma2d transfer -/// -/// # Safety -/// -/// This function is unsafe because the caller has to guarantee that he: -/// 1) doesn't mutate the buffers until the transfer is finished, which is -/// guaranteed by calling `dma2d_wait_for_transfer` -/// 2) the buffer doesn't get dropped until the transfer is finished -/// 3) doesn't call this function while another transfer is running -pub unsafe fn dma2d_start(buffer: &[u8], pixels: i16) { - unsafe { - ffi::dma2d_start( - buffer.as_ptr() as _, - ffi::display_get_wr_addr() as _, - pixels as _, - ); - } -} - -/// Starts blending -/// -/// # Safety -/// -/// This function is unsafe because the caller has to guarantee that he: -/// 1) doesn't mutate the buffers until the transfer is finished, which is -/// guaranteed by calling `dma2d_wait_for_transfer` -/// 2) the buffer doesn't get dropped until the transfer is finished -/// 3) doesn't call this function while another transfer is running -pub unsafe fn dma2d_start_blend(overlay_buffer: &[u8], bg_buffer: &[u8], pixels: i16) { - unsafe { - ffi::dma2d_start_blend( - overlay_buffer.as_ptr() as _, - bg_buffer.as_ptr() as _, - ffi::display_get_wr_addr() as _, - pixels as _, - ); - } -} - -/// Starts blending -/// -/// # Safety -/// -/// This function is unsafe because the caller has to guarantee that he: -/// 1) doesn't mutate the buffers until the transfer is finished, which is -/// guaranteed by calling `dma2d_wait_for_transfer` -/// 2) the buffer doesn't get dropped until the transfer is finished -/// 3) doesn't call this function while another transfer is running -pub unsafe fn dma2d_start_const(color: u16, pixels: i16) { - unsafe { - ffi::dma2d_start_const(color, ffi::display_get_wr_addr() as _, pixels as _); - } -} - -#[cfg(feature = "framebuffer")] -/// Starts blending -/// -/// # Safety -/// -/// This function is unsafe because the caller has to guarantee that he: -/// 1) doesn't mutate the buffers until the transfer is finished, which is -/// guaranteed by calling `dma2d_wait_for_transfer` -/// 2) the buffer doesn't get dropped until the transfer is finished -/// 3) doesn't call this function while another transfer is running -pub unsafe fn dma2d_start_const_multiline(color: u16, width: i16, height: i16) { - unsafe { - ffi::dma2d_start_const_multiline( - color, - ffi::display_get_wr_addr() as _, - width as _, - height as _, - ); - } -} - -pub fn dma2d_wait_for_transfer() { - unsafe { - ffi::dma2d_wait_for_transfer(); - } -} diff --git a/core/embed/rust/src/trezorhal/mod.rs b/core/embed/rust/src/trezorhal/mod.rs index bab3c62660..228b276e13 100644 --- a/core/embed/rust/src/trezorhal/mod.rs +++ b/core/embed/rust/src/trezorhal/mod.rs @@ -6,8 +6,6 @@ pub mod fatal_error; pub mod bitblt; #[cfg(feature = "ui")] pub mod display; -#[cfg(feature = "dma2d")] -pub mod dma2d; mod ffi; #[cfg(feature = "haptic")] pub mod haptic; @@ -25,7 +23,6 @@ pub mod usb; pub mod uzlib; pub mod wordlist; -pub mod buffers; pub mod secbool; #[cfg(not(feature = "micropython"))] diff --git a/core/embed/rust/src/ui/api/bootloader_c.rs b/core/embed/rust/src/ui/api/bootloader_c.rs index 30bb2524b5..9783f9c427 100644 --- a/core/embed/rust/src/ui/api/bootloader_c.rs +++ b/core/embed/rust/src/ui/api/bootloader_c.rs @@ -12,12 +12,6 @@ extern "C" fn screen_welcome() { ModelUI::screen_welcome(); } -#[no_mangle] -#[cfg(not(feature = "new_rendering"))] -extern "C" fn bld_continue_label(bg_color: cty::uint16_t) { - ModelUI::bld_continue_label(bg_color.into()); -} - #[no_mangle] extern "C" fn screen_install_success( restart_seconds: u8, @@ -105,7 +99,6 @@ extern "C" fn screen_boot_stage_1(fading: bool) { } #[no_mangle] -#[cfg(feature = "new_rendering")] extern "C" fn screen_boot( warning: bool, vendor_str: *const cty::c_char, diff --git a/core/embed/rust/src/ui/api/common_c.rs b/core/embed/rust/src/ui/api/common_c.rs index 7eafbef5aa..1050e1b45b 100644 --- a/core/embed/rust/src/ui/api/common_c.rs +++ b/core/embed/rust/src/ui/api/common_c.rs @@ -3,14 +3,6 @@ use crate::ui::ui_features::{ModelUI, UIFeaturesCommon}; -#[cfg(not(feature = "new_rendering"))] -use crate::ui::{ - component::image::Image, - display::{Color, Icon}, - geometry::{Alignment2D, Point}, -}; - -#[cfg(feature = "new_rendering")] use crate::ui::shape; use crate::ui::util::from_c_str; @@ -30,10 +22,7 @@ extern "C" fn display_rsod_rust( // to allow nested calls to `run_with_bumps`/`render_on_display`, // because after the error message is displayed, the application will // shut down. - #[cfg(feature = "new_rendering")] - unsafe { - shape::unlock_bumps_on_failure() - }; + unsafe { shape::unlock_bumps_on_failure() }; ModelUI::screen_fatal_error(title, msg, footer); ModelUI::backlight_on(); @@ -43,36 +32,3 @@ extern "C" fn display_rsod_rust( extern "C" fn screen_boot_stage_2() { ModelUI::screen_boot_stage_2(); } - -#[no_mangle] -#[cfg(not(feature = "new_rendering"))] -extern "C" fn display_icon( - x: cty::int16_t, - y: cty::int16_t, - data: *const cty::uint8_t, - data_len: cty::uint32_t, - fg_color: cty::uint16_t, - bg_color: cty::uint16_t, -) { - let data_slice = unsafe { core::slice::from_raw_parts(data, data_len as usize) }; - let icon = Icon::new(data_slice); - icon.draw( - Point::new(x, y), - Alignment2D::TOP_LEFT, - Color::from_u16(fg_color), - Color::from_u16(bg_color), - ); -} - -#[no_mangle] -#[cfg(not(feature = "new_rendering"))] -extern "C" fn display_image( - x: cty::int16_t, - y: cty::int16_t, - data: *const cty::uint8_t, - data_len: cty::uint32_t, -) { - let data_slice = unsafe { core::slice::from_raw_parts(data, data_len as usize) }; - let image = Image::new(data_slice); - image.draw(Point::new(x, y), Alignment2D::TOP_LEFT); -} diff --git a/core/embed/rust/src/ui/component/bar.rs b/core/embed/rust/src/ui/component/bar.rs index 2ac5556cfb..36afe16d1b 100644 --- a/core/embed/rust/src/ui/component/bar.rs +++ b/core/embed/rust/src/ui/component/bar.rs @@ -1,6 +1,5 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never}, - display, display::Color, geometry::Rect, shape, @@ -37,10 +36,6 @@ impl Component for Bar { None } - fn paint(&mut self) { - display::rect_fill_rounded(self.area, self.color, self.bg_color, self.radius as u8); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::Bar::new(self.area) .with_bg(self.color) diff --git a/core/embed/rust/src/ui/component/base.rs b/core/embed/rust/src/ui/component/base.rs index 10faf12e5d..2cb1acdf03 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -5,8 +5,7 @@ use crate::{ time::Duration, ui::{ button_request::{ButtonRequest, ButtonRequestCode}, - component::{maybe::PaintOverlapping, MsgMap, PageMap}, - display::Color, + component::{MsgMap, PageMap}, geometry::{Offset, Rect}, shape::Renderer, }, @@ -60,11 +59,6 @@ pub trait Component { fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option; /// Render to screen, based on current internal state. - /// - /// To prevent unnecessary over-draw, dirty state checking is performed in - /// the `Child` wrapper. - fn paint(&mut self); - fn render<'s>(&'s self, _target: &mut impl Renderer<'s>); } @@ -150,13 +144,6 @@ where }) } - fn paint(&mut self) { - if self.marked_for_paint { - self.marked_for_paint = false; - self.component.paint(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.component.render(target); } @@ -172,22 +159,6 @@ impl Paginate for Child { } } -impl PaintOverlapping for Child -where - T: PaintOverlapping, -{ - fn cleared_area(&self) -> Option<(Rect, Color)> { - self.component.cleared_area() - } - - fn paint_overlapping(&mut self) { - if self.marked_for_paint { - self.marked_for_paint = false; - self.component.paint_overlapping() - } - } -} - #[cfg(feature = "ui_debug")] impl crate::trace::Trace for Child where @@ -215,11 +186,6 @@ where .or_else(|| self.1.event(ctx, event)) } - fn paint(&mut self) { - self.0.paint(); - self.1.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.0.render(target); self.1.render(target); @@ -262,12 +228,6 @@ where .or_else(|| self.2.event(ctx, event)) } - fn paint(&mut self) { - self.0.paint(); - self.1.paint(); - self.2.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.0.render(target); self.1.render(target); @@ -288,12 +248,6 @@ where } } - fn paint(&mut self) { - if let Some(ref mut c) = self { - c.paint() - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if let Some(ref c) = self { c.render(target) diff --git a/core/embed/rust/src/ui/component/border.rs b/core/embed/rust/src/ui/component/border.rs index a8b93ecd84..9882a5b594 100644 --- a/core/embed/rust/src/ui/component/border.rs +++ b/core/embed/rust/src/ui/component/border.rs @@ -38,10 +38,6 @@ where self.inner.event(ctx, event) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target); } diff --git a/core/embed/rust/src/ui/component/button_request.rs b/core/embed/rust/src/ui/component/button_request.rs index 529f2b3e0f..75e3314227 100644 --- a/core/embed/rust/src/ui/component/button_request.rs +++ b/core/embed/rust/src/ui/component/button_request.rs @@ -4,7 +4,7 @@ use crate::ui::{ geometry::Rect, }; -#[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] +#[cfg(all(feature = "micropython", feature = "touch"))] use crate::ui::component::swipe_detect::SwipeConfig; /// Component that sends a ButtonRequest after receiving Event::Attach. The @@ -62,16 +62,12 @@ impl Component for SendButtonRequest { self.inner.event(ctx, event) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl crate::ui::shape::Renderer<'s>) { self.inner.render(target) } } -#[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] +#[cfg(all(feature = "micropython", feature = "touch"))] impl crate::ui::flow::Swipable for SendButtonRequest { fn get_swipe_config(&self) -> SwipeConfig { self.inner.get_swipe_config() diff --git a/core/embed/rust/src/ui/component/cached_jpeg.rs b/core/embed/rust/src/ui/component/cached_jpeg.rs index 600c02f8cf..53f38357b9 100644 --- a/core/embed/rust/src/ui/component/cached_jpeg.rs +++ b/core/embed/rust/src/ui/component/cached_jpeg.rs @@ -58,8 +58,6 @@ impl Component for CachedJpeg { None } - fn paint(&mut self) {} - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let off = Offset::new( self.image_size.x / (2 << self.scale), diff --git a/core/embed/rust/src/ui/component/connect.rs b/core/embed/rust/src/ui/component/connect.rs index 3d7897bdf0..e085b928b6 100644 --- a/core/embed/rust/src/ui/component/connect.rs +++ b/core/embed/rust/src/ui/component/connect.rs @@ -2,7 +2,7 @@ use crate::{ strutil::TString, ui::{ component::{Component, Event, EventCtx, Never, Pad}, - display::{self, Color, Font}, + display::{Color, Font}, geometry::{Alignment, Offset, Rect}, shape::{self, Renderer}, }, @@ -42,21 +42,6 @@ impl Component for Connect { None } - fn paint(&mut self) { - let font = Font::NORMAL; - - self.bg.paint(); - self.message.map(|t| { - display::text_center( - self.bg.area.center() + Offset::y(font.text_height() / 2), - t, - font, - self.fg, - self.bg.color, - ) - }); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let font = Font::NORMAL; diff --git a/core/embed/rust/src/ui/component/empty.rs b/core/embed/rust/src/ui/component/empty.rs index cce48b0cec..8c559a3bef 100644 --- a/core/embed/rust/src/ui/component/empty.rs +++ b/core/embed/rust/src/ui/component/empty.rs @@ -15,8 +15,6 @@ impl Component for Empty { None } - fn paint(&mut self) {} - fn render<'s>(&'s self, _target: &mut impl Renderer<'s>) {} } diff --git a/core/embed/rust/src/ui/component/image.rs b/core/embed/rust/src/ui/component/image.rs index b51a54f63f..9d38b9cc4b 100644 --- a/core/embed/rust/src/ui/component/image.rs +++ b/core/embed/rust/src/ui/component/image.rs @@ -1,8 +1,7 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never}, - display, display::{ - toif::{image, Toif, ToifFormat}, + toif::{Toif, ToifFormat}, Color, Icon, }, geometry::{Alignment2D, Offset, Point, Rect}, @@ -25,13 +24,6 @@ impl Image { area: Rect::zero(), } } - - /// Display the icon with baseline Point, aligned according to the - /// `alignment` argument. - pub fn draw(&self, baseline: Point, alignment: Alignment2D) { - let r = Rect::snap(baseline, self.toif.size(), alignment); - image(self, r.center()); - } } impl Component for Image { @@ -46,10 +38,6 @@ impl Component for Image { None } - fn paint(&mut self) { - self.draw(self.area.center(), Alignment2D::CENTER); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::ToifImage::new(self.area.center(), self.toif) .with_align(Alignment2D::CENTER) @@ -92,15 +80,6 @@ impl BlendedImage { pub fn single(icon: Icon, color: Color, area_color: Color) -> Self { Self::new(icon, icon, color, color, area_color) } - - fn paint_image(&self) { - display::icon_over_icon( - None, - (self.bg, self.bg_top_left.into(), self.bg_color), - (self.fg, self.fg_offset, self.fg_color), - self.area_color, - ); - } } impl Component for BlendedImage { @@ -126,10 +105,6 @@ impl Component for BlendedImage { None } - fn paint(&mut self) { - self.paint_image(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::ToifImage::new(self.bg_top_left, self.bg.toif) .with_fg(self.bg_color) diff --git a/core/embed/rust/src/ui/component/jpeg.rs b/core/embed/rust/src/ui/component/jpeg.rs index 1285c6003b..44cb19d331 100644 --- a/core/embed/rust/src/ui/component/jpeg.rs +++ b/core/embed/rust/src/ui/component/jpeg.rs @@ -2,8 +2,7 @@ use crate::{ io::BinaryData, ui::{ component::{Component, Event, EventCtx, Never}, - display, - geometry::{Alignment2D, Offset, Rect}, + geometry::{Alignment2D, Rect}, shape, shape::Renderer, }, @@ -37,17 +36,6 @@ impl Component for Jpeg { None } - fn paint(&mut self) { - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let jpeg_data = unsafe { self.image.data() }; - - if let Some((size, _)) = display::tjpgd::jpeg_info(jpeg_data) { - let off = Offset::new(size.x / (2 << self.scale), size.y / (2 << self.scale)); - display::tjpgd::jpeg(jpeg_data, self.area.center() - off, self.scale); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::JpegImage::new_image(self.area.center(), self.image) .with_align(Alignment2D::CENTER) diff --git a/core/embed/rust/src/ui/component/label.rs b/core/embed/rust/src/ui/component/label.rs index 624eb75ae0..f2be969858 100644 --- a/core/embed/rust/src/ui/component/label.rs +++ b/core/embed/rust/src/ui/component/label.rs @@ -136,12 +136,8 @@ impl Component for Label<'_> { None } - fn paint(&mut self) { - self.text.map(|c| self.layout.render_text(c)); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { - self.text.map(|c| self.layout.render_text2(c, target)); + self.text.map(|c| self.layout.render_text(c, target)); } } diff --git a/core/embed/rust/src/ui/component/map.rs b/core/embed/rust/src/ui/component/map.rs index 3fc5c469d4..1a08196620 100644 --- a/core/embed/rust/src/ui/component/map.rs +++ b/core/embed/rust/src/ui/component/map.rs @@ -1,7 +1,7 @@ use super::{Component, Event, EventCtx}; use crate::ui::{geometry::Rect, shape::Renderer}; -#[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] +#[cfg(all(feature = "micropython", feature = "touch"))] use crate::ui::component::swipe_detect::SwipeConfig; pub struct MsgMap { @@ -30,16 +30,12 @@ where self.inner.event(ctx, event).and_then(&self.func) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target); } } -#[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] +#[cfg(all(feature = "micropython", feature = "touch"))] impl crate::ui::flow::Swipable for MsgMap where T: Component + crate::ui::flow::Swipable, @@ -90,10 +86,6 @@ where res } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target); } @@ -109,7 +101,7 @@ where } } -#[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] +#[cfg(all(feature = "micropython", feature = "touch"))] impl crate::ui::flow::Swipable for PageMap where T: Component + crate::ui::flow::Swipable, diff --git a/core/embed/rust/src/ui/component/marquee.rs b/core/embed/rust/src/ui/component/marquee.rs index fff8ca83de..104a96c694 100644 --- a/core/embed/rust/src/ui/component/marquee.rs +++ b/core/embed/rust/src/ui/component/marquee.rs @@ -4,7 +4,7 @@ use crate::{ ui::{ animation::Animation, component::{Component, Event, EventCtx, Never, Timer}, - display::{self, Color, Font}, + display::{Color, Font}, geometry::{Offset, Rect}, shape::{self, Renderer}, util::animation_disabled, @@ -119,11 +119,6 @@ impl Marquee { self.animation().is_some() } - pub fn paint_anim(&mut self, offset: i16) { - self.text - .map(|t| display::marquee(self.area, t, offset, self.font, self.fg, self.bg)); - } - pub fn render_anim<'s>(&'s self, target: &mut impl Renderer<'s>, offset: i16) { target.in_window(self.area, &|target| { let text_height = self.font.text_height(); @@ -201,30 +196,6 @@ impl Component for Marquee { None } - fn paint(&mut self) { - let now = Instant::now(); - - match self.state { - State::Initial => { - self.paint_anim(0); - } - State::PauseRight => { - self.paint_anim(self.min_offset); - } - State::PauseLeft => { - self.paint_anim(self.max_offset); - } - _ => { - let progress = self.progress(now); - if let Some(done) = progress { - self.paint_anim(done); - } else { - self.paint_anim(0); - } - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let now = Instant::now(); diff --git a/core/embed/rust/src/ui/component/maybe.rs b/core/embed/rust/src/ui/component/maybe.rs index e46c804de0..93aa00512c 100644 --- a/core/embed/rust/src/ui/component/maybe.rs +++ b/core/embed/rust/src/ui/component/maybe.rs @@ -1,6 +1,6 @@ use crate::ui::{ component::{Component, ComponentExt, Event, EventCtx, Pad}, - display::{self, Color}, + display::Color, geometry::Rect, shape::Renderer, }; @@ -88,13 +88,6 @@ where } } - fn paint(&mut self) { - self.pad.paint(); - if self.visible { - self.inner.paint(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); if self.visible { @@ -103,51 +96,6 @@ where } } -pub trait PaintOverlapping { - /// Return area that would be cleared during regular paint, along with - /// background color, or None if clearing isn't requested. - fn cleared_area(&self) -> Option<(Rect, Color)>; - - /// Paint the component but do not clear background beforehand. - fn paint_overlapping(&mut self); -} - -impl PaintOverlapping for Maybe -where - T: Component, -{ - fn cleared_area(&self) -> Option<(Rect, Color)> { - self.pad.will_paint() - } - - fn paint_overlapping(&mut self) { - self.pad.cancel_clear(); - self.paint() - } -} - -/// Paint multiple Maybe components, correctly handling clearing of -/// background in the case the areas overlap, i.e. clear the combined area first -/// and then paint over it. -pub fn paint_overlapping(components: &mut [&mut dyn PaintOverlapping]) { - let mut area = Rect::zero(); - let mut color = Color::rgb(0, 0, 0); - for component in components.iter() { - if let Some((clear_area, clear_color)) = component.cleared_area() { - area = area.union(clear_area); - color = clear_color; - } - } - - if area != Rect::zero() { - display::rect_fill(area, color) - } - - for component in components.iter_mut() { - component.paint_overlapping() - } -} - // DEBUG-ONLY SECTION BELOW #[cfg(feature = "ui_debug")] diff --git a/core/embed/rust/src/ui/component/pad.rs b/core/embed/rust/src/ui/component/pad.rs index fa6b5b065b..e51192cf7a 100644 --- a/core/embed/rust/src/ui/component/pad.rs +++ b/core/embed/rust/src/ui/component/pad.rs @@ -1,9 +1,4 @@ -use crate::ui::{ - display::{self, Color}, - geometry::Rect, - shape, - shape::Renderer, -}; +use crate::ui::{display::Color, geometry::Rect, shape, shape::Renderer}; pub struct Pad { pub area: Rect, @@ -47,14 +42,6 @@ impl Pad { } } - pub fn paint(&mut self) { - if self.clear { - self.clear = false; - - display::rect_fill(self.area, self.color); - } - } - pub fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::Bar::new(self.area) .with_bg(self.color) diff --git a/core/embed/rust/src/ui/component/placed.rs b/core/embed/rust/src/ui/component/placed.rs index d3901203f3..aae74c23ad 100644 --- a/core/embed/rust/src/ui/component/placed.rs +++ b/core/embed/rust/src/ui/component/placed.rs @@ -61,10 +61,6 @@ where self.inner.event(ctx, event) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target); } @@ -108,10 +104,6 @@ where self.inner.event(ctx, event) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target); } @@ -184,10 +176,6 @@ where self.inner.event(ctx, event) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target); } @@ -278,11 +266,6 @@ where .or_else(|| self.second.event(ctx, event)) } - fn paint(&mut self) { - self.first.paint(); - self.second.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.first.render(target); self.second.render(target); diff --git a/core/embed/rust/src/ui/component/qr_code.rs b/core/embed/rust/src/ui/component/qr_code.rs index f3f7fd0aae..252852ad29 100644 --- a/core/embed/rust/src/ui/component/qr_code.rs +++ b/core/embed/rust/src/ui/component/qr_code.rs @@ -5,9 +5,8 @@ use crate::{ error::Error, ui::{ component::{Component, Event, EventCtx, Never}, - constant, - display::{pixeldata, pixeldata_dirty, rect_fill_rounded, set_window, Color}, - geometry::{Insets, Offset, Rect}, + display::Color, + geometry::{Offset, Rect}, shape, shape::Renderer, }, @@ -76,33 +75,6 @@ impl Qr { } false } - - fn draw(qr: &QrCode, area: Rect, border: i16, scale: i16) { - if border > 0 { - rect_fill_rounded( - area.inset(Insets::uniform(-border)), - LIGHT, - DARK, - CORNER_RADIUS, - ); - } - - let window = area.clamp(constant::screen()); - set_window(window); - - for y in window.y0..window.y1 { - for x in window.x0..window.x1 { - let rx = (x - window.x0) / scale; - let ry = (y - window.y0) / scale; - if qr.get_module(rx.into(), ry.into()) { - pixeldata(DARK); - } else { - pixeldata(LIGHT); - }; - } - } - pixeldata_dirty(); - } } impl Component for Qr { @@ -117,32 +89,6 @@ impl Component for Qr { None } - fn paint(&mut self) { - let mut outbuffer = [0u8; QR_MAX_VERSION.buffer_len()]; - let mut tempbuffer = [0u8; QR_MAX_VERSION.buffer_len()]; - - let qr = QrCode::encode_text( - self.text.as_ref(), - &mut tempbuffer, - &mut outbuffer, - QrCodeEcc::Medium, - Version::MIN, - QR_MAX_VERSION, - None, - true, - ); - let qr = unwrap!(qr); - let size = qr.size() as i16; - - let avail_space = self.area.width().min(self.area.height()); - let avail_space = avail_space - 2 * self.border; - let scale = avail_space / size; - assert!((1..=10).contains(&scale)); - - let area = Rect::from_center_and_size(self.area.center(), Offset::uniform(size * scale)); - Self::draw(&qr, area, self.border, scale); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let mut outbuffer = [0u8; QR_MAX_VERSION.buffer_len()]; let mut tempbuffer = [0u8; QR_MAX_VERSION.buffer_len()]; diff --git a/core/embed/rust/src/ui/component/swipe.rs b/core/embed/rust/src/ui/component/swipe.rs index 820ffeb3f1..b959549fe6 100644 --- a/core/embed/rust/src/ui/component/swipe.rs +++ b/core/embed/rust/src/ui/component/swipe.rs @@ -134,7 +134,5 @@ impl Component for Swipe { None } - fn paint(&mut self) {} - fn render<'s>(&'s self, _target: &mut impl Renderer<'s>) {} } diff --git a/core/embed/rust/src/ui/component/text/formatted.rs b/core/embed/rust/src/ui/component/text/formatted.rs index 9219dbdcb8..2844756ce4 100644 --- a/core/embed/rust/src/ui/component/text/formatted.rs +++ b/core/embed/rust/src/ui/component/text/formatted.rs @@ -5,7 +5,7 @@ use crate::ui::{ }; use super::{ - layout::{LayoutFit, LayoutSink, TextNoOp, TextRenderer, TextRenderer2}, + layout::{LayoutFit, LayoutSink, TextNoOp, TextRenderer}, op::OpTextLayout, }; @@ -130,12 +130,8 @@ impl Component for FormattedText { None } - fn paint(&mut self) { - self.layout_content(&mut TextRenderer); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { - self.layout_content(&mut TextRenderer2::new(target)); + self.layout_content(&mut TextRenderer::new(target)); } } diff --git a/core/embed/rust/src/ui/component/text/layout.rs b/core/embed/rust/src/ui/component/text/layout.rs index 52a422ba58..6a49b70daa 100644 --- a/core/embed/rust/src/ui/component/text/layout.rs +++ b/core/embed/rust/src/ui/component/text/layout.rs @@ -1,5 +1,4 @@ use crate::ui::{ - display, display::{toif::Icon, Color, Font, GlyphMetrics}, geometry::{Alignment, Alignment2D, Dimensions, Offset, Point, Rect}, shape, @@ -233,12 +232,7 @@ impl TextLayout { } /// Draw as much text as possible on the current screen. - pub fn render_text(&self, text: &str) -> LayoutFit { - self.layout_text(text, &mut self.initial_cursor(), &mut TextRenderer) - } - - /// Draw as much text as possible on the current screen. - pub fn render_text2<'s>(&self, text: &str, target: &mut impl Renderer<'s>) -> LayoutFit { + pub fn render_text<'s>(&self, text: &str, target: &mut impl Renderer<'s>) -> LayoutFit { self.render_text_with_alpha(text, target, 255) } /// Draw as much text as possible on the current screen. @@ -251,7 +245,7 @@ impl TextLayout { self.layout_text( text, &mut self.initial_cursor(), - &mut TextRenderer2::new(target).with_alpha(alpha), + &mut TextRenderer::new(target).with_alpha(alpha), ) } @@ -486,71 +480,7 @@ pub struct TextNoOp; impl LayoutSink for TextNoOp {} -/// `LayoutSink` for rendering the content. -pub struct TextRenderer; - -impl LayoutSink for TextRenderer { - fn text(&mut self, cursor: Point, layout: &TextLayout, text: &str) { - display::text_left( - cursor, - text, - layout.style.text_font, - layout.style.text_color, - layout.style.background_color, - ); - } - - fn hyphen(&mut self, cursor: Point, layout: &TextLayout) { - display::text_left( - cursor, - "-", - layout.style.text_font, - layout.style.hyphen_color, - layout.style.background_color, - ); - } - - fn ellipsis(&mut self, cursor: Point, layout: &TextLayout) { - if let Some((icon, margin)) = layout.style.ellipsis_icon { - let bottom_left = cursor + Offset::x(margin); - icon.draw( - bottom_left, - Alignment2D::BOTTOM_LEFT, - layout.style.ellipsis_color, - layout.style.background_color, - ); - } else { - display::text_left( - cursor, - ELLIPSIS, - layout.style.text_font, - layout.style.ellipsis_color, - layout.style.background_color, - ); - } - } - - fn prev_page_ellipsis(&mut self, cursor: Point, layout: &TextLayout) { - if let Some((icon, _margin)) = layout.style.prev_page_ellipsis_icon { - icon.draw( - cursor, - Alignment2D::BOTTOM_LEFT, - layout.style.ellipsis_color, - layout.style.background_color, - ); - } else { - display::text_left( - cursor, - ELLIPSIS, - layout.style.text_font, - layout.style.ellipsis_color, - layout.style.background_color, - ); - } - } -} - -pub struct TextRenderer2<'a, 's, R> +pub struct TextRenderer<'a, 's, R> where R: Renderer<'s>, { @@ -559,7 +489,7 @@ where alpha: u8, } -impl<'a, 's, R> TextRenderer2<'a, 's, R> +impl<'a, 's, R> TextRenderer<'a, 's, R> where R: Renderer<'s>, { @@ -576,7 +506,7 @@ where } } -impl<'a, 's, R> LayoutSink for TextRenderer2<'a, 's, R> +impl<'a, 's, R> LayoutSink for TextRenderer<'a, 's, R> where R: Renderer<'s>, { diff --git a/core/embed/rust/src/ui/component/text/paragraphs.rs b/core/embed/rust/src/ui/component/text/paragraphs.rs index 1ca054cb98..26a6033e40 100644 --- a/core/embed/rust/src/ui/component/text/paragraphs.rs +++ b/core/embed/rust/src/ui/component/text/paragraphs.rs @@ -5,9 +5,7 @@ use crate::{ ui::{ component::{Component, Event, EventCtx, Never, Paginate}, display::{toif::Icon, Color, Font}, - geometry::{ - Alignment, Alignment2D, Dimensions, Insets, LinearPlacement, Offset, Point, Rect, - }, + geometry::{Alignment, Dimensions, Insets, LinearPlacement, Offset, Point, Rect}, shape, shape::Renderer, }, @@ -196,24 +194,13 @@ where None } - fn paint(&mut self) { - Self::foreach_visible( - &self.source, - &self.visible, - self.offset, - &mut |layout, content| { - layout.render_text(content); - }, - ) - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { Self::foreach_visible( &self.source, &self.visible, self.offset, &mut |layout, content| { - layout.render_text2(content, target); + layout.render_text(content, target); }, ) } @@ -649,16 +636,6 @@ where } } - fn paint_icon(&self, layout: &TextLayout, icon: Icon, offset: Offset) { - let top_left = Point::new(self.area.x0, layout.bounds.y0); - icon.draw( - top_left + offset, - Alignment2D::TOP_LEFT, - layout.style.text_color, - layout.style.background_color, - ); - } - fn render_numeral<'s>( &self, base_point: Point, @@ -703,26 +680,6 @@ where self.paragraphs.event(ctx, event) } - fn paint(&mut self) { - self.paragraphs.paint(); - - let current_visible = self.current.saturating_sub(self.paragraphs.offset.par); - for layout in self.paragraphs.visible.iter().take(current_visible) { - self.paint_icon( - &layout.layout(&self.paragraphs.source), - self.icon_done, - self.done_offset, - ); - } - if let Some(layout) = self.paragraphs.visible.iter().nth(current_visible) { - self.paint_icon( - &layout.layout(&self.paragraphs.source), - self.icon_current, - self.current_offset, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.paragraphs.render(target); self.render_left_column(target); diff --git a/core/embed/rust/src/ui/component/text/util.rs b/core/embed/rust/src/ui/component/text/util.rs index 69ddd4de42..29355a3c39 100644 --- a/core/embed/rust/src/ui/component/text/util.rs +++ b/core/embed/rust/src/ui/component/text/util.rs @@ -19,33 +19,7 @@ use super::{ /// /// If it fits, returns the rest of the area. /// If it does not fit, returns `None`. -pub fn text_multiline( - area: Rect, - text: TString<'_>, - font: Font, - fg_color: Color, - bg_color: Color, - alignment: Alignment, -) -> Option { - let text_style = TextStyle::new(font, fg_color, bg_color, fg_color, fg_color); - let text_layout = TextLayout::new(text_style) - .with_bounds(area) - .with_align(alignment); - let layout_fit = text.map(|t| text_layout.render_text(t)); - match layout_fit { - LayoutFit::Fitting { height, .. } => Some(area.split_top(height).1), - LayoutFit::OutOfBounds { .. } => None, - } -} - -/// Draws longer multiline texts inside an area. -/// Splits lines on word boundaries/whitespace. -/// When a word is too long to fit one line, splitting -/// it on multiple lines with "-" at the line-ends. -/// -/// If it fits, returns the rest of the area. -/// If it does not fit, returns `None`. -pub fn text_multiline2<'s>( +pub fn text_multiline<'s>( target: &mut impl Renderer<'s>, area: Rect, text: TString<'_>, @@ -58,7 +32,7 @@ pub fn text_multiline2<'s>( let text_layout = TextLayout::new(text_style) .with_bounds(area) .with_align(alignment); - let layout_fit = text.map(|t| text_layout.render_text2(t, target)); + let layout_fit = text.map(|t| text_layout.render_text(t, target)); match layout_fit { LayoutFit::Fitting { height, .. } => Some(area.split_top(height).1), LayoutFit::OutOfBounds { .. } => None, @@ -67,37 +41,7 @@ pub fn text_multiline2<'s>( /// Same as `text_multiline` above, but aligns the text to the bottom of the /// area. -pub fn text_multiline_bottom( - area: Rect, - text: TString<'_>, - font: Font, - fg_color: Color, - bg_color: Color, - alignment: Alignment, -) -> Option { - let text_style = TextStyle::new(font, fg_color, bg_color, fg_color, fg_color); - let mut text_layout = TextLayout::new(text_style) - .with_bounds(area) - .with_align(alignment); - // When text fits the area, displaying it in the bottom part. - // When not, render it "normally". - text.map(|t| match text_layout.fit_text(t) { - LayoutFit::Fitting { height, .. } => { - let (top, bottom) = area.split_bottom(height); - text_layout = text_layout.with_bounds(bottom); - text_layout.render_text(t); - Some(top) - } - LayoutFit::OutOfBounds { .. } => { - text_layout.render_text(t); - None - } - }) -} - -/// Same as `text_multiline` above, but aligns the text to the bottom of the -/// area. -pub fn text_multiline_bottom2<'s>( +pub fn text_multiline_bottom<'s>( target: &mut impl Renderer<'s>, area: Rect, text: TString<'_>, @@ -116,11 +60,11 @@ pub fn text_multiline_bottom2<'s>( LayoutFit::Fitting { height, .. } => { let (top, bottom) = area.split_bottom(height); text_layout = text_layout.with_bounds(bottom); - text_layout.render_text2(t, target); + text_layout.render_text(t, target); Some(top) } LayoutFit::OutOfBounds { .. } => { - text_layout.render_text2(t, target); + text_layout.render_text(t, target); None } }) diff --git a/core/embed/rust/src/ui/component/timeout.rs b/core/embed/rust/src/ui/component/timeout.rs index 9d5c83e648..77da02b032 100644 --- a/core/embed/rust/src/ui/component/timeout.rs +++ b/core/embed/rust/src/ui/component/timeout.rs @@ -35,8 +35,6 @@ impl Component for Timeout { self.timer.expire(event).then_some(()) } - fn paint(&mut self) {} - fn render<'s>(&'s self, _target: &mut impl Renderer<'s>) {} } diff --git a/core/embed/rust/src/ui/display/font.rs b/core/embed/rust/src/ui/display/font.rs index 04600d7371..090d22ad08 100644 --- a/core/embed/rust/src/ui/display/font.rs +++ b/core/embed/rust/src/ui/display/font.rs @@ -2,14 +2,12 @@ use crate::{ trezorhal::display, ui::{ constant, - geometry::{Offset, Point, Rect}, + geometry::Offset, shape::{Bitmap, BitmapFormat}, }, }; use core::slice; -use super::{get_color_table, get_offset, pixeldata, set_window, Color}; - /// Representation of a single glyph. /// We use standard typographic terms. For a nice explanation, see, e.g., /// the FreeType docs at https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html @@ -67,28 +65,6 @@ impl Glyph { self.adv - self.width - self.bearing_x } - pub fn print(&self, pos: Point, colortable: [Color; 16]) -> i16 { - let bearing = Offset::new(self.bearing_x, -self.bearing_y); - let size = Offset::new(self.width, self.height); - let pos_adj = pos + bearing; - let r = Rect::from_top_left_and_size(pos_adj, size); - - let area = r.translate(get_offset()); - let window = area.clamp(constant::screen()); - - set_window(window); - - for y in window.y0..window.y1 { - for x in window.x0..window.x1 { - let p = Point::new(x, y); - let r = p - pos_adj; - let c = self.get_pixel_data(r); - pixeldata(colortable[c as usize]); - } - } - self.adv - } - pub fn unpack_bpp1(&self, a: i16) -> u8 { let c_data = self.data[(a / 8) as usize]; ((c_data >> (7 - (a % 8))) & 0x01) * 15 @@ -109,18 +85,6 @@ impl Glyph { c_data >> 4 } - pub fn get_pixel_data(&self, p: Offset) -> u8 { - let a = p.x + p.y * self.width; - - match constant::FONT_BPP { - 1 => self.unpack_bpp1(a), - 2 => self.unpack_bpp2(a), - 4 => self.unpack_bpp4(a), - 8 => self.unpack_bpp8(a), - _ => 0, - } - } - pub fn bitmap(&self) -> Bitmap<'static> { match constant::FONT_BPP { 1 => unwrap!(Bitmap::new( @@ -298,16 +262,6 @@ impl Font { unsafe { Glyph::load(gl_data) } } - pub fn display_text(self, text: &str, baseline: Point, fg_color: Color, bg_color: Color) { - let colortable = get_color_table(fg_color, bg_color); - let mut adv_total = 0; - for c in text.chars() { - let gly = self.get_glyph(c); - let adv = gly.print(baseline + Offset::new(adv_total, 0), colortable); - adv_total += adv; - } - } - /// Get the longest prefix of a given `text` (breaking at word boundaries) /// that will fit into the area `width` pixels wide. pub fn longest_prefix(self, width: i16, text: &str) -> &str { diff --git a/core/embed/rust/src/ui/display/loader/circular.rs b/core/embed/rust/src/ui/display/loader/circular.rs deleted file mode 100644 index 894974a8ab..0000000000 --- a/core/embed/rust/src/ui/display/loader/circular.rs +++ /dev/null @@ -1,429 +0,0 @@ -use crate::ui::{ - constant, - constant::{screen, LOADER_INNER, LOADER_OUTER}, - display, - display::{toif::Icon, Color}, - geometry::{Offset, Point, Rect}, -}; - -#[cfg(feature = "dma2d")] -use crate::trezorhal::{ - buffers, - dma2d::{dma2d_setup_4bpp_over_4bpp, dma2d_start_blend, dma2d_wait_for_transfer}, -}; - -const ICON_MAX_SIZE: i16 = constant::LOADER_ICON_MAX_SIZE; - -#[derive(Clone, Copy)] -pub struct LoaderDimensions { - in_inner_anti: i32, - inner_min: i32, - inner_max: i32, - inner_outer_anti: i32, - outer_out_anti: i32, - outer_max: i32, -} - -impl LoaderDimensions { - pub fn new(outer: i16, inner: i16) -> Self { - let outer: f32 = outer.into(); - let inner: f32 = inner.into(); - Self { - in_inner_anti: ((inner - 0.5) * (inner - 0.5)) as i32, - inner_min: ((inner + 0.5) * (inner + 0.5)) as i32, - inner_max: ((inner + 1.5) * (inner + 1.5)) as i32, - inner_outer_anti: ((inner + 2.5) * (inner + 2.5)) as i32, - outer_out_anti: ((outer - 1.5) * (outer - 1.5)) as i32, - outer_max: ((outer - 0.5) * (outer - 0.5)) as i32, - } - } -} - -pub fn loader_circular_uncompress( - dim: LoaderDimensions, - y_offset: i16, - fg_color: Color, - bg_color: Color, - progress: u16, - indeterminate: bool, - icon: Option<(Icon, Color)>, -) { - if let Some((icon, color)) = icon { - let toif_size = icon.toif.size(); - if toif_size.x <= ICON_MAX_SIZE && toif_size.y <= ICON_MAX_SIZE { - let mut icon_data = [0_u8; ((ICON_MAX_SIZE * ICON_MAX_SIZE) / 2) as usize]; - icon.toif.uncompress(&mut icon_data); - let i = Some((icon_data.as_ref(), color, toif_size)); - loader_rust( - dim, - y_offset, - fg_color, - bg_color, - progress, - indeterminate, - i, - ); - } else { - loader_rust( - dim, - y_offset, - fg_color, - bg_color, - progress, - indeterminate, - None, - ); - } - } else { - loader_rust( - dim, - y_offset, - fg_color, - bg_color, - progress, - indeterminate, - None, - ); - } -} - -pub fn loader_circular( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - loader_circular_uncompress( - LoaderDimensions::new(LOADER_OUTER, LOADER_INNER), - y_offset, - fg_color, - bg_color, - progress, - false, - icon, - ); -} - -pub fn loader_circular_indeterminate( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - loader_circular_uncompress( - LoaderDimensions::new(LOADER_OUTER, LOADER_INNER), - y_offset, - fg_color, - bg_color, - progress, - true, - icon, - ); -} - -#[inline(always)] -fn get_loader_vectors(indeterminate: bool, progress: u16) -> (Point, Point) { - let (start_progress, end_progress) = if indeterminate { - const LOADER_INDETERMINATE_WIDTH: u16 = 100; - ( - (progress + 1000 - LOADER_INDETERMINATE_WIDTH) % 1000, - (progress + LOADER_INDETERMINATE_WIDTH) % 1000, - ) - } else { - (0, progress) - }; - - let start = ((360 * start_progress as i32) / 1000) % 360; - let end = ((360 * end_progress as i32) / 1000) % 360; - - let start_vector; - let end_vector; - - if indeterminate { - start_vector = display::get_vector(start as _); - end_vector = display::get_vector(end as _); - } else if progress >= 1000 { - start_vector = Point::zero(); - end_vector = Point::zero(); - } else if progress > 500 { - start_vector = display::get_vector(end as _); - end_vector = display::get_vector(start as _); - } else { - start_vector = display::get_vector(start as _); - end_vector = display::get_vector(end as _); - } - - (start_vector, end_vector) -} - -#[inline(always)] -fn loader_get_pixel_color_idx( - show_all: bool, - inverted: bool, - end_vector: Point, - n_start: Point, - c: Point, - center: Point, - dim: LoaderDimensions, -) -> u8 { - let y_p = -(c.y - center.y); - let x_p = c.x - center.x; - - let vx = Point::new(x_p, y_p); - let n_vx = Point::new(-y_p, x_p); - - let d = y_p as i32 * y_p as i32 + x_p as i32 * x_p as i32; - - let included = if inverted { - !display::is_clockwise_or_equal(n_start, vx) - || !display::is_clockwise_or_equal_inc(n_vx, end_vector) - } else { - display::is_clockwise_or_equal(n_start, vx) - && display::is_clockwise_or_equal_inc(n_vx, end_vector) - }; - - // The antialiasing calculation below uses simplified distance difference - // calculation. Optimally, SQRT should be used, but assuming - // diameter large enough and antialiasing over distance - // r_outer-r_inner = 1, the difference between simplified: - // (d^2-r_inner^2)/(r_outer^2-r_inner^2) and precise: (sqrt(d^2) - // - r_inner)/(r_outer-r_inner) is negligible - if show_all || included { - //active part - if d <= dim.in_inner_anti { - 0 - } else if d <= dim.inner_min { - ((15 * (d - dim.in_inner_anti)) / (dim.inner_min - dim.in_inner_anti)) as u8 - } else if d <= dim.outer_out_anti { - 15 - } else if d <= dim.outer_max { - (15 - ((15 * (d - dim.outer_out_anti)) / (dim.outer_max - dim.outer_out_anti))) as u8 - } else { - 0 - } - } else { - //inactive part - if d <= dim.in_inner_anti { - 0 - } else if d <= dim.inner_min { - ((15 * (d - dim.in_inner_anti)) / (dim.inner_min - dim.in_inner_anti)) as u8 - } else if d <= dim.inner_max { - 15 - } else if d <= dim.inner_outer_anti { - (15 - ((10 * (d - dim.inner_max)) / (dim.inner_outer_anti - dim.inner_max))) as u8 - } else if d <= dim.outer_out_anti { - 5 - } else if d <= dim.outer_max { - 5 - ((5 * (d - dim.outer_out_anti)) / (dim.outer_max - dim.outer_out_anti)) as u8 - } else { - 0 - } - } -} - -#[cfg(not(feature = "dma2d"))] -pub fn loader_rust( - dim: LoaderDimensions, - y_offset: i16, - fg_color: Color, - bg_color: Color, - progress: u16, - indeterminate: bool, - icon: Option<(&[u8], Color, Offset)>, -) { - let center = screen().center() + Offset::new(0, y_offset); - let r = Rect::from_center_and_size(center, Offset::uniform(LOADER_OUTER as i16 * 2)); - let clamped = r.clamp(constant::screen()); - display::set_window(clamped); - - let center = r.center(); - - let colortable = display::get_color_table(fg_color, bg_color); - let mut icon_colortable = colortable; - - let mut use_icon = false; - let mut icon_area = Rect::zero(); - let mut icon_area_clamped = Rect::zero(); - let mut icon_width = 0; - let mut icon_data = [].as_ref(); - - if let Some((data, color, size)) = icon { - if size.x <= ICON_MAX_SIZE && size.y <= ICON_MAX_SIZE { - icon_width = size.x; - icon_area = Rect::from_center_and_size(center, size); - icon_area_clamped = icon_area.clamp(constant::screen()); - icon_data = data; - use_icon = true; - icon_colortable = display::get_color_table(color, bg_color); - } - } - - let show_all = !indeterminate && progress >= 1000; - let inverted = !indeterminate && progress > 500; - let (start_vector, end_vector) = get_loader_vectors(indeterminate, progress); - - let n_start = Point::new(-start_vector.y, start_vector.x); - - for y_c in r.y0..r.y1 { - for x_c in r.x0..r.x1 { - let p = Point::new(x_c, y_c); - let mut icon_pixel = false; - - let mut underlying_color = bg_color; - - if use_icon && icon_area_clamped.contains(p) { - let x = x_c - center.x; - let y = y_c - center.y; - if (x as i32 * x as i32 + y as i32 * y as i32) <= dim.in_inner_anti { - let x_i = x_c - icon_area.x0; - let y_i = y_c - icon_area.y0; - - let data = icon_data[(((x_i & 0xFE) + (y_i * icon_width)) / 2) as usize]; - if (x_i & 0x01) == 0 { - underlying_color = icon_colortable[(data & 0xF) as usize]; - } else { - underlying_color = icon_colortable[(data >> 4) as usize]; - } - icon_pixel = true; - } - } - - if clamped.contains(p) && !icon_pixel { - let pix_c_idx = loader_get_pixel_color_idx( - show_all, - inverted, - end_vector, - n_start, - Point::new(x_c, y_c), - center, - dim, - ); - underlying_color = colortable[pix_c_idx as usize]; - } - - display::pixeldata(underlying_color); - } - } - - display::pixeldata_dirty(); -} - -#[cfg(feature = "dma2d")] -pub fn loader_rust( - dim: LoaderDimensions, - y_offset: i16, - fg_color: Color, - bg_color: Color, - progress: u16, - indeterminate: bool, - icon: Option<(&[u8], Color, Offset)>, -) { - let center = screen().center() + Offset::new(0, y_offset); - let r = Rect::from_center_and_size(center, Offset::uniform(LOADER_OUTER * 2)); - let clamped = r.clamp(constant::screen()); - display::set_window(clamped); - - let center = r.center(); - - let mut use_icon = false; - let mut icon_area = Rect::zero(); - let mut icon_area_clamped = Rect::zero(); - let mut icon_width = 0; - let mut icon_offset = 0; - let mut icon_color = Color::from_u16(0); - let mut icon_data = [].as_ref(); - - if let Some((data, color, size)) = icon { - if size.x <= ICON_MAX_SIZE && size.y <= ICON_MAX_SIZE { - icon_width = size.x; - icon_area = Rect::from_center_and_size(center, size); - icon_area_clamped = icon_area.clamp(constant::screen()); - icon_offset = (icon_area_clamped.x0 - r.x0) / 2; - icon_color = color; - icon_data = data; - use_icon = true; - } - } - - let show_all = !indeterminate && progress >= 1000; - let inverted = !indeterminate && progress > 500; - let (start_vector, end_vector) = get_loader_vectors(indeterminate, progress); - - let n_start = Point::new(-start_vector.y, start_vector.x); - - let mut b1 = buffers::BufferLine16bpp::get(); - let mut b2 = buffers::BufferLine16bpp::get(); - let mut ib1 = buffers::BufferLine4bpp::get_cleared(); - let mut ib2 = buffers::BufferLine4bpp::get_cleared(); - let mut empty_line = buffers::BufferLine4bpp::get_cleared(); - - dma2d_setup_4bpp_over_4bpp(fg_color.into(), bg_color.into(), icon_color.into()); - - for y_c in r.y0..r.y1 { - let mut icon_buffer = &mut *empty_line; - let icon_buffer_used; - let loader_buffer; - - if y_c % 2 == 0 { - icon_buffer_used = &mut *ib1; - loader_buffer = &mut *b1; - } else { - icon_buffer_used = &mut *ib2; - loader_buffer = &mut *b2; - } - - if use_icon && y_c >= icon_area_clamped.y0 && y_c < icon_area_clamped.y1 { - let y_i = y_c - icon_area.y0; - - // Optimally, we should cut corners of the icon if it happens to be large enough - // to invade loader area. but this would require calculation of circle chord - // length (since we need to limit data copied to the buffer), - // which requires expensive SQRT. Therefore, when using this method of loader - // drawing, special care needs to be taken to ensure that the icons - // have transparent corners. - - icon_buffer_used.buffer[icon_offset as usize..(icon_offset + icon_width / 2) as usize] - .copy_from_slice( - &icon_data[(y_i * (icon_width / 2)) as usize - ..((y_i + 1) * (icon_width / 2)) as usize], - ); - icon_buffer = icon_buffer_used; - } - - let mut pix_c_idx_prev: u8 = 0; - - for x_c in r.x0..r.x1 { - let p = Point::new(x_c, y_c); - - let pix_c_idx = if clamped.contains(p) { - loader_get_pixel_color_idx( - show_all, - inverted, - end_vector, - n_start, - Point::new(x_c, y_c), - center, - dim, - ) - } else { - 0 - }; - - let x = x_c - r.x0; - if x % 2 == 0 { - pix_c_idx_prev = pix_c_idx; - } else { - loader_buffer.buffer[(x >> 1) as usize] = pix_c_idx_prev | pix_c_idx << 4; - } - } - - dma2d_wait_for_transfer(); - unsafe { - dma2d_start_blend(&icon_buffer.buffer, &loader_buffer.buffer, clamped.width()); - } - } - - dma2d_wait_for_transfer(); -} diff --git a/core/embed/rust/src/ui/display/loader/circular_thin.rs b/core/embed/rust/src/ui/display/loader/circular_thin.rs deleted file mode 100644 index 33efebd7fe..0000000000 --- a/core/embed/rust/src/ui/display/loader/circular_thin.rs +++ /dev/null @@ -1,333 +0,0 @@ -use crate::ui::{ - constant, - constant::{screen, LOADER_INNER, LOADER_OUTER}, - display, - display::{toif::Icon, Color}, - geometry::{Offset, Point, Rect}, -}; - -use crate::trezorhal::{ - buffers, - dma2d::{dma2d_setup_4bpp_over_4bpp, dma2d_start_blend, dma2d_wait_for_transfer}, -}; - -const ICON_MAX_SIZE: i16 = constant::LOADER_ICON_MAX_SIZE; - -#[derive(Clone, Copy)] -pub struct LoaderDimensions { - in_inner_anti: i32, - inner_min: i32, - outer_out_anti: i32, - outer_max: i32, -} - -impl LoaderDimensions { - pub fn new(outer: i16, inner: i16) -> Self { - let outer: f32 = outer.into(); - let inner: f32 = inner.into(); - Self { - in_inner_anti: ((inner + 0.5) * (inner + 0.5)) as i32, - inner_min: ((inner + 1.5) * (inner + 1.5)) as i32, - outer_out_anti: ((outer - 1.5) * (outer - 1.5)) as i32, - outer_max: ((outer - 0.5) * (outer - 0.5)) as i32, - } - } -} - -pub fn loader_circular_uncompress( - dim: LoaderDimensions, - y_offset: i16, - fg_color: Color, - bg_color: Color, - progress: u16, - indeterminate: bool, - icon: Option<(Icon, Color)>, -) { - if let Some((icon, color)) = icon { - let toif_size = icon.toif.size(); - if toif_size.x <= ICON_MAX_SIZE && toif_size.y <= ICON_MAX_SIZE { - let mut icon_data = [0_u8; ((ICON_MAX_SIZE * ICON_MAX_SIZE) / 2) as usize]; - icon.toif.uncompress(&mut icon_data); - let i = Some((icon_data.as_ref(), color, toif_size)); - loader_rust( - dim, - y_offset, - fg_color, - bg_color, - progress, - indeterminate, - i, - ); - } else { - loader_rust( - dim, - y_offset, - fg_color, - bg_color, - progress, - indeterminate, - None, - ); - } - } else { - loader_rust( - dim, - y_offset, - fg_color, - bg_color, - progress, - indeterminate, - None, - ); - } -} - -pub fn loader_circular( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - loader_circular_uncompress( - LoaderDimensions::new(LOADER_OUTER, LOADER_INNER), - y_offset, - fg_color, - bg_color, - progress, - false, - icon, - ); -} - -pub fn loader_circular_indeterminate( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - loader_circular_uncompress( - LoaderDimensions::new(LOADER_OUTER, LOADER_INNER), - y_offset, - fg_color, - bg_color, - progress, - true, - icon, - ); -} - -#[inline(always)] -fn get_loader_vectors(indeterminate: bool, progress: u16) -> (Point, Point) { - let (start_progress, end_progress) = if indeterminate { - const LOADER_INDETERMINATE_WIDTH: u16 = 100; - ( - (progress + 1000 - LOADER_INDETERMINATE_WIDTH) % 1000, - (progress + LOADER_INDETERMINATE_WIDTH) % 1000, - ) - } else { - (0, progress) - }; - - let start = ((360 * start_progress as i32) / 1000) % 360; - let end = ((360 * end_progress as i32) / 1000) % 360; - - let start_vector; - let end_vector; - - if indeterminate { - start_vector = display::get_vector(start as _); - end_vector = display::get_vector(end as _); - } else if progress >= 1000 { - start_vector = Point::zero(); - end_vector = Point::zero(); - } else if progress > 500 { - start_vector = display::get_vector(end as _); - end_vector = display::get_vector(start as _); - } else { - start_vector = display::get_vector(start as _); - end_vector = display::get_vector(end as _); - } - - (start_vector, end_vector) -} - -#[inline(always)] -fn loader_get_pixel_color_idx( - show_all: bool, - inverted: bool, - end_vector: Point, - n_start: Point, - c: Point, - center: Point, - dim: LoaderDimensions, -) -> u8 { - let y_p = -(c.y - center.y); - let x_p = c.x - center.x; - - let vx = Point::new(x_p, y_p); - let n_vx = Point::new(-y_p, x_p); - - let d = y_p as i32 * y_p as i32 + x_p as i32 * x_p as i32; - - let included = if inverted { - !display::is_clockwise_or_equal(n_start, vx) - || !display::is_clockwise_or_equal_inc(n_vx, end_vector) - } else { - display::is_clockwise_or_equal(n_start, vx) - && display::is_clockwise_or_equal_inc(n_vx, end_vector) - }; - - // The antialiasing calculation below uses simplified distance difference - // calculation. Optimally, SQRT should be used, but assuming - // diameter large enough and antialiasing over distance - // r_outer-r_inner = 1, the difference between simplified: - // (d^2-r_inner^2)/(r_outer^2-r_inner^2) and precise: (sqrt(d^2) - // - r_inner)/(r_outer-r_inner) is negligible - if show_all || included { - //active part - if d <= dim.in_inner_anti { - 0 - } else if d <= dim.inner_min { - ((15 * (d - dim.in_inner_anti)) / (dim.inner_min - dim.in_inner_anti)) as u8 - } else if d <= dim.outer_out_anti { - 15 - } else if d <= dim.outer_max { - (15 - ((15 * (d - dim.outer_out_anti)) / (dim.outer_max - dim.outer_out_anti))) as u8 - } else { - 0 - } - } else { - //inactive part - if d <= dim.in_inner_anti { - 0 - } else if d <= dim.inner_min { - ((4 * (d - dim.in_inner_anti)) / (dim.inner_min - dim.in_inner_anti)) as u8 - } else if d <= dim.outer_out_anti { - 4 - } else if d <= dim.outer_max { - 4 - ((4 * (d - dim.outer_out_anti)) / (dim.outer_max - dim.outer_out_anti)) as u8 - } else { - 0 - } - } -} - -pub fn loader_rust( - dim: LoaderDimensions, - y_offset: i16, - fg_color: Color, - bg_color: Color, - progress: u16, - indeterminate: bool, - icon: Option<(&[u8], Color, Offset)>, -) { - let center = screen().center() + Offset::new(0, y_offset); - let r = Rect::from_center_and_size(center, Offset::uniform(LOADER_OUTER * 2)); - let clamped = r.clamp(constant::screen()); - display::set_window(clamped); - - let center = r.center(); - - let mut use_icon = false; - let mut icon_area = Rect::zero(); - - let mut icon_area_clamped = Rect::zero(); - let mut icon_width = 0; - let mut icon_offset = 0; - let mut icon_color = Color::from_u16(0); - let mut icon_data = [].as_ref(); - - if let Some((data, color, size)) = icon { - if size.x <= ICON_MAX_SIZE && size.y <= ICON_MAX_SIZE { - icon_width = size.x; - icon_area = Rect::from_center_and_size(center, size); - icon_area_clamped = icon_area.clamp(constant::screen()); - icon_offset = (icon_area_clamped.x0 - r.x0) / 2; - icon_color = color; - icon_data = data; - use_icon = true; - } - } - - let show_all = !indeterminate && progress >= 1000; - let inverted = !indeterminate && progress > 500; - let (start_vector, end_vector) = get_loader_vectors(indeterminate, progress); - - let n_start = Point::new(-start_vector.y, start_vector.x); - - let mut b1 = buffers::BufferLine16bpp::get(); - let mut b2 = buffers::BufferLine16bpp::get(); - let mut ib1 = buffers::BufferLine4bpp::get_cleared(); - let mut ib2 = buffers::BufferLine4bpp::get_cleared(); - let mut empty_line = buffers::BufferLine4bpp::get_cleared(); - - dma2d_setup_4bpp_over_4bpp(fg_color.into(), bg_color.into(), icon_color.into()); - - for y_c in r.y0..r.y1 { - let mut icon_buffer = &mut *empty_line; - let icon_buffer_used; - let loader_buffer; - - if y_c % 2 == 0 { - icon_buffer_used = &mut *ib1; - loader_buffer = &mut *b1; - } else { - icon_buffer_used = &mut *ib2; - loader_buffer = &mut *b2; - } - - if use_icon && y_c >= icon_area_clamped.y0 && y_c < icon_area_clamped.y1 { - let y_i = y_c - icon_area.y0; - - // Optimally, we should cut corners of the icon if it happens to be large enough - // to invade loader area. but this would require calculation of circle chord - // length (since we need to limit data copied to the buffer), - // which requires expensive SQRT. Therefore, when using this method of loader - // drawing, special care needs to be taken to ensure that the icons - // have transparent corners. - - icon_buffer_used.buffer[icon_offset as usize..(icon_offset + icon_width / 2) as usize] - .copy_from_slice( - &icon_data[(y_i * (icon_width / 2)) as usize - ..((y_i + 1) * (icon_width / 2)) as usize], - ); - icon_buffer = icon_buffer_used; - } - - let mut pix_c_idx_prev: u8 = 0; - - for x_c in r.x0..r.x1 { - let p = Point::new(x_c, y_c); - - let pix_c_idx = if clamped.contains(p) { - loader_get_pixel_color_idx( - show_all, - inverted, - end_vector, - n_start, - Point::new(x_c, y_c), - center, - dim, - ) - } else { - 0 - }; - - let x = x_c - r.x0; - if x % 2 == 0 { - pix_c_idx_prev = pix_c_idx; - } else { - loader_buffer.buffer[(x >> 1) as usize] = pix_c_idx_prev | pix_c_idx << 4; - } - } - - dma2d_wait_for_transfer(); - unsafe { - dma2d_start_blend(&icon_buffer.buffer, &loader_buffer.buffer, clamped.width()); - } - } - - dma2d_wait_for_transfer(); -} diff --git a/core/embed/rust/src/ui/display/loader/mod.rs b/core/embed/rust/src/ui/display/loader/mod.rs deleted file mode 100644 index 5d41532c04..0000000000 --- a/core/embed/rust/src/ui/display/loader/mod.rs +++ /dev/null @@ -1,50 +0,0 @@ -mod circular; -#[cfg(feature = "dma2d")] -mod circular_thin; -mod rectangular; -mod small; -mod starry; - -use crate::ui::display::{Color, Icon}; - -#[cfg(feature = "model_tt")] -use crate::ui::display::loader::circular::{ - loader_circular as determinate, loader_circular_indeterminate as indeterminate, -}; -#[cfg(any(feature = "model_tt", feature = "model_mercury"))] -pub use crate::ui::display::loader::circular::{loader_circular_uncompress, LoaderDimensions}; - -#[cfg(all(feature = "model_mercury", not(feature = "model_tt")))] -use crate::ui::display::loader::circular_thin::{ - loader_circular as determinate, loader_circular_indeterminate as indeterminate, -}; - -#[cfg(all(not(feature = "model_tt"), not(feature = "model_mercury")))] -use crate::ui::display::loader::rectangular::loader_rectangular as determinate; -#[cfg(all(not(feature = "model_tt"), not(feature = "model_mercury")))] -use crate::ui::display::loader::starry::loader_starry_indeterminate as indeterminate; - -pub use small::loader_small_indeterminate; - -pub const LOADER_MIN: u16 = 0; -pub const LOADER_MAX: u16 = 1000; - -pub fn loader( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - determinate(progress, y_offset, fg_color, bg_color, icon); -} - -pub fn loader_indeterminate( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - indeterminate(progress, y_offset, fg_color, bg_color, icon); -} diff --git a/core/embed/rust/src/ui/display/loader/rectangular.rs b/core/embed/rust/src/ui/display/loader/rectangular.rs deleted file mode 100644 index 7ad16c57f0..0000000000 --- a/core/embed/rust/src/ui/display/loader/rectangular.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::ui::{ - constant::{screen, LOADER_INNER}, - display, - display::{Color, Icon}, - geometry::{Offset, Rect}, -}; - -pub fn loader_rectangular( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - let area = Rect::from_center_and_size(screen().center(), Offset::uniform(LOADER_INNER as _)) - .translate(Offset::y(y_offset)); - - display::rect_rounded2_partial( - area, - fg_color, - bg_color, - (100 * progress as u32 / 1000) as i16, - icon, - ); -} diff --git a/core/embed/rust/src/ui/display/loader/small.rs b/core/embed/rust/src/ui/display/loader/small.rs deleted file mode 100644 index 0b1196f43b..0000000000 --- a/core/embed/rust/src/ui/display/loader/small.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::ui::{ - constant::screen, - display::{rect_fill, Color}, - geometry::{Offset, Point, Rect}, -}; -use core::f32::consts::SQRT_2; - -const STAR_COUNT: usize = 8; -const RADIUS: i16 = 3; -const DIAGONAL: i16 = ((RADIUS as f32 * SQRT_2) / 2_f32) as i16; -const LOADER_SIZE: Offset = Offset::uniform(2 * RADIUS + 3); - -fn fill_point(point: Point, color: Color) { - let area = Rect::from_center_and_size(point, Offset::uniform(1)); - rect_fill(area, color); -} - -pub fn loader_small_indeterminate(progress: u16, y_offset: i16, fg_color: Color, bg_color: Color) { - let area = - Rect::from_center_and_size(screen().center(), LOADER_SIZE).translate(Offset::y(y_offset)); - - rect_fill(area, bg_color); - - // Offset of the normal point and then the extra offset for the main point - let offsets: [(Offset, Offset); STAR_COUNT] = [ - (Offset::y(-RADIUS), Offset::y(-1)), - (Offset::new(DIAGONAL, -DIAGONAL), Offset::new(1, -1)), - (Offset::x(RADIUS), Offset::x(1)), - (Offset::new(DIAGONAL, DIAGONAL), Offset::new(1, 1)), - (Offset::y(RADIUS), Offset::y(1)), - (Offset::new(-DIAGONAL, DIAGONAL), Offset::new(-1, 1)), - (Offset::x(-RADIUS), Offset::x(-1)), - (Offset::new(-DIAGONAL, -DIAGONAL), Offset::new(-1, -1)), - ]; - - let main_idx = (STAR_COUNT * progress as usize / 1000) % STAR_COUNT; - - for (i, (point_offset, main_offset)) in offsets.iter().enumerate() { - // Skip it when it is behind the main one (clockwise) - if (main_idx + 1) % STAR_COUNT == i { - continue; - } - - // Draw the normal point - let point = area.center() + *point_offset; - fill_point(point, fg_color); - - // Draw the main point - if main_idx == i { - fill_point(point + *main_offset, fg_color); - } - } -} diff --git a/core/embed/rust/src/ui/display/loader/starry.rs b/core/embed/rust/src/ui/display/loader/starry.rs deleted file mode 100644 index 59e498552c..0000000000 --- a/core/embed/rust/src/ui/display/loader/starry.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::ui::{ - constant::{screen, LOADER_OUTER}, - display::{rect_fill, rect_fill_rounded, Color, Icon}, - geometry::{Alignment2D, Offset, Point, Rect}, -}; -use core::f32::consts::SQRT_2; - -const SIZE_SMALL: i16 = 2; -const SIZE_MEDIUM: i16 = 4; -const SIZE_LARGE: i16 = 6; -const RADIUS: i16 = 13; -const DIAGONAL: i16 = ((RADIUS as f32 * SQRT_2) / 2_f32) as i16; - -fn star_small(center: Point, fg: Color, _bg: Color) { - let r = Rect::from_center_and_size(center, Offset::uniform(SIZE_SMALL)); - rect_fill(r, fg); -} - -fn star_medium(center: Point, fg: Color, bg: Color) { - let r = Rect::from_center_and_size(center, Offset::uniform(SIZE_MEDIUM)); - rect_fill_rounded(r, fg, bg, 1); -} - -fn star_large(center: Point, fg: Color, bg: Color) { - let r = Rect::from_center_and_size(center, Offset::uniform(SIZE_LARGE)); - rect_fill_rounded(r, fg, bg, 2); -} - -pub fn loader_starry_indeterminate( - progress: u16, - y_offset: i16, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, -) { - let area = Rect::from_center_and_size(screen().center(), Offset::uniform(LOADER_OUTER as _)) - .translate(Offset::y(y_offset)); - - rect_fill(area, bg_color); - - let coords = [ - Point::new(area.center().x, area.center().y - RADIUS), - Point::new(area.center().x + DIAGONAL, area.center().y - DIAGONAL), - Point::new(area.center().x + RADIUS, area.center().y), - Point::new(area.center().x + DIAGONAL, area.center().y + DIAGONAL), - Point::new(area.center().x, area.center().y + RADIUS), - Point::new(area.center().x - DIAGONAL, area.center().y + DIAGONAL), - Point::new(area.center().x - RADIUS, area.center().y), - Point::new(area.center().x - DIAGONAL, area.center().y - DIAGONAL), - ]; - - let big_idx = (progress / 125) as usize % 8; - - for (i, c) in coords.iter().enumerate() { - if i == big_idx { - star_large(*c, fg_color, bg_color); - } else if (big_idx + 1) % 8 == i || (big_idx - 1) % 8 == i { - star_medium(*c, fg_color, bg_color); - } else { - star_small(*c, fg_color, bg_color); - } - } - - if let Some((icon, color)) = icon { - icon.draw(area.center(), Alignment2D::CENTER, color, bg_color); - } -} diff --git a/core/embed/rust/src/ui/display/mod.rs b/core/embed/rust/src/ui/display/mod.rs index 390c977eff..f2290fd316 100644 --- a/core/embed/rust/src/ui/display/mod.rs +++ b/core/embed/rust/src/ui/display/mod.rs @@ -1,53 +1,25 @@ pub mod color; pub mod font; pub mod image; -pub mod loader; -#[cfg(feature = "jpeg")] -pub mod tjpgd; pub mod toif; -use super::{ - constant, - geometry::{Offset, Point, Rect}, -}; -#[cfg(feature = "dma2d")] -use crate::trezorhal::{ - dma2d::{ - dma2d_setup_4bpp_over_16bpp, dma2d_setup_4bpp_over_4bpp, dma2d_start_blend, - dma2d_wait_for_transfer, - }, - uzlib::UZLIB_WINDOW_SIZE, -}; -#[cfg(feature = "dma2d")] -use crate::ui::component::image::Image; - -#[cfg(not(feature = "dma2d"))] -use crate::ui::geometry::Alignment2D; +use super::geometry::{Offset, Point, Rect}; #[cfg(feature = "backlight")] use crate::{time::Duration, trezorhal::time}; -use crate::{ - strutil::TString, - trezorhal::{buffers, display, uzlib::UzlibContext}, - ui::lerp::Lerp, -}; +use crate::{strutil::TString, trezorhal::display}; + +#[cfg(feature = "backlight")] +use crate::ui::lerp::Lerp; // Reexports -use crate::trezorhal::buffers::BufferText; pub use crate::ui::display::toif::Icon; pub use color::Color; pub use font::{Font, Glyph, GlyphMetrics}; -pub use loader::{ - loader, loader_indeterminate, loader_small_indeterminate, LOADER_MAX, LOADER_MIN, -}; -#[cfg(all(feature = "dma2d", feature = "framebuffer"))] -use crate::trezorhal::{ - display::{get_fb_addr, pixel}, - dma2d::{dma2d_setup_const, dma2d_start_const_multiline}, -}; -use crate::ui::constant::WIDTH; +pub const LOADER_MIN: u16 = 0; +pub const LOADER_MAX: u16 = 1000; pub fn backlight() -> u8 { display::backlight(-1) as u8 @@ -88,266 +60,6 @@ pub fn fade_backlight(_: u8) {} #[cfg(not(feature = "backlight"))] pub fn fade_backlight_duration(_: u8, _: u32) {} -#[cfg(not(feature = "framebuffer"))] -/// Fill a whole rectangle with a specific color. -pub fn rect_fill(r: Rect, fg_color: Color) { - let r = r.translate(get_offset()); - let r = r.clamp(constant::screen()); - - set_window(r); - - for _ in r.y0..r.y1 { - for _ in r.x0..r.x1 { - pixeldata(fg_color.into()); - } - } - - pixeldata_dirty(); -} - -#[cfg(feature = "framebuffer")] -pub fn rect_fill(r: Rect, fg_color: Color) { - let r = r.translate(get_offset()); - let r = r.clamp(constant::screen()); - set_window(r); - dma2d_setup_const(); - unsafe { - dma2d_start_const_multiline(fg_color.into(), r.width(), r.height()); - } - dma2d_wait_for_transfer(); - pixeldata_dirty(); -} - -pub fn rect_stroke(r: Rect, fg_color: Color) { - rect_fill( - Rect::from_top_left_and_size(Point::new(r.x0, r.y0), Offset::new(r.width(), 1)), - fg_color, - ); - rect_fill( - Rect::from_top_left_and_size( - Point::new(r.x0, r.y0 + r.height() - 1), - Offset::new(r.width(), 1), - ), - fg_color, - ); - rect_fill( - Rect::from_top_left_and_size(Point::new(r.x0, r.y0), Offset::new(1, r.height())), - fg_color, - ); - rect_fill( - Rect::from_top_left_and_size( - Point::new(r.x0 + r.width() - 1, r.y0), - Offset::new(1, r.height()), - ), - fg_color, - ); -} - -const CORNER_RADIUS: usize = 16; - -#[rustfmt::skip] -const CORNER_TABLE: [usize; CORNER_RADIUS * CORNER_RADIUS] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 9, 12, 14, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 3, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -]; - -/// Draw a rectangle with rounded corners. -#[cfg(not(feature = "framebuffer"))] -pub fn rect_fill_rounded(r: Rect, fg_color: Color, bg_color: Color, radius: u8) { - if radius == 1 { - rect_fill_rounded1(r, fg_color, bg_color); - } else { - assert!([2, 4, 8, 16].iter().any(|allowed| radius == *allowed)); - - let color_table = get_color_table(fg_color, bg_color); - let area = r.translate(get_offset()); - let clamped = area.clamp(constant::screen()); - - set_window(clamped); - - let radius = radius as i16; - let radius_inv = 16 / radius; - - for y in area.y0..area.y1 { - for x in area.x0..area.x1 { - if x - r.x0 < radius && y - r.y0 < radius { - let c = CORNER_TABLE[((x - area.x0) * radius_inv - + (y - area.y0) * radius_inv * CORNER_RADIUS as i16) - as usize]; - pixeldata(color_table[c]); - } else if x - r.x0 < radius && y - r.y0 >= r.height() - radius { - let c = CORNER_TABLE[((x - area.x0) * radius_inv - + (r.height() - 1 - (y - area.y0)) * radius_inv * CORNER_RADIUS as i16) - as usize]; - pixeldata(color_table[c]); - } else if x - r.x0 >= r.width() - radius && y - r.y0 < radius { - let c = CORNER_TABLE[((r.width() - 1 - (x - area.x0)) * radius_inv - + (y - area.y0) * radius_inv * CORNER_RADIUS as i16) - as usize]; - pixeldata(color_table[c]); - } else if x - r.x0 >= r.width() - radius && y - r.y0 >= r.height() - radius { - let c = CORNER_TABLE[((r.width() - 1 - (x - area.x0)) * radius_inv - + (r.height() - 1 - (y - area.y0)) * radius_inv * CORNER_RADIUS as i16) - as usize]; - pixeldata(color_table[c]); - } else { - pixeldata(color_table[15]); - } - } - } - } - pixeldata_dirty(); -} - -pub fn rect_fill_rounded_buffer(r: Rect, radius: u8, buffer: &mut BufferText) { - if r.height() > r.y0 + buffers::TEXT_BUFFER_HEIGHT as i16 || r.x0 + r.width() > WIDTH { - return; - } - - assert!([2, 4, 8, 16].iter().any(|allowed| radius == *allowed)); - - let radius = radius as i16; - let radius_inv = 16 / radius; - - for y in r.y0..r.y1 { - for x in r.x0..r.x1 { - let c = if x - r.x0 < radius && y - r.y0 < radius { - CORNER_TABLE[((x - r.x0) * radius_inv - + (y - r.y0) * radius_inv * CORNER_RADIUS as i16) - as usize] - } else if x - r.x0 < radius && y - r.y0 >= r.height() - radius { - CORNER_TABLE[((x - r.x0) * radius_inv - + (r.height() - 1 - (y - r.y0)) * radius_inv * CORNER_RADIUS as i16) - as usize] - } else if x - r.x0 >= r.width() - radius && y - r.y0 < radius { - CORNER_TABLE[((r.width() - 1 - (x - r.x0)) * radius_inv - + (y - r.y0) * radius_inv * CORNER_RADIUS as i16) - as usize] - } else if x - r.x0 >= r.width() - radius && y - r.y0 >= r.height() - radius { - CORNER_TABLE[((r.width() - 1 - (x - r.x0)) * radius_inv - + (r.height() - 1 - (y - r.y0)) * radius_inv * CORNER_RADIUS as i16) - as usize] - } else { - 15usize - }; - let p = y * WIDTH + x; - let b = (p / 2) as usize; - if p % 2 != 0 { - buffer.buffer[b] |= (c << 4) as u8; - } else { - buffer.buffer[b] |= c as u8; - } - } - } - pixeldata_dirty(); -} - -#[cfg(feature = "framebuffer")] -/// Draw a rectangle with rounded corners. -pub fn rect_fill_rounded(area: Rect, fg_color: Color, bg_color: Color, radius: u8) { - let radius = radius as i16; - if radius == 1 { - rect_fill_rounded1(area, fg_color, bg_color); - } else { - assert!([2, 4, 8, 16].iter().any(|allowed| radius == *allowed)); - - let r = area.translate(get_offset()); - let r = r.clamp(constant::screen()); - let fb = get_fb_addr(); - - rect_fill(r, fg_color); - let r_inv = 16 / radius; - let color_table = get_color_table(fg_color, bg_color); - - for y in 0..radius { - for x in 0..radius { - let c = CORNER_TABLE[(x * r_inv + y * r_inv * 16) as usize]; - pixel(fb, r.x0 + x, r.y0 + y, color_table[c].into()); - } - } - for y in 0..radius { - for x in 0..radius { - let c = CORNER_TABLE[((radius - x - 1) * r_inv + y * r_inv * 16) as usize]; - pixel(fb, r.x1 - radius + x, r.y0 + y, color_table[c].into()); - } - } - for y in 0..radius { - for x in 0..radius { - let c = CORNER_TABLE[(x * r_inv + (radius - y - 1) * r_inv * 16) as usize]; - pixel(fb, r.x0 + x, r.y1 - radius + y, color_table[c].into()); - } - } - for y in 0..radius { - for x in 0..radius { - let c = CORNER_TABLE - [((radius - x - 1) * r_inv + (radius - y - 1) * r_inv * 16) as usize]; - pixel( - fb, - r.x1 - radius + x, - r.y1 - radius + y, - color_table[c].into(), - ); - } - } - } - pixeldata_dirty(); -} - -/// Filling a rectangle with a rounding of 1 pixel - removing the corners. -fn rect_fill_rounded1(r: Rect, fg_color: Color, bg_color: Color) { - rect_fill(r, fg_color); - rect_fill_corners(r, bg_color); -} - -/// Creating a rectangular outline with a given radius/rounding. -pub fn rect_outline_rounded(r: Rect, fg_color: Color, bg_color: Color, radius: u8) { - // Painting a bigger rectangle with FG and inner smaller with BG - // to create the outline. - let inner_r = r.shrink(1); - if radius == 1 { - rect_fill_rounded(r, fg_color, bg_color, 1); - rect_fill(inner_r, bg_color); - rect_fill_corners(inner_r, fg_color); - } else if radius == 2 { - rect_fill_rounded(r, fg_color, bg_color, 2); - rect_fill_rounded(inner_r, bg_color, fg_color, 1); - } else if radius == 4 { - rect_fill_rounded(r, fg_color, bg_color, 4); - rect_fill_rounded(inner_r, bg_color, fg_color, 2); - rect_fill_corners(inner_r, bg_color); - } -} - -/// Filling all four corners of a rectangle with a given color. -pub fn rect_fill_corners(r: Rect, fg_color: Color) { - for p in r.corner_points().iter() { - // This draws a 1x1 rectangle at the given point. - rect_fill( - Rect::from_top_left_and_size(*p, Offset::uniform(1)), - fg_color, - ); - } -} - -/// Draw black rectangle over entire screen. -pub fn clear() { - display::clear(); -} - #[derive(Clone)] pub struct TextOverlay { area: Rect, @@ -389,760 +101,6 @@ impl TextOverlay { self.area = area; } - - pub fn get_pixel(&self, underlying: Color, fg: Color, p: Point) -> Color { - if !self.area.contains(p) { - return underlying; - } - - let mut tot_adv = 0; - - let p_rel = Point::new(p.x - self.area.x0, p.y - self.area.y0); - - let color = self.text.map(|t| { - for g in t.chars().map(|c| self.font.get_glyph(c)) { - let top = self.max_height - self.baseline - g.bearing_y; - let char_area = Rect::new( - Point::new(tot_adv + g.bearing_x, top), - Point::new(tot_adv + g.bearing_x + g.width, top + g.height), - ); - - tot_adv += g.adv; - - if !char_area.contains(p_rel) { - continue; - } - - let p_inner = p_rel - char_area.top_left(); - let overlay_data = g.get_pixel_data(p_inner); - return Some(Color::lerp(underlying, fg, overlay_data as f32 / 15_f32)); - } - None - }); - - color.unwrap_or(underlying) - } -} - -/// Performs a conversion from `angle` (in degrees) to a vector (`Point`) -/// (polar to cartesian transformation) -/// Suitable for cases where we don't care about distance, it is assumed 1000 -/// -/// The implementation could be replaced by (cos(`angle`), sin(`angle`)), -/// if we allow trigonometric functions. -/// In the meantime, approximate this with predefined octagon -fn get_vector(angle: i16) -> Point { - //octagon vertices - let v = [ - Point::new(0, 1000), - Point::new(707, 707), - Point::new(1000, 0), - Point::new(707, -707), - Point::new(0, -1000), - Point::new(-707, -707), - Point::new(-1000, 0), - Point::new(-707, 707), - ]; - - let angle = angle % 360; - let vertices = v.len() as i16; - let sector_length = 360 / vertices; // only works if 360 is divisible by vertices - let sector = angle / sector_length; - let sector_angle = (angle % sector_length) as f32; - let v1 = v[sector as usize]; - let v2 = v[((sector + 1) % vertices) as usize]; - Point::lerp(v1, v2, sector_angle / sector_length as f32) -} - -/// Find whether vector `v2` is clockwise to another vector v1 -/// `n_v1` is counter clockwise normal vector to v1 -/// ( if v1=(x1,y1), then the counter-clockwise normal is n_v1=(-y1,x1) -#[inline(always)] -fn is_clockwise_or_equal(n_v1: Point, v2: Point) -> bool { - let psize = v2.x as i32 * n_v1.x as i32 + v2.y as i32 * n_v1.y as i32; - psize < 0 -} - -/// Find whether vector v2 is clockwise or equal to another vector v1 -/// `n_v1` is counter clockwise normal vector to v1 -/// ( if v1=(x1,y1), then the counter-clockwise normal is n_v1=(-y1,x1) -#[inline(always)] -fn is_clockwise_or_equal_inc(n_v1: Point, v2: Point) -> bool { - let psize = v2.x as i32 * n_v1.x as i32 + v2.y as i32 * n_v1.y as i32; - psize <= 0 -} - -/// Draw a rounded rectangle with corner radius 2 -/// Draws only a part (sector of a corresponding circle) -/// of the rectangle according to `show_percent` argument, -/// and optionally draw an `icon` inside -pub fn rect_rounded2_partial( - area: Rect, - fg_color: Color, - bg_color: Color, - show_percent: i16, - icon: Option<(Icon, Color)>, -) { - const MAX_ICON_SIZE: i16 = 64; - - let r = area.translate(get_offset()); - let clamped = r.clamp(constant::screen()); - - set_window(clamped); - - let center = r.center(); - let colortable = get_color_table(fg_color, bg_color); - let mut icon_colortable = colortable; - - let mut use_icon = false; - let mut icon_area = Rect::zero(); - let mut icon_area_clamped = Rect::zero(); - let mut icon_data = [0_u8; ((MAX_ICON_SIZE * MAX_ICON_SIZE) / 2) as usize]; - let mut icon_width = 0; - - if let Some((icon, icon_color)) = icon { - let icon_size = icon.toif.size(); - if icon_size.x <= MAX_ICON_SIZE && icon_size.y <= MAX_ICON_SIZE { - icon_area = Rect::from_center_and_size(center, icon_size); - icon_area_clamped = icon_area.clamp(constant::screen()); - icon.toif.uncompress(&mut icon_data); - icon_colortable = get_color_table(icon_color, bg_color); - icon_width = icon.toif.width(); - use_icon = true; - } - } - - let start = 0; - let end = (start + (360 * show_percent as u32) / 100) % 360; - - let start_vector; - let end_vector; - - let mut show_all = false; - let mut inverted = false; - - if show_percent >= 100 { - show_all = true; - start_vector = Point::zero(); - end_vector = Point::zero(); - } else if show_percent > 50 { - inverted = true; - start_vector = get_vector(end as _); - end_vector = get_vector(start as _); - } else { - start_vector = get_vector(start as _); - end_vector = get_vector(end as _); - } - - let n_start = Point::new(-start_vector.y, start_vector.x); - - for y_c in r.y0..r.y1 { - for x_c in r.x0..r.x1 { - let p = Point::new(x_c, y_c); - - let mut icon_pixel = false; - if use_icon && icon_area_clamped.contains(p) { - let x_i = p.x - icon_area.x0; - let y_i = p.y - icon_area.y0; - - let data = icon_data[(((x_i & 0xFE) + (y_i * icon_width)) / 2) as usize]; - if (x_i & 0x01) == 0 { - pixeldata(icon_colortable[(data & 0xF) as usize]); - } else { - pixeldata(icon_colortable[(data >> 4) as usize]); - } - icon_pixel = true; - } - - if !clamped.contains(p) || icon_pixel { - continue; - } - - let y_p = -(p.y - center.y); - let x_p = p.x - center.x; - - let vx = Point::new(x_p, y_p); - let n_vx = Point::new(-y_p, x_p); - - let is_past_start = is_clockwise_or_equal(n_start, vx); - let is_before_end = is_clockwise_or_equal_inc(n_vx, end_vector); - - if show_all - || (!inverted && (is_past_start && is_before_end)) - || (inverted && !(is_past_start && is_before_end)) - { - let p_b = p - r.top_left(); - let c = rect_rounded2_get_pixel(p_b, r.size(), colortable, false, 2); - pixeldata(c); - } else { - pixeldata(bg_color); - } - } - } - - pixeldata_dirty(); -} - -/// Shifts position of pixel data in `src_buffer` horizontally by `offset_x` -/// pixels and places the result into `dest_buffer`. Or in another words, -/// `src_buffer[n]` is copied into `dest_buffer[n+offset_x]`, if it fits the -/// `dest_buffer`. -/// -/// Buffers hold one line of pixels on the screen, the copying is limited to -/// respect the size of screen. -/// -/// `buffer_bpp` determines size of pixel data -/// `data_width` sets the width of valid data in the `src_buffer` -pub(crate) fn position_buffer( - dest_buffer: &mut [u8], - src_buffer: &[u8], - buffer_bpp: usize, - offset_x: i16, - data_width: i16, -) { - let data_width_even = if buffer_bpp == 4 && data_width % 2 != 0 { - data_width + 1 - } else { - data_width - }; - - let mut start: usize = (offset_x).clamp(0, constant::WIDTH) as usize; - let mut end: usize = (offset_x + data_width_even).clamp(0, constant::WIDTH) as usize; - - if buffer_bpp == 4 { - start &= !0x01; - end &= !0x01; - } - - let width = end - start; - - // if the offset is negative, need to skip beginning of uncompressed data - let x_sh = if offset_x < 0 { - (-offset_x).clamp(0, constant::WIDTH - width as i16) as usize - } else { - 0 - }; - dest_buffer[((start * buffer_bpp) / 8)..((start + width) * buffer_bpp) / 8] - .copy_from_slice(&src_buffer[((x_sh * buffer_bpp) / 8)..((x_sh + width) * buffer_bpp) / 8]); -} - -/// Performs decompression of one line of pixels, -/// vertically positions the line against the display area (current position of -/// which is described by `display_area_y`) by skipping relevant number of lines -/// and finally horizontally positions the line against the display area -/// by calling `position_buffer`. -/// -/// Number of already decompressed lines is stored in `decompressed_lines` to -/// keep track of how many need to be skipped. -/// -/// Signals to the caller whether some data should be drawn on this line. -fn process_buffer( - display_area_y: i16, - img_area: Rect, - offset: Offset, - ctx: &mut UzlibContext, - buffer: &mut [u8], - decompressed_lines: &mut i16, - buffer_bpp: usize, -) -> bool { - let mut not_empty = false; - let uncomp_buffer = - &mut [0u8; (constant::WIDTH * 2) as usize][..((constant::WIDTH as usize) * buffer_bpp) / 8]; - - if display_area_y >= img_area.y0 && display_area_y < img_area.y1 { - let img_line_idx = display_area_y - img_area.y0; - - while *decompressed_lines < img_line_idx { - //compensate uncompressed unused lines - unwrap!( - ctx.uncompress( - &mut uncomp_buffer[0..((img_area.width() * buffer_bpp as i16) / 8) as usize] - ), - "Decompression failed" - ); - - (*decompressed_lines) += 1; - } - // decompress whole line - unwrap!( - ctx.uncompress( - &mut uncomp_buffer[0..((img_area.width() * buffer_bpp as i16) / 8) as usize] - ), - "Decompression failed" - ); - - (*decompressed_lines) += 1; - - position_buffer( - buffer, - uncomp_buffer, - buffer_bpp, - offset.x, - img_area.width(), - ); - - not_empty = true; - } - - not_empty -} - -/// Renders text over image background -/// If `bg_area` is given, it is filled with its color in places where there are -/// neither text or image Positioning also depends on whether `bg_area` is -/// provided: -/// - if it is, text and image are positioned relative to the `bg_area` top left -/// corner, using respective offsets. Nothing is drawn outside the `bg_area`. -/// - if it is not, text is positioned relative to the images top left corner -/// using `offset_text` and image is positioned on the screen using -/// `offset_img`. Nothing is drawn outside the image. -/// `offset_text` is interpreted as baseline, so using (0,0) will position most -/// of the text outside the drawing area in either case. -/// -/// The drawing area is coerced to even width, which is due to dma2d limitation -/// when using 4bpp -#[cfg(feature = "dma2d")] -pub fn text_over_image( - bg_area: Option<(Rect, Color)>, - image: Image, - text: &str, - font: Font, - offset_img: Offset, - offset_text: Offset, - text_color: Color, -) { - let mut text_buffer = buffers::BufferText::get(); - let mut img1 = buffers::BufferLine16bpp::get_cleared(); - let mut img2 = buffers::BufferLine16bpp::get_cleared(); - let mut empty_img = buffers::BufferLine16bpp::get_cleared(); - let mut t1 = buffers::BufferLine4bpp::get_cleared(); - let mut t2 = buffers::BufferLine4bpp::get_cleared(); - let mut empty_t = buffers::BufferLine4bpp::get_cleared(); - - let r_img; - let area; - let offset_img_final; - if let Some((a, color)) = bg_area { - let hi = color.hi_byte(); - let lo = color.lo_byte(); - //prefill image/bg buffers with the bg color - for i in 0..(constant::WIDTH) as usize { - img1.buffer[2 * i] = lo; - img1.buffer[2 * i + 1] = hi; - } - img2.buffer.copy_from_slice(&img1.buffer); - empty_img.buffer.copy_from_slice(&img1.buffer); - - area = a; - r_img = Rect::from_top_left_and_size(a.top_left() + offset_img, image.toif.size()); - offset_img_final = offset_img; - } else { - area = Rect::from_top_left_and_size(offset_img.into(), image.toif.size()); - r_img = area; - offset_img_final = Offset::zero(); - } - let clamped = area.clamp(constant::screen()).ensure_even_width(); - - let text_width = display::text_width(text, font.into()); - let font_max_height = display::text_max_height(font.into()); - let font_baseline = display::text_baseline(font.into()); - let text_width_clamped = text_width.clamp(0, clamped.width()); - - let text_top = area.y0 + offset_text.y - font_max_height + font_baseline; - let text_bottom = area.y0 + offset_text.y + font_baseline; - let text_left = area.x0 + offset_text.x; - let text_right = area.x0 + offset_text.x + text_width_clamped; - - let text_area = Rect::new( - Point::new(text_left, text_top), - Point::new(text_right, text_bottom), - ); - - display::text_into_buffer(text, font.into(), &mut text_buffer, 0); - - set_window(clamped); - - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut ctx = image.toif.decompression_context(Some(&mut window)); - - dma2d_setup_4bpp_over_16bpp(text_color.into()); - - let mut i = 0; - - for y in clamped.y0..clamped.y1 { - let mut img_buffer = &mut *empty_img; - let mut t_buffer = &mut *empty_t; - let img_buffer_used; - let t_buffer_used; - - if y % 2 == 0 { - t_buffer_used = &mut *t1; - img_buffer_used = &mut *img1; - } else { - t_buffer_used = &mut *t2; - img_buffer_used = &mut *img2; - } - - let using_img = process_buffer( - y, - r_img, - offset_img_final, - &mut ctx, - &mut img_buffer_used.buffer, - &mut i, - 16, - ); - - if y >= text_area.y0 && y < text_area.y1 { - let y_pos = y - text_area.y0; - position_buffer( - &mut t_buffer_used.buffer, - &text_buffer.buffer[(y_pos * constant::WIDTH / 2) as usize - ..((y_pos + 1) * constant::WIDTH / 2) as usize], - 4, - offset_text.x, - text_width, - ); - t_buffer = t_buffer_used; - } - - if using_img { - img_buffer = img_buffer_used; - } - - dma2d_wait_for_transfer(); - unsafe { dma2d_start_blend(&t_buffer.buffer, &img_buffer.buffer, clamped.width()) }; - } - - dma2d_wait_for_transfer(); -} - -/// Renders text over image background -/// If `bg_area` is given, it is filled with its color in places where there is -/// neither icon. Positioning also depends on whether `bg_area` is provided: -/// - if it is, icons are positioned relative to the `bg_area` top left corner, -/// using respective offsets. Nothing is drawn outside the `bg_area`. -/// - if it is not, `fg` icon is positioned relative to the `bg` icons top left -/// corner using its offset and `fg` icon is positioned on the screen using -/// its offset. Nothing is drawn outside the `bg` icon. -/// -/// The drawing area is coerced to even width, which is due to dma2d limitation -/// when using 4bpp -#[cfg(feature = "dma2d")] -pub fn icon_over_icon( - bg_area: Option, - bg: (Icon, Offset, Color), - fg: (Icon, Offset, Color), - bg_color: Color, -) { - let mut bg1 = buffers::BufferLine16bpp::get_cleared(); - let mut bg2 = buffers::BufferLine16bpp::get_cleared(); - let mut empty1 = buffers::BufferLine16bpp::get_cleared(); - let mut fg1 = buffers::BufferLine4bpp::get_cleared(); - let mut fg2 = buffers::BufferLine4bpp::get_cleared(); - let mut empty2 = buffers::BufferLine4bpp::get_cleared(); - - let (icon_bg, offset_bg, color_icon_bg) = bg; - let (icon_fg, offset_fg, color_icon_fg) = fg; - - assert!(icon_bg.toif.width() <= constant::WIDTH); - assert_eq!(icon_bg.toif.width() % 2, 0); - - assert!(icon_fg.toif.width() <= constant::WIDTH); - assert_eq!(icon_fg.toif.width() % 2, 0); - - let area; - let r_bg; - let final_offset_bg; - if let Some(a) = bg_area { - area = a; - r_bg = Rect::from_top_left_and_size(a.top_left() + offset_bg, icon_bg.toif.size()); - final_offset_bg = offset_bg; - } else { - r_bg = - Rect::from_top_left_and_size(Point::new(offset_bg.x, offset_bg.y), icon_bg.toif.size()); - area = r_bg; - final_offset_bg = Offset::zero(); - } - - let r_fg = Rect::from_top_left_and_size(area.top_left() + offset_fg, icon_fg.toif.size()); - - let clamped = area.clamp(constant::screen()).ensure_even_width(); - - set_window(clamped); - - let mut window_bg = [0; UZLIB_WINDOW_SIZE]; - let mut ctx_bg = UzlibContext::new(icon_bg.toif.zdata(), Some(&mut window_bg)); - - let mut window_fg = [0; UZLIB_WINDOW_SIZE]; - let mut ctx_fg = UzlibContext::new(icon_fg.toif.zdata(), Some(&mut window_fg)); - - dma2d_setup_4bpp_over_4bpp(color_icon_bg.into(), bg_color.into(), color_icon_fg.into()); - - let mut fg_i = 0; - let mut bg_i = 0; - - for y in clamped.y0..clamped.y1 { - let mut fg_buffer = &mut *empty2; - let mut bg_buffer = &mut *empty1; - let fg_buffer_used; - let bg_buffer_used; - - if y % 2 == 0 { - fg_buffer_used = &mut *fg1; - bg_buffer_used = &mut *bg1; - } else { - fg_buffer_used = &mut *fg2; - bg_buffer_used = &mut *bg2; - } - - let using_fg = process_buffer( - y, - r_fg, - offset_fg, - &mut ctx_fg, - &mut fg_buffer_used.buffer, - &mut fg_i, - 4, - ); - let using_bg = process_buffer( - y, - r_bg, - final_offset_bg, - &mut ctx_bg, - &mut bg_buffer_used.buffer, - &mut bg_i, - 4, - ); - - if using_fg { - fg_buffer = fg_buffer_used; - } - if using_bg { - bg_buffer = bg_buffer_used; - } - - dma2d_wait_for_transfer(); - unsafe { dma2d_start_blend(&fg_buffer.buffer, &bg_buffer.buffer, clamped.width()) }; - } - - dma2d_wait_for_transfer(); -} - -#[cfg(not(feature = "dma2d"))] -pub fn icon_over_icon( - bg_area: Option, - bg: (Icon, Offset, Color), - fg: (Icon, Offset, Color), - bg_color: Color, -) { - let (icon_bg, offset_bg, color_icon_bg) = bg; - let (icon_fg, offset_fg, color_icon_fg) = fg; - - let pos_bg = if let Some(area) = bg_area { - rect_fill(area, bg_color); - area.top_left() + offset_bg - } else { - Point::from(offset_bg) - }; - - icon_bg.draw(pos_bg, Alignment2D::TOP_LEFT, color_icon_bg, bg_color); - icon_fg.draw( - pos_bg + offset_fg, - Alignment2D::TOP_LEFT, - color_icon_fg, - color_icon_bg, - ); -} - -/// Gets a color of a pixel on `p` coordinates of rounded rectangle with corner -/// radius 2 -fn rect_rounded2_get_pixel( - p: Offset, - size: Offset, - colortable: [Color; 16], - fill: bool, - line_width: i16, -) -> Color { - let border = (p.x >= 0 && p.x < line_width) - || ((p.x >= size.x - line_width) && p.x <= (size.x - 1)) - || (p.y >= 0 && p.y < line_width) - || ((p.y >= size.y - line_width) && p.y <= (size.y - 1)); - - let corner_lim = 2 * line_width; - let corner_inner = line_width; - - let corner_all = ((p.x > size.x - (corner_lim + 1)) || p.x < corner_lim) - && (p.y < corner_lim || p.y > size.y - (corner_lim + 1)); - - let corner = corner_all - && (p.y >= corner_inner) - && (p.x >= corner_inner) - && (p.y <= size.y - (corner_inner + 1)) - && (p.x <= size.x - (corner_inner + 1)); - - let corner_out = corner_all && !corner; - - if (border || corner || fill) && !corner_out { - colortable[15] - } else { - colortable[0] - } -} - -/// Draws a rounded rectangle with corner radius 2, partially filled -/// according to `fill_from` and `fill_to` arguments. -/// Optionally draws a text inside the rectangle and adjusts its color to match -/// the fill. The coordinates of the text are specified in the TextOverlay -/// struct. -pub fn bar_with_text_and_fill( - area: Rect, - overlay: Option<&TextOverlay>, - fg_color: Color, - bg_color: Color, - fill_from: i16, - fill_to: i16, -) { - let r = area.translate(get_offset()); - let clamped = r.clamp(constant::screen()); - let colortable = get_color_table(fg_color, bg_color); - - set_window(clamped); - - for y_c in clamped.y0..clamped.y1 { - for x_c in clamped.x0..clamped.x1 { - let p = Point::new(x_c, y_c); - let r_offset = p - r.top_left(); - - let filled = (r_offset.x >= fill_from - && fill_from >= 0 - && (r_offset.x <= fill_to || fill_to < fill_from)) - || (r_offset.x < fill_to && fill_to >= 0); - - let underlying_color = - rect_rounded2_get_pixel(r_offset, r.size(), colortable, filled, 1); - - let final_color = overlay.map_or(underlying_color, |o| { - let text_color = if filled { bg_color } else { fg_color }; - o.get_pixel(underlying_color, text_color, p) - }); - - pixeldata(final_color); - } - } - pixeldata_dirty(); -} - -pub fn marquee(area: Rect, text: &str, offset: i16, font: Font, fg: Color, bg: Color) { - let mut buffer = buffers::BufferText::get_cleared(); - - let area = area.translate(get_offset()); - let clamped = area.clamp(constant::screen()); - set_window(clamped); - - display::text_into_buffer(text, font.into(), &mut buffer, offset); - let tbl = get_color_table(fg, bg); - - for y in 0..clamped.height() { - for x in 0..clamped.width() { - let pixel = y as usize * constant::WIDTH as usize + x as usize; - let byte_idx = pixel / 2; - if byte_idx < buffer.buffer.len() as _ { - let data = if pixel % 2 != 0 { - buffer.buffer[byte_idx] >> 4 - } else { - buffer.buffer[byte_idx] & 0xF - }; - pixeldata(tbl[data as usize]); - } else { - pixeldata(bg); - } - } - } - - pixeldata_dirty(); -} - -pub fn dotted_line(start: Point, width: i16, color: Color, step: i16) { - for x in (start.x..width).step_by(step as usize) { - rect_fill( - Rect::from_top_left_and_size(Point::new(x, start.y), Offset::new(1, 1)), - color, - ); - } -} - -/// Display text left-aligned to a certain Point -pub fn text_left(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) { - display::text( - baseline.x, - baseline.y, - text, - font.into(), - fg_color.into(), - bg_color.into(), - ); -} - -/// Display text centered around a certain Point -pub fn text_center(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) { - let w = font.text_width(text); - display::text( - baseline.x - w / 2, - baseline.y, - text, - font.into(), - fg_color.into(), - bg_color.into(), - ); -} - -/// Display text right-aligned to a certain Point -pub fn text_right(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) { - let w = font.text_width(text); - display::text( - baseline.x - w, - baseline.y, - text, - font.into(), - fg_color.into(), - bg_color.into(), - ); -} - -pub fn text_top_left(position: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) { - let h = font.text_height(); - display::text( - position.x, - position.y + h, - text, - font.into(), - fg_color.into(), - bg_color.into(), - ); -} - -#[inline(always)] -pub fn pixeldata(color: Color) { - display::pixeldata(color.into()); -} - -pub fn pixeldata_dirty() { - display::pixeldata_dirty(); -} - -pub fn get_offset() -> Offset { - let offset = display::get_offset(); - Offset::new(offset.0, offset.1) -} - -pub fn set_window(window: Rect) { - display::set_window( - window.x0 as u16, - window.y0 as u16, - window.x1 as u16 - 1, - window.y1 as u16 - 1, - ); } pub fn sync() { @@ -1152,13 +110,3 @@ pub fn sync() { pub fn refresh() { display::refresh(); } - -pub fn get_color_table(fg_color: Color, bg_color: Color) -> [Color; 16] { - let mut table: [Color; 16] = [Color::from_u16(0); 16]; - - for (i, item) in table.iter_mut().enumerate() { - *item = Color::lerp(bg_color, fg_color, i as f32 / 15_f32); - } - - table -} diff --git a/core/embed/rust/src/ui/display/tjpgd.rs b/core/embed/rust/src/ui/display/tjpgd.rs deleted file mode 100644 index 734cad50c9..0000000000 --- a/core/embed/rust/src/ui/display/tjpgd.rs +++ /dev/null @@ -1,159 +0,0 @@ -use trezor_tjpgdec::{BlackHoleOutput, JpegOutput}; -pub use trezor_tjpgdec::{BufferInput, Error, JDEC}; - -use crate::{ - trezorhal::{ - buffers::{BufferJpeg, BufferJpegWork}, - display::pixeldata, - }, - ui::{ - constant, - display::set_window, - geometry::{Offset, Point, Rect}, - }, -}; - -pub fn jpeg(data: &[u8], pos: Point, scale: u8) { - let mut buffer = BufferJpegWork::get_cleared(); - let pool = buffer.buffer.as_mut_slice(); - let mut out = PixelDataOutput(pos); - let mut inp = BufferInput(data); - if let Ok(mut jd) = JDEC::new(&mut inp, pool) { - let _ = jd.set_scale(scale); - let _ = jd.decomp(&mut inp, &mut out); - } -} - -pub fn jpeg_info(data: &[u8]) -> Option<(Offset, i16)> { - let mut buffer = BufferJpegWork::get_cleared(); - let pool = buffer.buffer.as_mut_slice(); - let mut inp = BufferInput(data); - let result = if let Ok(jd) = JDEC::new(&mut inp, pool) { - let mcu_height = jd.mcu_height(); - if mcu_height > 16 { - return None; - } - Some((Offset::new(jd.width(), jd.height()), mcu_height)) - } else { - None - }; - result -} - -pub fn jpeg_test(data: &[u8]) -> bool { - let mut buffer = BufferJpegWork::get_cleared(); - let pool = buffer.buffer.as_mut_slice(); - let mut inp = BufferInput(data); - let result = if let Ok(mut jd) = JDEC::new(&mut inp, pool) { - if jd.mcu_height() > 16 { - return false; - } - - let mut out = BlackHoleOutput; - let mut res = jd.decomp(&mut inp, &mut out); - while res == Err(Error::Interrupted) { - res = jd.decomp(&mut inp, &mut out); - } - res.is_ok() - } else { - false - }; - result -} - -pub struct BufferOutput { - buffer: BufferJpeg, - buffer_width: i16, - buffer_height: i16, - current_line: i16, - current_line_pix: i16, -} - -impl BufferOutput { - pub fn new(buffer_width: i16, buffer_height: i16) -> Self { - Self { - buffer: BufferJpeg::get_cleared(), - buffer_width, - buffer_height, - current_line: 0, - current_line_pix: 0, - } - } - - pub fn buffer(&mut self) -> &mut BufferJpeg { - &mut self.buffer - } -} - -impl JpegOutput for BufferOutput { - fn write( - &mut self, - jd: &JDEC, - rect_origin: (u32, u32), - rect_size: (u32, u32), - bitmap: &[u16], - ) -> bool { - let w = rect_size.0 as i16; - let h = rect_size.1 as i16; - let x = rect_origin.0 as i16; - - if h > self.buffer_height { - // unsupported height, call and let know - return true; - } - - let buffer_len = (self.buffer_width * self.buffer_height) as usize; - - for i in 0..h { - for j in 0..w { - let buffer_pos = ((x + j) + (i * self.buffer_width)) as usize; - if buffer_pos < buffer_len { - self.buffer.buffer[buffer_pos] = bitmap[(i * w + j) as usize]; - } - } - } - - self.current_line_pix += w; - - if self.current_line_pix >= jd.width() { - self.current_line_pix = 0; - self.current_line += jd.mcu_height(); - // finished line, abort and continue later - return false; - } - - true - } -} - -pub struct PixelDataOutput(Point); - -impl JpegOutput for PixelDataOutput { - fn write( - &mut self, - _jd: &JDEC, - rect_origin: (u32, u32), - rect_size: (u32, u32), - bitmap: &[u16], - ) -> bool { - let pos = self.0; - let rect = Rect::from_top_left_and_size( - Point::new(rect_origin.0 as i16, rect_origin.1 as i16), - Offset::new(rect_size.0 as i16, rect_size.1 as i16), - ); - let r = rect.translate(pos.into()); - let clamped = r.clamp(constant::screen()); - set_window(clamped); - for py in r.y0..r.y1 { - for px in r.x0..r.x1 { - let p = Point::new(px, py); - if clamped.contains(p) { - let off = p - r.top_left(); - let c = bitmap[(off.y * rect.width() + off.x) as usize]; - pixeldata(c); - } - } - } - true - } -} diff --git a/core/embed/rust/src/ui/display/toif.rs b/core/embed/rust/src/ui/display/toif.rs index eff8808921..9dea8365c4 100644 --- a/core/embed/rust/src/ui/display/toif.rs +++ b/core/embed/rust/src/ui/display/toif.rs @@ -1,33 +1,8 @@ use crate::{ error::{value_error, Error}, - trezorhal::uzlib::{UzlibContext, UZLIB_WINDOW_SIZE}, - ui::{ - component::image::Image, - constant, - display::{get_offset, pixeldata_dirty, set_window}, - geometry::{Alignment2D, Offset, Point, Rect}, - }, + ui::geometry::Offset, }; -#[cfg(feature = "dma2d")] -use crate::{ - trezorhal::{ - buffers::BufferLine16bpp, - dma2d::{dma2d_setup_16bpp, dma2d_start, dma2d_wait_for_transfer}, - }, - ui::display::process_buffer, -}; - -#[cfg(not(feature = "framebuffer"))] -use crate::ui::display::{get_color_table, pixeldata}; - -#[cfg(feature = "framebuffer")] -use crate::trezorhal::{buffers::BufferLine4bpp, dma2d::dma2d_setup_4bpp}; -#[cfg(feature = "framebuffer")] -use core::cmp::max; - -use super::Color; - const TOIF_HEADER_LENGTH: usize = 12; #[derive(PartialEq, Debug, Eq, FromPrimitive, Clone, Copy)] @@ -38,160 +13,6 @@ pub enum ToifFormat { GrayScaleEH = 3, // even hi } -pub fn render_icon(icon: &Icon, center: Point, fg_color: Color, bg_color: Color) { - render_toif(&icon.toif, center, fg_color, bg_color); -} - -#[cfg(not(feature = "framebuffer"))] -pub fn render_toif(toif: &Toif, center: Point, fg_color: Color, bg_color: Color) { - let r = Rect::from_center_and_size(center, toif.size()); - let area = r.translate(get_offset()); - let clamped = area.clamp(constant::screen()); - let colortable = get_color_table(fg_color, bg_color); - - set_window(clamped); - - let mut dest = [0_u8; 1]; - - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut ctx = toif.decompression_context(Some(&mut window)); - - for py in area.y0..area.y1 { - for px in area.x0..area.x1 { - let p = Point::new(px, py); - let x = p.x - area.x0; - - if clamped.contains(p) { - if x % 2 == 0 { - unwrap!(ctx.uncompress(&mut dest), "Decompression failed"); - pixeldata(colortable[(dest[0] & 0xF) as usize]); - } else { - pixeldata(colortable[(dest[0] >> 4) as usize]); - } - } else if x % 2 == 0 { - //continue unzipping but dont write to display - unwrap!(ctx.uncompress(&mut dest), "Decompression failed"); - } - } - } - - pixeldata_dirty(); -} - -#[cfg(feature = "framebuffer")] -pub fn render_toif(toif: &Toif, center: Point, fg_color: Color, bg_color: Color) { - let r = Rect::from_center_and_size(center, toif.size()); - let area = r.translate(get_offset()); - let clamped = area.clamp(constant::screen()).ensure_even_width(); - - set_window(clamped); - - let mut b1 = BufferLine4bpp::get_cleared(); - let mut b2 = BufferLine4bpp::get_cleared(); - - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut ctx = toif.decompression_context(Some(&mut window)); - - dma2d_setup_4bpp(fg_color.into(), bg_color.into()); - - let x_shift = max(0, clamped.x0 - area.x0); - - for y in area.y0..clamped.y1 { - let img_buffer_used = if y % 2 == 0 { &mut b1 } else { &mut b2 }; - - unwrap!(ctx.uncompress(&mut (&mut img_buffer_used.buffer)[..(area.width() / 2) as usize])); - - if y >= clamped.y0 { - dma2d_wait_for_transfer(); - unsafe { - dma2d_start( - &img_buffer_used.buffer - [(x_shift / 2) as usize..((clamped.width() + x_shift) / 2) as usize], - clamped.width(), - ) - }; - } - } - - dma2d_wait_for_transfer(); - pixeldata_dirty(); -} - -#[cfg(feature = "dma2d")] -pub fn image(image: &Image, center: Point) { - let r = Rect::from_center_and_size(center, image.toif.size()); - let area = r.translate(get_offset()); - let clamped = area.clamp(constant::screen()); - - set_window(clamped); - - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut ctx = image.toif.decompression_context(Some(&mut window)); - - let mut b1 = BufferLine16bpp::get_cleared(); - let mut b2 = BufferLine16bpp::get_cleared(); - - let mut decompressed_lines = 0; - let clamp_x = if clamped.x0 > area.x0 { - area.x0 - clamped.x0 - } else { - 0 - }; - - dma2d_setup_16bpp(); - - for y in clamped.y0..clamped.y1 { - let img_buffer_used = if y % 2 == 0 { &mut b1 } else { &mut b2 }; - - process_buffer( - y, - area, - Offset::x(clamp_x), - &mut ctx, - &mut img_buffer_used.buffer, - &mut decompressed_lines, - 16, - ); - - dma2d_wait_for_transfer(); - unsafe { dma2d_start(&img_buffer_used.buffer, clamped.width()) }; - } - - dma2d_wait_for_transfer(); - pixeldata_dirty(); -} - -#[cfg(not(feature = "dma2d"))] -pub fn image(image: &Image, center: Point) { - let r = Rect::from_center_and_size(center, image.toif.size()); - let area = r.translate(get_offset()); - let clamped = area.clamp(constant::screen()); - - set_window(clamped); - - let mut dest = [0_u8; 2]; - - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut ctx = image.toif.decompression_context(Some(&mut window)); - - for py in area.y0..area.y1 { - for px in area.x0..area.x1 { - let p = Point::new(px, py); - - if clamped.contains(p) { - unwrap!(ctx.uncompress(&mut dest), "Decompression failed"); - let c = Color::from_u16(u16::from_le_bytes(dest)); - pixeldata(c); - } else { - //continue unzipping but dont write to display - unwrap!(ctx.uncompress(&mut dest), "Decompression failed"); - } - } - } - - pixeldata_dirty(); -} - /// Holding toif data and allowing it to draw itself. /// See https://docs.trezor.io/trezor-firmware/misc/toif.html for data format. #[derive(PartialEq, Eq, Clone, Copy)] @@ -259,14 +80,6 @@ impl<'i> Toif<'i> { Offset::new(self.width(), self.height()) } - pub fn stride(&self) -> usize { - if self.is_grayscale() { - (self.width() + 1) as usize / 2 - } else { - self.width() as usize * 2 - } - } - pub fn zdata(&self) -> &'i [u8] { &self.data[TOIF_HEADER_LENGTH..] } @@ -274,25 +87,6 @@ impl<'i> Toif<'i> { pub fn original_data(&self) -> &'i [u8] { self.data } - - pub fn uncompress(&self, dest: &mut [u8]) { - let mut ctx = self.decompression_context(None); - unwrap!(ctx.uncompress(dest)); - } - - pub fn decompression_context<'a>( - &'a self, - window: Option<&'a mut [u8; UZLIB_WINDOW_SIZE]>, - ) -> UzlibContext { - UzlibContext::new(self.zdata(), window) - } - - /// Display the data with baseline Point, aligned according to the - /// `alignment` argument. - pub fn draw(&self, baseline: Point, alignment: Alignment2D, fg_color: Color, bg_color: Color) { - let r = Rect::snap(baseline, self.size(), alignment); - render_toif(self, r.center(), fg_color, bg_color); - } } #[derive(PartialEq, Eq, Clone, Copy)] @@ -330,11 +124,4 @@ impl Icon { ..Self::new(data) } } - - /// Display the icon with baseline Point, aligned according to the - /// `alignment` argument. - pub fn draw(&self, baseline: Point, alignment: Alignment2D, fg_color: Color, bg_color: Color) { - let r = Rect::snap(baseline, self.toif.size(), alignment); - render_icon(self, r.center(), fg_color, bg_color); - } } diff --git a/core/embed/rust/src/ui/flow/page.rs b/core/embed/rust/src/ui/flow/page.rs index e99f6d1ec5..f2d3e7ba4b 100644 --- a/core/embed/rust/src/ui/flow/page.rs +++ b/core/embed/rust/src/ui/flow/page.rs @@ -93,10 +93,6 @@ impl Component for SwipePage { self.inner.event(ctx, event) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target) } diff --git a/core/embed/rust/src/ui/layout/obj.rs b/core/embed/rust/src/ui/layout/obj.rs index 2c1f4115c5..3ab4d64ea5 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -9,8 +9,9 @@ use num_traits::{FromPrimitive, ToPrimitive}; #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; -#[cfg(feature = "new_rendering")] + use crate::ui::{display::Color, shape::render_on_display}; + #[cfg(feature = "touch")] use crate::ui::{event::TouchEvent, geometry::Direction}; use crate::{ @@ -141,14 +142,9 @@ where } fn paint(&mut self) { - #[cfg(not(feature = "new_rendering"))] - self.inner.paint(); - #[cfg(feature = "new_rendering")] - { - render_on_display(None, Some(Color::black()), |target| { - self.inner.render(target); - }); - } + render_on_display(None, Some(Color::black()), |target| { + self.inner.render(target); + }); } } @@ -305,10 +301,6 @@ impl LayoutObjInner { /// Run a paint pass over the component tree. Returns true if any component /// actually requested painting since last invocation of the function. fn obj_paint_if_requested(&mut self) -> bool { - if self.repaint == Repaint::Full { - display::clear(); - } - display::sync(); if self.repaint != Repaint::None { diff --git a/core/embed/rust/src/ui/layout/simplified.rs b/core/embed/rust/src/ui/layout/simplified.rs index 23fe4cf669..6ecc692a4d 100644 --- a/core/embed/rust/src/ui/layout/simplified.rs +++ b/core/embed/rust/src/ui/layout/simplified.rs @@ -15,7 +15,6 @@ use crate::ui::{ use num_traits::ToPrimitive; -#[cfg(feature = "new_rendering")] use crate::ui::{display::color::Color, shape::render_on_display}; pub trait ReturnToC { @@ -68,21 +67,11 @@ fn touch_eval() -> Option { } fn render(frame: &mut impl Component) { - #[cfg(not(feature = "new_rendering"))] - { - display::sync(); - frame.paint(); - display::refresh(); - } - - #[cfg(feature = "new_rendering")] - { - display::sync(); - render_on_display(None, Some(Color::black()), |target| { - frame.render(target); - }); - display::refresh(); - } + display::sync(); + render_on_display(None, Some(Color::black()), |target| { + frame.render(target); + }); + display::refresh(); } pub fn run(frame: &mut impl Component) -> u32 { diff --git a/core/embed/rust/src/ui/mod.rs b/core/embed/rust/src/ui/mod.rs index da52799582..89e0ec2a76 100644 --- a/core/embed/rust/src/ui/mod.rs +++ b/core/embed/rust/src/ui/mod.rs @@ -6,7 +6,7 @@ pub mod component; pub mod constant; pub mod display; pub mod event; -#[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] +#[cfg(all(feature = "micropython", feature = "touch"))] pub mod flow; pub mod geometry; pub mod lerp; diff --git a/core/embed/rust/src/ui/model_mercury/bootloader/intro.rs b/core/embed/rust/src/ui/model_mercury/bootloader/intro.rs index 8fe0b39818..816b14c848 100644 --- a/core/embed/rust/src/ui/model_mercury/bootloader/intro.rs +++ b/core/embed/rust/src/ui/model_mercury/bootloader/intro.rs @@ -102,15 +102,6 @@ impl<'a> Component for Intro<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - self.title.paint(); - self.text.paint(); - self.warn.paint(); - self.host.paint(); - self.menu.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.title.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/bootloader/menu.rs b/core/embed/rust/src/ui/model_mercury/bootloader/menu.rs index 97ab8857ae..25e152b54d 100644 --- a/core/embed/rust/src/ui/model_mercury/bootloader/menu.rs +++ b/core/embed/rust/src/ui/model_mercury/bootloader/menu.rs @@ -101,14 +101,6 @@ impl Component for Menu { None } - fn paint(&mut self) { - self.bg.paint(); - self.title.paint(); - self.close.paint(); - self.reboot.paint(); - self.reset.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.title.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs b/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs index 70d886400c..e36169ed2a 100644 --- a/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs @@ -31,10 +31,6 @@ use super::{ use crate::ui::{ui_features::UIFeaturesBootloader, UIFeaturesCommon}; -#[cfg(not(feature = "new_rendering"))] -use super::theme::BLACK; - -#[cfg(feature = "new_rendering")] use crate::ui::{ display::{toif::Toif, LOADER_MAX}, geometry::Alignment2D, @@ -43,10 +39,8 @@ use crate::ui::{ shape::render_on_display, }; -#[cfg(feature = "new_rendering")] use ufmt::uwrite; -#[cfg(feature = "new_rendering")] use super::theme::bootloader::BLD_WARN_COLOR; use intro::Intro; use menu::Menu; @@ -63,42 +57,6 @@ const SCREEN: Rect = ModelMercuryFeatures::SCREEN; const PROGRESS_TEXT_ORIGIN: Point = Point::new(2, 28); impl ModelMercuryFeatures { - #[cfg(not(feature = "new_rendering"))] - fn screen_progress( - text: &str, - progress: u16, - initialize: bool, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, - center_text: Option<&str>, - ) { - let loader_offset: i16 = 19; - let center_text_offset: i16 = 10; - - if initialize { - Self::fadeout(); - display::rect_fill(SCREEN, bg_color); - } - - display::text_left(PROGRESS_TEXT_ORIGIN, text, Font::NORMAL, BLD_FG, bg_color); - display::loader(progress, 19, fg_color, bg_color, icon); - if let Some(center_text) = center_text { - display::text_center( - SCREEN.center() + Offset::y(loader_offset + center_text_offset), - center_text, - Font::NORMAL, - GREY, - bg_color, - ); - } - display::refresh(); - if initialize { - Self::fadein(); - } - } - - #[cfg(feature = "new_rendering")] fn screen_progress( text: &str, progress: u16, @@ -170,17 +128,6 @@ impl UIFeaturesBootloader for ModelMercuryFeatures { show(&mut frame, true); } - #[cfg(not(feature = "new_rendering"))] - fn bld_continue_label(bg_color: Color) { - display::text_center( - Point::new(SCREEN.width() / 2, SCREEN.height() - 5), - "click to continue ...", - Font::NORMAL, - BLD_FG, - bg_color, - ); - } - fn screen_install_success(restart_seconds: u8, initial_setup: bool, complete_draw: bool) { let mut reboot_msg = BootloaderString::new(); @@ -372,9 +319,6 @@ impl UIFeaturesBootloader for ModelMercuryFeatures { Self::fadeout(); } - #[cfg(not(feature = "new_rendering"))] - display::rect_fill(SCREEN, BLACK); - let mut frame = WelcomeScreen::new(); show(&mut frame, false); @@ -443,7 +387,6 @@ impl UIFeaturesBootloader for ModelMercuryFeatures { show(&mut frame, true); } - #[cfg(feature = "new_rendering")] fn screen_boot( warning: bool, vendor_str: Option<&str>, diff --git a/core/embed/rust/src/ui/model_mercury/bootloader/welcome.rs b/core/embed/rust/src/ui/model_mercury/bootloader/welcome.rs index 3900459163..2779b14de1 100644 --- a/core/embed/rust/src/ui/model_mercury/bootloader/welcome.rs +++ b/core/embed/rust/src/ui/model_mercury/bootloader/welcome.rs @@ -1,7 +1,7 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never, Pad}, constant::screen, - display::{self, Font}, + display::Font, geometry::{Offset, Point, Rect}, shape, shape::Renderer, @@ -36,34 +36,6 @@ impl Component for Welcome { None } - fn paint(&mut self) { - let at_width = Font::NORMAL.text_width("at "); - - self.bg.paint(); - display::text_left(TEXT_ORIGIN, "Get started", Font::NORMAL, GREY, BLACK); - display::text_left( - TEXT_ORIGIN + Offset::y(STRIDE), - "with your Trezor", - Font::NORMAL, - GREY, - BLACK, - ); - display::text_left( - TEXT_ORIGIN + Offset::y(2 * STRIDE), - "at", - Font::NORMAL, - GREY, - BLACK, - ); - display::text_left( - TEXT_ORIGIN + Offset::new(at_width, 2 * STRIDE), - "trezor.io/start", - Font::NORMAL, - WHITE, - BLACK, - ); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/address_details.rs b/core/embed/rust/src/ui/model_mercury/component/address_details.rs index 7e2978a5a5..ce0ee70c98 100644 --- a/core/embed/rust/src/ui/model_mercury/component/address_details.rs +++ b/core/embed/rust/src/ui/model_mercury/component/address_details.rs @@ -174,13 +174,6 @@ impl Component for AddressDetails { } } - fn paint(&mut self) { - match self.current_page { - 0 => self.details.paint(), - _ => self.xpub_view.paint(), - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { match self.current_page { 0 => self.details.render(target), diff --git a/core/embed/rust/src/ui/model_mercury/component/binary_selection.rs b/core/embed/rust/src/ui/model_mercury/component/binary_selection.rs index 5b990c0926..decc466e4f 100644 --- a/core/embed/rust/src/ui/model_mercury/component/binary_selection.rs +++ b/core/embed/rust/src/ui/model_mercury/component/binary_selection.rs @@ -72,10 +72,6 @@ impl Component for BinarySelection { None } - fn paint(&mut self) { - unimplemented!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.button_left.render(target); self.button_right.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/bl_confirm.rs b/core/embed/rust/src/ui/model_mercury/component/bl_confirm.rs index d48d2cce47..3e06b9b002 100644 --- a/core/embed/rust/src/ui/model_mercury/component/bl_confirm.rs +++ b/core/embed/rust/src/ui/model_mercury/component/bl_confirm.rs @@ -205,42 +205,6 @@ impl Component for Confirm<'_> { None } - fn paint(&mut self) { - self.bg.paint(); - self.content_pad.paint(); - - if let Some(info) = self.info.as_mut() { - if self.show_info { - info.close_button.paint(); - info.title.paint(); - info.text.paint(); - self.left_button.paint(); - self.right_button.paint(); - // short-circuit before painting the main components - return; - } else { - info.info_button.paint(); - // pass through to the rest of the paint - } - } - - self.message.paint(); - self.alert.paint(); - self.left_button.paint(); - self.right_button.paint(); - match &mut self.title { - ConfirmTitle::Text(label) => label.paint(), - ConfirmTitle::Icon(icon) => { - icon.draw( - Point::new(screen().center().x, ICON_TOP), - Alignment2D::TOP_CENTER, - WHITE, - self.bg_color, - ); - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.content_pad.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/button.rs b/core/embed/rust/src/ui/model_mercury/component/button.rs index 2d2d0282e9..9a09e01f0b 100644 --- a/core/embed/rust/src/ui/model_mercury/component/button.rs +++ b/core/embed/rust/src/ui/model_mercury/component/button.rs @@ -5,7 +5,7 @@ use crate::{ time::Duration, ui::{ component::{Component, Event, EventCtx, Timer}, - display::{self, toif::Icon, Color, Font}, + display::{toif::Icon, Color, Font}, event::TouchEvent, geometry::{Alignment, Alignment2D, Insets, Offset, Point, Rect}, shape::{self, Renderer}, @@ -172,10 +172,6 @@ impl Button { } } - pub fn paint_background(&self, style: &ButtonStyle) { - display::rect_fill(self.area, style.button_color); - } - pub fn render_background<'s>( &self, target: &mut impl Renderer<'s>, @@ -199,35 +195,6 @@ impl Button { } } - pub fn paint_content(&self, style: &ButtonStyle) { - match &self.content { - ButtonContent::Empty => {} - ButtonContent::Text(text) => { - let start_of_baseline = self.area.center() + Self::BASELINE_OFFSET; - text.map(|text| { - display::text_left( - start_of_baseline, - text, - style.font, - style.text_color, - style.button_color, - ); - }); - } - ButtonContent::Icon(icon) => { - icon.draw( - self.area.center(), - Alignment2D::CENTER, - style.icon_color, - style.button_color, - ); - } - ButtonContent::IconAndText(child) => { - child.paint(self.area, self.style(), Self::BASELINE_OFFSET); - } - } - } - pub fn render_content<'s>( &self, target: &mut impl Renderer<'s>, @@ -387,12 +354,6 @@ impl Component for Button { None } - fn paint(&mut self) { - let style = self.style(); - self.paint_background(style); - self.paint_content(style); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let style = self.style(); self.render_background(target, style, 0xFF); @@ -466,54 +427,6 @@ impl IconText { } } - pub fn paint(&self, area: Rect, style: &ButtonStyle, baseline_offset: Offset) { - let width = self.text.map(|t| style.font.text_width(t)); - let height = style.font.text_height(); - - let mut use_icon = false; - let mut use_text = false; - - let mut icon_pos = Point::new( - area.top_left().x + ((Self::ICON_SPACE + Self::ICON_MARGIN) / 2), - area.center().y, - ); - let mut text_pos = area.center() + Offset::new(-width / 2, height / 2) + baseline_offset; - - if area.width() > (Self::ICON_SPACE + Self::TEXT_MARGIN + width) { - //display both icon and text - text_pos = Point::new(area.top_left().x + Self::ICON_SPACE, text_pos.y); - use_text = true; - use_icon = true; - } else if area.width() > (width + Self::TEXT_MARGIN) { - use_text = true; - } else { - //if we can't fit the text, retreat to centering the icon - icon_pos = area.center(); - use_icon = true; - } - - if use_text { - self.text.map(|t| { - display::text_left( - text_pos, - t, - style.font, - style.text_color, - style.button_color, - ) - }); - } - - if use_icon { - self.icon.draw( - icon_pos, - Alignment2D::CENTER, - style.icon_color, - style.button_color, - ); - } - } - pub fn render<'s>( &self, target: &mut impl Renderer<'s>, diff --git a/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs b/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs index b67616bee2..25b5ac5f64 100644 --- a/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs +++ b/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs @@ -7,7 +7,6 @@ use crate::{ translations::TR, ui::{ component::{base::Never, Bar, Component, Empty, Event, EventCtx, Label, Split}, - display::loader::{loader_circular_uncompress, LoaderDimensions}, geometry::{Insets, Offset, Rect}, model_mercury::constant, shape, @@ -107,20 +106,6 @@ where None } - fn paint(&mut self) { - self.content.paint(); - loader_circular_uncompress( - LoaderDimensions::new(LOADER_OUTER, LOADER_INNER), - LOADER_OFFSET, - theme::FG, - theme::BG, - self.value, - self.indeterminate, - None, - ); - self.label.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.content.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/error.rs b/core/embed/rust/src/ui/model_mercury/component/error.rs index 9df9741851..c6ca54e5b7 100644 --- a/core/embed/rust/src/ui/model_mercury/component/error.rs +++ b/core/embed/rust/src/ui/model_mercury/component/error.rs @@ -77,21 +77,6 @@ impl<'a> Component for ErrorScreen<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - - let icon = ICON_WARNING40; - icon.draw( - Point::new(screen().center().x, ICON_TOP), - Alignment2D::TOP_CENTER, - WHITE, - FATAL_ERROR_COLOR, - ); - self.title.paint(); - self.message.paint(); - self.footer.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/fido.rs b/core/embed/rust/src/ui/model_mercury/component/fido.rs index 92bcbe344e..34c5cca169 100644 --- a/core/embed/rust/src/ui/model_mercury/component/fido.rs +++ b/core/embed/rust/src/ui/model_mercury/component/fido.rs @@ -70,10 +70,6 @@ impl TString<'static>> Component for FidoCredential { None } - fn paint(&mut self) { - unimplemented!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.app_icon.render(target); self.text.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/footer.rs b/core/embed/rust/src/ui/model_mercury/component/footer.rs index 151d774654..c0c4ba0c5f 100644 --- a/core/embed/rust/src/ui/model_mercury/component/footer.rs +++ b/core/embed/rust/src/ui/model_mercury/component/footer.rs @@ -186,10 +186,6 @@ impl<'a> Component for Footer<'a> { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done") - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let progress = self.progress as f32 / 1000.0; diff --git a/core/embed/rust/src/ui/model_mercury/component/frame.rs b/core/embed/rust/src/ui/model_mercury/component/frame.rs index 13f4666f6a..b25de2c8cb 100644 --- a/core/embed/rust/src/ui/model_mercury/component/frame.rs +++ b/core/embed/rust/src/ui/model_mercury/component/frame.rs @@ -319,11 +319,6 @@ where None } - fn paint(&mut self) { - self.header.paint(); - self.footer.paint(); - self.content.paint(); - } fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.header.render(target); self.footer.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/header.rs b/core/embed/rust/src/ui/model_mercury/component/header.rs index 45a3d48cf1..5e01aa9877 100644 --- a/core/embed/rust/src/ui/model_mercury/component/header.rs +++ b/core/embed/rust/src/ui/model_mercury/component/header.rs @@ -212,10 +212,6 @@ impl Component for Header { None } - fn paint(&mut self) { - todo!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let offset = if let Some(anim) = &self.anim { Offset::x(anim.get_title_offset(anim.eval())) diff --git a/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs b/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs index f0f2b145e6..4cbe5ccf97 100644 --- a/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs @@ -271,10 +271,6 @@ impl Component for HoldToConfirm { None } - fn paint(&mut self) { - unimplemented!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let elapsed = self.anim.eval(); diff --git a/core/embed/rust/src/ui/model_mercury/component/homescreen.rs b/core/embed/rust/src/ui/model_mercury/component/homescreen.rs index 892cebfc96..db19990a41 100644 --- a/core/embed/rust/src/ui/model_mercury/component/homescreen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/homescreen.rs @@ -573,10 +573,6 @@ impl Component for Homescreen { } } - fn paint(&mut self) { - todo!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if self.loader.is_animating() || self.loader.is_completely_grown(Instant::now()) { self.render_loader(target); @@ -798,10 +794,6 @@ impl Component for Lockscreen { None } - fn paint(&mut self) { - todo!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { const OVERLAY_BORDER: i16 = (AREA.height() / 2) - DEFAULT_HS_RADIUS; diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs index 9eec4b179b..2f07a00cd1 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs @@ -102,10 +102,6 @@ impl Component for Bip39Input { } } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done"); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let area = self.button.area(); let style = self.button.style(); diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/common.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/common.rs index 0f52d68632..deea319194 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/common.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/common.rs @@ -2,7 +2,7 @@ use crate::{ time::Duration, ui::{ component::{text::common::TextEdit, Event, EventCtx, Timer}, - display::{self, Color, Font}, + display::{Color, Font}, geometry::{Alignment2D, Offset, Point, Rect}, shape::{self, Renderer}, }, @@ -110,21 +110,6 @@ impl MultiTapKeyboard { } } -/// Create a visible "underscoring" of the last letter of a text. -pub fn paint_pending_marker(text_baseline: Point, text: &str, font: Font, color: Color) { - // Measure the width of the last character of input. - if let Some(last) = text.chars().last() { - let width = font.text_width(text); - let last_width = font.char_width(last); - // Draw the marker 2px under the start of the baseline of the last character. - let marker_origin = text_baseline + Offset::new(width - last_width, 2); - // Draw the marker 1px longer than the last character, and 3px thick. - let marker_rect = - Rect::from_top_left_and_size(marker_origin, Offset::new(last_width + 1, 3)); - display::rect_fill(marker_rect, color); - } -} - /// Create a visible "underscoring" of the last letter of a text. pub fn render_pending_marker<'s>( target: &mut impl Renderer<'s>, diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs index e9ee60cc56..793ab69028 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs @@ -1,7 +1,7 @@ use crate::{ strutil::TString, ui::{ - component::{maybe::paint_overlapping, Component, Event, EventCtx, Label, Maybe}, + component::{Component, Event, EventCtx, Label, Maybe}, geometry::{Alignment, Grid, Insets, Rect}, model_mercury::{ component::{Button, ButtonMsg}, @@ -185,13 +185,6 @@ where None } - fn paint(&mut self) { - paint_overlapping(&mut [&mut self.prompt, &mut self.input, &mut self.erase]); - for btn in &mut self.keys { - btn.paint(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if self.input.inner().is_empty() { self.prompt.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/passphrase.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/passphrase.rs index 52651ff06d..6b6e5ee580 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/passphrase.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/passphrase.rs @@ -389,10 +389,6 @@ impl Component for PassphraseKeyboard { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done") - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.input.render(target); self.next_btn.render(target); @@ -444,10 +440,6 @@ impl Component for Input { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done"); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let style = theme::label_keyboard(); diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/pin.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/pin.rs index 6561ad802e..9f25bc49dd 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/pin.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/pin.rs @@ -477,10 +477,6 @@ impl Component for PinKeyboard<'_> { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done"); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let t_attach = self.attach_animation.eval(); let t_close = self.close_animation.eval(); @@ -678,10 +674,6 @@ impl Component for PinDots { } } - fn paint(&mut self) { - // TODO: remove when ui-t3t1 done - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let dot_area = self.area.inset(HEADER_PADDING); self.pad.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/slip39.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/slip39.rs index de7ec4f1a7..50b3a48667 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/slip39.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/slip39.rs @@ -121,10 +121,6 @@ impl Component for Slip39Input { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done") - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let area = self.button.area(); let style = self.button.style(); diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/word_count.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/word_count.rs index 33b4800ca2..30994d5efe 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/word_count.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/word_count.rs @@ -63,10 +63,6 @@ impl Component for SelectWordCount { } } - fn paint(&mut self) { - unimplemented!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { match self { SelectWordCount::All(full_selector) => full_selector.render(target), @@ -127,12 +123,6 @@ impl Component for ValueKeypad { None } - fn paint(&mut self) { - for btn in self.button.iter_mut() { - btn.paint() - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { for btn in self.button.iter() { btn.render(target) diff --git a/core/embed/rust/src/ui/model_mercury/component/loader.rs b/core/embed/rust/src/ui/model_mercury/component/loader.rs index f32939142c..d1acee08c5 100644 --- a/core/embed/rust/src/ui/model_mercury/component/loader.rs +++ b/core/embed/rust/src/ui/model_mercury/component/loader.rs @@ -190,28 +190,6 @@ impl Component for Loader { None } - fn paint(&mut self) { - // TODO: Consider passing the current instant along with the event -- that way, - // we could synchronize painting across the component tree. Also could be useful - // in automated tests. - // In practice, taking the current instant here is more precise in case some - // other component in the tree takes a long time to draw. - let now = Instant::now(); - - if let Some(progress) = self.progress(now) { - let style = self.styles.active; - - self.pad.paint(); - display::loader( - progress, - self.offset_y, - style.active, - style.background_color, - style.icon, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // TODO: Consider passing the current instant along with the event -- that way, // we could synchronize painting across the component tree. Also could be useful diff --git a/core/embed/rust/src/ui/model_mercury/component/number_input.rs b/core/embed/rust/src/ui/model_mercury/component/number_input.rs index 4a8e449fd0..34c8cffd2a 100644 --- a/core/embed/rust/src/ui/model_mercury/component/number_input.rs +++ b/core/embed/rust/src/ui/model_mercury/component/number_input.rs @@ -73,10 +73,6 @@ impl Component for NumberInputDialog { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done"); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.input.render(target); self.paragraphs_pad.render(target); @@ -152,10 +148,6 @@ impl Component for NumberInput { None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done"); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let mut buf = [0u8; 10]; diff --git a/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs b/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs index 3eac245f0d..97bf34b179 100644 --- a/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs +++ b/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs @@ -5,7 +5,6 @@ use crate::{ ui::{ component::{Component, Event, EventCtx}, constant::screen, - display, event::TouchEvent, geometry::{Alignment, Alignment2D, Insets, Offset, Point, Rect}, shape::{self, Renderer}, @@ -96,10 +95,6 @@ impl Component for NumberInputSliderDialog { }) } - fn paint(&mut self) { - self.input.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.input.render(target); self.footer.render(target); @@ -190,13 +185,6 @@ impl Component for NumberInputSlider { None } - fn paint(&mut self) { - let val_pct = (100 * (self.value - self.min)) / (self.max - self.min); - let fill_to = (val_pct as i16 * self.area.width()) / 100; - - display::bar_with_text_and_fill(self.area, None, theme::FG, theme::BG, 0, fill_to as _); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let (top_left_shape, top_right_shape, bot_left_shape, bot_right_shape) = shape::CornerHighlight::from_rect( diff --git a/core/embed/rust/src/ui/model_mercury/component/progress.rs b/core/embed/rust/src/ui/model_mercury/component/progress.rs index 9b5f0fe3cd..38ffc8d7ce 100644 --- a/core/embed/rust/src/ui/model_mercury/component/progress.rs +++ b/core/embed/rust/src/ui/model_mercury/component/progress.rs @@ -8,7 +8,7 @@ use crate::{ text::paragraphs::{Paragraph, Paragraphs}, Component, Event, EventCtx, Label, Never, Pad, }, - display::{self, Font, LOADER_MAX}, + display::{Font, LOADER_MAX}, geometry::{Insets, Offset, Rect}, model_mercury::{ constant, @@ -88,23 +88,6 @@ impl Component for Progress { None } - fn paint(&mut self) { - self.title.paint(); - if self.indeterminate { - display::loader_indeterminate( - self.value, - self.loader_y_offset, - theme::FG, - theme::BG, - None, - ); - } else { - display::loader(self.value, self.loader_y_offset, theme::FG, theme::BG, None); - } - self.description_pad.paint(); - self.description.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.title.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs b/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs index 9737523deb..4e4f37ccc0 100644 --- a/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs @@ -106,10 +106,6 @@ impl Component for PromptScreen { None } - fn paint(&mut self) { - todo!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { match self { PromptScreen::Tap(t) => t.render(target), diff --git a/core/embed/rust/src/ui/model_mercury/component/result.rs b/core/embed/rust/src/ui/model_mercury/component/result.rs index f9d0374806..fcc4cc65bd 100644 --- a/core/embed/rust/src/ui/model_mercury/component/result.rs +++ b/core/embed/rust/src/ui/model_mercury/component/result.rs @@ -3,7 +3,7 @@ use crate::{ ui::{ component::{text::TextStyle, Component, Event, EventCtx, Label, Never, Pad}, constant::screen, - display::{self, Color, Font, Icon}, + display::{Color, Font, Icon}, geometry::{Alignment2D, Insets, Offset, Point, Rect}, shape, shape::Renderer, @@ -85,18 +85,6 @@ impl Component for ResultFooter<'_> { None } - fn paint(&mut self) { - // divider line - let bar = Rect::from_center_and_size( - Point::new(self.area.center().x, self.area.y0), - Offset::new(self.area.width(), 1), - ); - display::rect_fill(bar, self.style.divider_color); - - // footer text - self.text.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // divider line let bar = Rect::from_center_and_size( @@ -168,20 +156,6 @@ impl<'a> Component for ResultScreen<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - self.footer_pad.paint(); - - self.icon.draw( - Point::new(screen().center().x, ICON_CENTER_Y), - Alignment2D::CENTER, - self.style.fg_color, - self.style.bg_color, - ); - self.message.paint(); - self.footer.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.footer_pad.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/component/scroll.rs b/core/embed/rust/src/ui/model_mercury/component/scroll.rs index 3c611fdc9a..04d0e6b9ba 100644 --- a/core/embed/rust/src/ui/model_mercury/component/scroll.rs +++ b/core/embed/rust/src/ui/model_mercury/component/scroll.rs @@ -84,46 +84,6 @@ impl Component for ScrollBar { None } - fn paint(&mut self) { - fn dotsize(distance: usize, nhidden: usize) -> Icon { - match (nhidden.saturating_sub(distance)).min(2 - distance) { - 0 => theme::DOT_INACTIVE, - 1 => theme::DOT_INACTIVE_HALF, - _ => theme::DOT_INACTIVE_QUARTER, - } - } - - // Number of visible dots. - let num_shown = self.page_count.min(Self::MAX_DOTS); - // Page indices corresponding to the first (and last) dot. - let first_shown = self - .active_page - .saturating_sub(Self::MAX_DOTS / 2) - .min(self.page_count.saturating_sub(Self::MAX_DOTS)); - let last_shown = first_shown + num_shown - 1; - - let mut cursor = self.area.center() - - Offset::on_axis( - self.layout.axis, - Self::DOT_INTERVAL * (num_shown.saturating_sub(1) as i16) / 2, - ); - for i in first_shown..(last_shown + 1) { - let icon = if i == self.active_page { - theme::DOT_ACTIVE - } else if i <= first_shown + 1 { - let before_first_shown = first_shown; - dotsize(i - first_shown, before_first_shown) - } else if i >= last_shown - 1 { - let after_last_shown = self.page_count - 1 - last_shown; - dotsize(last_shown - i, after_last_shown) - } else { - theme::DOT_INACTIVE - }; - icon.draw(cursor, Alignment2D::CENTER, theme::FG, theme::BG); - cursor = cursor + Offset::on_axis(self.layout.axis, Self::DOT_INTERVAL); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { fn dotsize(distance: usize, nhidden: usize) -> Icon { match (nhidden.saturating_sub(distance)).min(2 - distance) { diff --git a/core/embed/rust/src/ui/model_mercury/component/share_words.rs b/core/embed/rust/src/ui/model_mercury/component/share_words.rs index 51061ce0a2..fbab6a803b 100644 --- a/core/embed/rust/src/ui/model_mercury/component/share_words.rs +++ b/core/embed/rust/src/ui/model_mercury/component/share_words.rs @@ -186,10 +186,6 @@ impl<'a> Component for ShareWords<'a> { None } - fn paint(&mut self) { - // TODO: remove when ui-t3t1 done - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // corner highlights let (_, top_right_shape, bot_left_shape, bot_right_shape) = diff --git a/core/embed/rust/src/ui/model_mercury/component/status_screen.rs b/core/embed/rust/src/ui/model_mercury/component/status_screen.rs index d9cff5b86c..a20688e856 100644 --- a/core/embed/rust/src/ui/model_mercury/component/status_screen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/status_screen.rs @@ -235,10 +235,6 @@ impl Component for StatusScreen { None } - fn paint(&mut self) { - todo!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let t = self.anim.eval(); diff --git a/core/embed/rust/src/ui/model_mercury/component/swipe_content.rs b/core/embed/rust/src/ui/model_mercury/component/swipe_content.rs index 9ac2928845..8d2e18f558 100644 --- a/core/embed/rust/src/ui/model_mercury/component/swipe_content.rs +++ b/core/embed/rust/src/ui/model_mercury/component/swipe_content.rs @@ -268,10 +268,6 @@ impl Component for SwipeContent { self.process_event(ctx, event, true) } - fn paint(&mut self) { - self.inner.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let (offset, clip, mask) = self.swipe_context.get_params(self.bounds); @@ -394,10 +390,6 @@ where self.content.process_event(ctx, event, animate) } - fn paint(&mut self) { - self.content.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.content.render(target) } diff --git a/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs b/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs index 9c3d81fce4..0005fb17e2 100644 --- a/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs @@ -60,10 +60,6 @@ impl Component for SwipeUpScreen { self.content.event(ctx, e).map(SwipeUpScreenMsg::Content) } - fn paint(&mut self) { - todo!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.content.render(target); } diff --git a/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs b/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs index 184e5fdf71..ed40875f2c 100644 --- a/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs +++ b/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs @@ -186,10 +186,6 @@ impl Component for TapToConfirm { None } - fn paint(&mut self) { - unimplemented!() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { const PAD_RADIUS: i16 = 70; const PAD_THICKNESS: i16 = 20; diff --git a/core/embed/rust/src/ui/model_mercury/component/updatable_more_info.rs b/core/embed/rust/src/ui/model_mercury/component/updatable_more_info.rs index 4a3824d9d0..1e3c14c87c 100644 --- a/core/embed/rust/src/ui/model_mercury/component/updatable_more_info.rs +++ b/core/embed/rust/src/ui/model_mercury/component/updatable_more_info.rs @@ -61,10 +61,6 @@ where None } - fn paint(&mut self) { - todo!("remove when ui-t3t1 done"); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.paragraphs.render(target); } diff --git a/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs b/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs index f8d423997b..6ccd648304 100644 --- a/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs +++ b/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs @@ -250,10 +250,6 @@ impl Component for VerticalMenu { None } - fn paint(&mut self) { - // TODO remove when ui-t3t1 done - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let t = self.attach_animation.eval(); @@ -377,10 +373,6 @@ impl TString<'static>> Component for PagedVerticalMenu { msg } - fn paint(&mut self) { - // TODO remove when ui-t3t1 done - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.inner.render(target) } diff --git a/core/embed/rust/src/ui/model_mercury/component/welcome_screen.rs b/core/embed/rust/src/ui/model_mercury/component/welcome_screen.rs index 35c0ef6589..13f5ad0c72 100644 --- a/core/embed/rust/src/ui/model_mercury/component/welcome_screen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/welcome_screen.rs @@ -1,6 +1,5 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never}, - display, display::font::Font, geometry::{Alignment, Alignment2D, Offset, Rect}, shape, @@ -12,7 +11,7 @@ use super::theme; const TEXT_BOTTOM_MARGIN: i16 = 54; const ICON_TOP_MARGIN: i16 = 48; #[cfg(not(feature = "bootloader"))] -const MODEL_NAME_FONT: display::Font = display::Font::DEMIBOLD; +const MODEL_NAME_FONT: Font = Font::DEMIBOLD; use crate::trezorhal::model; @@ -38,22 +37,6 @@ impl Component for WelcomeScreen { None } - fn paint(&mut self) { - theme::ICON_LOGO.draw( - self.area.top_center() + Offset::y(ICON_TOP_MARGIN), - Alignment2D::TOP_CENTER, - theme::FG, - theme::BG, - ); - display::text_center( - self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN), - model::FULL_NAME, - display::Font::NORMAL, - theme::FG, - theme::BG, - ); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::ToifImage::new( self.area.top_center() + Offset::y(ICON_TOP_MARGIN), diff --git a/core/embed/rust/src/ui/model_mercury/screens.rs b/core/embed/rust/src/ui/model_mercury/screens.rs index 2bb6b36757..86a62e6b2e 100644 --- a/core/embed/rust/src/ui/model_mercury/screens.rs +++ b/core/embed/rust/src/ui/model_mercury/screens.rs @@ -5,21 +5,16 @@ use super::{ constant, }; -#[cfg(feature = "new_rendering")] use crate::ui::{display::Color, shape::render_on_display}; pub fn screen_fatal_error(title: &str, msg: &str, footer: &str) { let mut frame = ErrorScreen::new(title.into(), msg.into(), footer.into()); frame.place(constant::screen()); - #[cfg(feature = "new_rendering")] render_on_display(None, Some(Color::black()), |target| { frame.render(target); }); - #[cfg(not(feature = "new_rendering"))] - frame.paint(); - display::refresh(); } @@ -29,13 +24,9 @@ pub fn screen_boot_stage_2() { display::sync(); - #[cfg(feature = "new_rendering")] render_on_display(None, Some(Color::black()), |target| { frame.render(target); }); - #[cfg(not(feature = "new_rendering"))] - frame.paint(); - display::refresh(); } diff --git a/core/embed/rust/src/ui/model_tr/bootloader/intro.rs b/core/embed/rust/src/ui/model_tr/bootloader/intro.rs index 304cec4679..1e4e897e32 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/intro.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/intro.rs @@ -95,17 +95,6 @@ impl<'a> Component for Intro<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - self.title.paint(); - let area = self.bg.area; - ICON_WARN_TITLE.draw(area.top_left(), Alignment2D::TOP_LEFT, BLD_FG, BLD_BG); - ICON_WARN_TITLE.draw(area.top_right(), Alignment2D::TOP_RIGHT, BLD_FG, BLD_BG); - self.warn.paint(); - self.text.paint(); - self.buttons.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.title.render(target); diff --git a/core/embed/rust/src/ui/model_tr/bootloader/menu.rs b/core/embed/rust/src/ui/model_tr/bootloader/menu.rs index d9118223d0..66ec2b9ebb 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/menu.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/menu.rs @@ -5,7 +5,6 @@ use crate::{ ui::{ component::{Child, Component, Event, EventCtx, Pad}, constant::screen, - display, display::{Font, Icon}, geometry::{Alignment, Alignment2D, Offset, Point, Rect}, layout::simplified::ReturnToC, @@ -52,25 +51,6 @@ impl MenuChoice { } impl Choice for MenuChoice { - fn paint_center(&self, _area: Rect, _inverse: bool) { - // Icon on top and two lines of text below - self.icon.draw( - SCREEN_CENTER + Offset::y(-20), - Alignment2D::CENTER, - BLD_FG, - BLD_BG, - ); - - display::text_center(SCREEN_CENTER, self.first_line, Font::NORMAL, BLD_FG, BLD_BG); - display::text_center( - SCREEN_CENTER + Offset::y(10), - self.second_line, - Font::NORMAL, - BLD_FG, - BLD_BG, - ); - } - fn render_center<'s>(&self, target: &mut impl Renderer<'s>, _area: Rect, _inverse: bool) { // Icon on top and two lines of text below shape::ToifImage::new(SCREEN_CENTER + Offset::y(-20), self.icon.toif) @@ -179,11 +159,6 @@ impl Component for Menu { self.choice_page.event(ctx, event).map(|evt| evt.0) } - fn paint(&mut self) { - self.pad.paint(); - self.choice_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); self.choice_page.render(target); diff --git a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs index 57e6bb96f8..f23e7bb13a 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs @@ -24,15 +24,10 @@ use super::{ ModelTRFeatures, }; -#[cfg(not(feature = "new_rendering"))] -use crate::ui::geometry::Rect; - -#[cfg(feature = "new_rendering")] use crate::ui::{ display::toif::Toif, geometry::Alignment, model_tr::cshape, shape, shape::render_on_display, }; -#[cfg(feature = "new_rendering")] use ufmt::uwrite; mod intro; @@ -53,51 +48,6 @@ impl ReturnToC for ConfirmMsg { } impl ModelTRFeatures { - #[cfg(not(feature = "new_rendering"))] - fn screen_progress( - text: &str, - text2: &str, - progress: u16, - initialize: bool, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, - ) { - if initialize { - display::rect_fill(SCREEN, bg_color); - } - - let progress = if progress < 20 { 20 } else { progress }; - - display::rect_rounded2_partial( - Rect::new( - SCREEN.top_center() + Offset::new(-9, 3), - SCREEN.top_center() + Offset::new(9, 18 + 3), - ), - fg_color, - bg_color, - ((100_u32 * progress as u32) / 1000) as _, - icon, - ); - display::text_center( - SCREEN.center() + Offset::y(8), - text, - Font::BOLD, - fg_color, - bg_color, - ); - display::text_center( - SCREEN.center() + Offset::y(20), - text2, - Font::BOLD, - fg_color, - bg_color, - ); - - display::refresh(); - } - - #[cfg(feature = "new_rendering")] fn screen_progress( text: &str, text2: &str, @@ -148,29 +98,6 @@ impl UIFeaturesBootloader for ModelTRFeatures { show(&mut frame, true); } - #[cfg(not(feature = "new_rendering"))] - fn bld_continue_label(bg_color: Color) { - display::text_center( - Point::new(constant::WIDTH / 2, HEIGHT - 2), - "CONTINUE", - Font::NORMAL, - BLD_FG, - bg_color, - ); - ICON_ARM_LEFT.draw( - Point::new(constant::WIDTH / 2 - 36, HEIGHT - 6), - Alignment2D::TOP_LEFT, - BLD_FG, - bg_color, - ); - ICON_ARM_RIGHT.draw( - Point::new(constant::WIDTH / 2 + 25, HEIGHT - 6), - Alignment2D::TOP_LEFT, - BLD_FG, - bg_color, - ); - } - fn screen_install_success(restart_seconds: u8, _initial_setup: bool, complete_draw: bool) { let mut reboot_msg = BootloaderString::new(); @@ -321,9 +248,6 @@ impl UIFeaturesBootloader for ModelTRFeatures { } fn screen_boot_stage_1(_fading: bool) { - #[cfg(not(feature = "new_rendering"))] - display::rect_fill(SCREEN, BLD_BG); - let mut frame = WelcomeScreen::new(cfg!(ui_empty_lock)); show(&mut frame, false); } @@ -377,7 +301,6 @@ impl UIFeaturesBootloader for ModelTRFeatures { show(&mut frame, false); } - #[cfg(feature = "new_rendering")] fn screen_boot( _warning: bool, vendor_str: Option<&str>, diff --git a/core/embed/rust/src/ui/model_tr/bootloader/welcome.rs b/core/embed/rust/src/ui/model_tr/bootloader/welcome.rs index ad261e3b17..6293d6ee06 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/welcome.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/welcome.rs @@ -1,6 +1,6 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never, Pad}, - display::{self, Font}, + display::Font, geometry::{Alignment, Offset, Rect}, shape, shape::Renderer, @@ -32,34 +32,6 @@ impl Component for Welcome { None } - fn paint(&mut self) { - self.bg.paint(); - - let top_center = self.bg.area.top_center(); - - display::text_center( - top_center + Offset::y(24), - "Get started with", - Font::NORMAL, - BLD_FG, - BLD_BG, - ); - display::text_center( - top_center + Offset::y(32), - "your Trezor at", - Font::NORMAL, - BLD_FG, - BLD_BG, - ); - display::text_center( - top_center + Offset::y(48), - "trezor.io/start", - Font::BOLD, - BLD_FG, - BLD_BG, - ); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/address_details.rs b/core/embed/rust/src/ui/model_tr/component/address_details.rs index 52ea99578d..0322197273 100644 --- a/core/embed/rust/src/ui/model_tr/component/address_details.rs +++ b/core/embed/rust/src/ui/model_tr/component/address_details.rs @@ -250,16 +250,6 @@ impl Component for AddressDetails { None } - fn paint(&mut self) { - self.pad.paint(); - self.buttons.paint(); - match self.current_page { - 0 => self.qr_code.paint(), - 1 => self.details_view.paint(), - _ => self.xpub_view.paint(), - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); self.buttons.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/bl_confirm.rs b/core/embed/rust/src/ui/model_tr/component/bl_confirm.rs index 487f1f7bef..12986b10f9 100644 --- a/core/embed/rust/src/ui/model_tr/component/bl_confirm.rs +++ b/core/embed/rust/src/ui/model_tr/component/bl_confirm.rs @@ -2,7 +2,7 @@ use crate::{ strutil::TString, ui::{ component::{Child, Component, ComponentExt, Event, EventCtx, Label, Pad}, - display::{self, Color, Font}, + display::{Color, Font}, geometry::{Point, Rect}, shape, shape::Renderer, @@ -195,29 +195,6 @@ impl Component for Confirm<'_> { } } - fn paint(&mut self) { - self.bg.paint(); - - let display_top_left = |text: TString| { - text.map(|t| { - display::text_top_left(Point::zero(), t, Font::BOLD, WHITE, self.bg_color) - }); - }; - - // We are either on the info screen or on the "main" screen - if self.showing_info_screen { - if let Some(title) = self.info_title { - display_top_left(title); - } - self.info_text.paint(); - } else { - display_top_left(self.title); - self.message.paint(); - self.alert.paint(); - } - self.buttons.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/button.rs b/core/embed/rust/src/ui/model_tr/component/button.rs index 33ecbed4ff..1f4aaacc15 100644 --- a/core/embed/rust/src/ui/model_tr/component/button.rs +++ b/core/embed/rust/src/ui/model_tr/component/button.rs @@ -4,7 +4,7 @@ use crate::{ ui::{ component::{Component, Event, EventCtx, Never}, constant, - display::{self, Color, Font, Icon}, + display::{Color, Font, Icon}, event::PhysicalButton, geometry::{Alignment2D, Offset, Point, Rect}, shape, @@ -190,80 +190,6 @@ impl Component for Button { None } - fn paint(&mut self) { - let style = self.style(); - let fg_color = style.text_color; - let bg_color = fg_color.negate(); - let area = self.get_current_area(); - let inversed_colors = bg_color != theme::BG; - - // Filling the background (with 2-pixel rounding when applicable) - if inversed_colors { - display::rect_outline_rounded(area, bg_color, fg_color, 2); - display::rect_fill(area.shrink(1), bg_color); - } else if style.with_outline { - display::rect_outline_rounded(area, fg_color, bg_color, 2); - } else { - display::rect_fill(area, bg_color); - } - - // Optionally display "arms" at both sides of content - always in FG and BG - // colors (they are not inverted). - if style.with_arms { - theme::ICON_ARM_LEFT.draw( - area.left_center(), - Alignment2D::TOP_RIGHT, - theme::FG, - theme::BG, - ); - theme::ICON_ARM_RIGHT.draw( - area.right_center(), - Alignment2D::TOP_LEFT, - theme::FG, - theme::BG, - ); - } - - // Painting the content - match &self.content { - ButtonContent::Text(text) => text.map(|t| { - display::text_left( - self.get_text_baseline(style) - Offset::x(style.font.start_x_bearing(t)), - t, - style.font, - fg_color, - bg_color, - ); - }), - ButtonContent::Icon(icon) => { - // Allowing for possible offset of the area from current style - let icon_area = area.translate(style.offset); - if style.with_outline { - icon.draw(icon_area.center(), Alignment2D::CENTER, fg_color, bg_color); - } else { - // Positioning the icon in the corresponding corner/center - match self.pos { - ButtonPos::Left => icon.draw( - icon_area.bottom_left(), - Alignment2D::BOTTOM_LEFT, - fg_color, - bg_color, - ), - ButtonPos::Right => icon.draw( - icon_area.bottom_right(), - Alignment2D::BOTTOM_RIGHT, - fg_color, - bg_color, - ), - ButtonPos::Middle => { - icon.draw(icon_area.center(), Alignment2D::CENTER, fg_color, bg_color) - } - } - } - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let style = self.style(); let fg_color = style.text_color; diff --git a/core/embed/rust/src/ui/model_tr/component/button_controller.rs b/core/embed/rust/src/ui/model_tr/component/button_controller.rs index c50d6d7046..ed7d4ebca8 100644 --- a/core/embed/rust/src/ui/model_tr/component/button_controller.rs +++ b/core/embed/rust/src/ui/model_tr/component/button_controller.rs @@ -83,18 +83,6 @@ impl ButtonType { } } - pub fn paint(&mut self) { - match self { - Self::Button(button) => { - button.paint(); - } - Self::HoldToConfirm(htc) => { - htc.paint(); - } - Self::Nothing => {} - } - } - pub fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { match self { Self::Button(button) => { @@ -162,11 +150,6 @@ impl ButtonContainer { self.button_type.place(bounds); } - /// Painting the component that should be currently visible, if any. - pub fn paint(&mut self) { - self.button_type.paint(); - } - pub fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.button_type.render(target); } @@ -588,13 +571,6 @@ impl Component for ButtonController { } } - fn paint(&mut self) { - self.pad.paint(); - self.left_btn.paint(); - self.middle_btn.paint(); - self.right_btn.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); self.left_btn.render(target); @@ -777,8 +753,6 @@ impl Component for AutomaticMover { bounds } - fn paint(&mut self) {} - fn render<'s>(&'s self, _target: &mut impl Renderer<'s>) {} fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option { diff --git a/core/embed/rust/src/ui/model_tr/component/changing_text.rs b/core/embed/rust/src/ui/model_tr/component/changing_text.rs index 9546fd311a..fb8ac492e6 100644 --- a/core/embed/rust/src/ui/model_tr/component/changing_text.rs +++ b/core/embed/rust/src/ui/model_tr/component/changing_text.rs @@ -9,7 +9,7 @@ use crate::{ }, }; -use super::{common, theme}; +use super::theme; /// Component that allows for "allocating" a standalone line of text anywhere /// on the screen and updating it arbitrarily - without affecting the rest @@ -108,11 +108,6 @@ impl ChangingTextLine { self.font.text_width(self.text.as_ref()) <= self.pad.area.width() } - fn paint_left(&self) { - let baseline = Point::new(self.pad.area.x0, self.y_baseline()); - common::display_left(baseline, &self.text, self.font); - } - fn render_left<'s>(&'s self, target: &mut impl Renderer<'s>) { let baseline = Point::new(self.pad.area.x0, self.y_baseline()); shape::Text::new(baseline, self.text.as_ref()) @@ -120,11 +115,6 @@ impl ChangingTextLine { .render(target); } - fn paint_center(&self) { - let baseline = Point::new(self.pad.area.bottom_center().x, self.y_baseline()); - common::display_center(baseline, &self.text, self.font); - } - fn render_center<'s>(&'s self, target: &mut impl Renderer<'s>) { let baseline = Point::new(self.pad.area.bottom_center().x, self.y_baseline()); shape::Text::new(baseline, self.text.as_ref()) @@ -133,11 +123,6 @@ impl ChangingTextLine { .render(target); } - fn paint_right(&self) { - let baseline = Point::new(self.pad.area.x1, self.y_baseline()); - common::display_right(baseline, &self.text, self.font); - } - fn render_right<'s>(&'s self, target: &mut impl Renderer<'s>) { let baseline = Point::new(self.pad.area.x1, self.y_baseline()); shape::Text::new(baseline, self.text.as_ref()) @@ -146,23 +131,6 @@ impl ChangingTextLine { .render(target); } - fn paint_long_content_with_ellipsis(&self) { - let text_to_display = long_line_content_with_ellipsis( - self.text.as_ref(), - self.ellipsis, - self.font, - self.pad.area.width(), - ); - - // Creating the notion of motion by shifting the text left and right with - // each new text character. - // (So that it is apparent for the user that the text is changing.) - let x_offset = if self.text.len() % 2 == 0 { 0 } else { 2 }; - - let baseline = Point::new(self.pad.area.x0 + x_offset, self.y_baseline()); - common::display_left(baseline, &text_to_display, self.font); - } - fn render_long_content_with_ellipsis<'s>(&'s self, target: &mut impl Renderer<'s>) { let text_to_display = long_line_content_with_ellipsis( self.text.as_ref(), @@ -195,26 +163,6 @@ impl Component for ChangingTextLine { None } - fn paint(&mut self) { - // Always re-painting from scratch. - // Effectively clearing the line completely - // when `self.show_content` is set to `false`. - self.pad.clear(); - self.pad.paint(); - if self.show_content { - // In the case text cannot fit, show ellipsis and its right part - if !self.text_fits_completely() { - self.paint_long_content_with_ellipsis(); - } else { - match self.alignment { - Alignment::Start => self.paint_left(), - Alignment::Center => self.paint_center(), - Alignment::End => self.paint_right(), - } - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); if self.show_content { diff --git a/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs b/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs index 2256af3edb..8d5d9c61b5 100644 --- a/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs +++ b/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs @@ -6,12 +6,10 @@ use crate::{ ui::{ component::{ base::Never, - text::util::{ - text_multiline, text_multiline2, text_multiline_bottom, text_multiline_bottom2, - }, + text::util::{text_multiline, text_multiline_bottom}, Component, Event, EventCtx, }, - display::{self, Font}, + display::Font, geometry::{Alignment, Alignment2D, Insets, Offset, Rect}, model_tr::cshape, shape, @@ -82,60 +80,12 @@ impl Component for CoinJoinProgress { None } - fn paint(&mut self) { - // TOP - if self.indeterminate { - text_multiline( - self.area, - TR::coinjoin__title_progress.into(), - Font::BOLD_UPPER, - theme::FG, - theme::BG, - Alignment::Center, - ); - display::loader::loader_small_indeterminate( - self.value, - self.loader_y_offset, - theme::FG, - theme::BG, - ); - } else { - display::loader( - self.value, - self.loader_y_offset, - theme::FG, - theme::BG, - Some((theme::ICON_TICK_FAT, theme::FG)), - ); - } - - // BOTTOM - let top_rest = text_multiline_bottom( - self.area, - TR::coinjoin__do_not_disconnect.into(), - Font::BOLD, - theme::FG, - theme::BG, - Alignment::Center, - ); - if let Some(rest) = top_rest { - text_multiline_bottom( - rest.inset(Insets::bottom(FOOTER_TEXT_MARGIN)), - self.text, - Font::NORMAL, - theme::FG, - theme::BG, - Alignment::Center, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // TOP let center = self.area.center() + Offset::y(self.loader_y_offset); if self.indeterminate { - text_multiline2( + text_multiline( target, self.area, TR::coinjoin__title_progress.into(), @@ -158,7 +108,7 @@ impl Component for CoinJoinProgress { } // BOTTOM - let top_rest = text_multiline_bottom2( + let top_rest = text_multiline_bottom( target, self.area, TR::coinjoin__do_not_disconnect.into(), @@ -168,7 +118,7 @@ impl Component for CoinJoinProgress { Alignment::Center, ); if let Some(rest) = top_rest { - text_multiline_bottom2( + text_multiline_bottom( target, rest.inset(Insets::bottom(FOOTER_TEXT_MARGIN)), self.text, diff --git a/core/embed/rust/src/ui/model_tr/component/common.rs b/core/embed/rust/src/ui/model_tr/component/common.rs deleted file mode 100644 index 78e9083f96..0000000000 --- a/core/embed/rust/src/ui/model_tr/component/common.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::ui::{ - display::{self, Font}, - geometry::Point, -}; - -use super::theme; - -/// Display white text on black background -pub fn display_left>(baseline: Point, text: T, font: Font) { - display::text_left(baseline, text.as_ref(), font, theme::FG, theme::BG); -} - -/// Display black text on white background -pub fn display_inverse>(baseline: Point, text: T, font: Font) { - display::text_left(baseline, text.as_ref(), font, theme::BG, theme::FG); -} - -/// Display white text on black background, -/// centered around a baseline Point -pub fn display_center>(baseline: Point, text: T, font: Font) { - display::text_center(baseline, text.as_ref(), font, theme::FG, theme::BG); -} - -/// Display white text on black background, -/// with right boundary at a baseline Point -pub fn display_right>(baseline: Point, text: T, font: Font) { - display::text_right(baseline, text.as_ref(), font, theme::FG, theme::BG); -} diff --git a/core/embed/rust/src/ui/model_tr/component/error.rs b/core/embed/rust/src/ui/model_tr/component/error.rs index 9772bc9d81..ff771a25f8 100644 --- a/core/embed/rust/src/ui/model_tr/component/error.rs +++ b/core/embed/rust/src/ui/model_tr/component/error.rs @@ -3,7 +3,6 @@ use crate::{ ui::{ component::{Child, Component, Event, EventCtx, Label, Never, Pad}, constant::{screen, WIDTH}, - display, geometry::{Alignment2D, Offset, Point, Rect}, model_tr::cshape, shape, @@ -86,22 +85,6 @@ impl Component for ErrorScreen<'_> { None } - fn paint(&mut self) { - self.bg.paint(); - - if self.show_icons { - theme::ICON_WARN_TITLE.draw(screen().top_left(), Alignment2D::TOP_LEFT, FG, BG); - theme::ICON_WARN_TITLE.draw(screen().top_right(), Alignment2D::TOP_RIGHT, FG, BG); - } - self.title.paint(); - self.message.paint(); - - // // divider line - display::dotted_line(Point::new(0, DIVIDER_POSITION), WIDTH, FG, 3); - - self.footer.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/flow.rs b/core/embed/rust/src/ui/model_tr/component/flow.rs index eb4841673e..0d0f8892cc 100644 --- a/core/embed/rust/src/ui/model_tr/component/flow.rs +++ b/core/embed/rust/src/ui/model_tr/component/flow.rs @@ -298,23 +298,6 @@ where None } - fn paint(&mut self) { - self.pad.paint(); - // Scrollbars are painted only with a title and when requested - if self.title.is_some() { - if self.show_scrollbar { - self.scrollbar.paint(); - } - self.title.paint(); - } - self.buttons.paint(); - // On purpose painting current page at the end, after buttons, - // because we sometimes (in the case of QR code) need to use the - // whole height of the display for showing the content - // (and painting buttons last would cover the lower part). - self.current_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); // Scrollbars are painted only with a title and when requested diff --git a/core/embed/rust/src/ui/model_tr/component/flow_pages.rs b/core/embed/rust/src/ui/model_tr/component/flow_pages.rs index c143c74232..d4a4c726ba 100644 --- a/core/embed/rust/src/ui/model_tr/component/flow_pages.rs +++ b/core/embed/rust/src/ui/model_tr/component/flow_pages.rs @@ -118,10 +118,6 @@ impl Page { self } - pub fn paint(&mut self) { - self.formatted.paint(); - } - pub fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.formatted.render(target); } diff --git a/core/embed/rust/src/ui/model_tr/component/frame.rs b/core/embed/rust/src/ui/model_tr/component/frame.rs index f47158d9e3..3ea0c8611d 100644 --- a/core/embed/rust/src/ui/model_tr/component/frame.rs +++ b/core/embed/rust/src/ui/model_tr/component/frame.rs @@ -77,11 +77,6 @@ where self.content.event(ctx, event) } - fn paint(&mut self) { - self.title.paint(); - self.content.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.title.render(target); self.content.render(target); @@ -198,12 +193,6 @@ where msg } - fn paint(&mut self) { - self.title.paint(); - self.scrollbar.paint(); - self.content.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.title.render(target); self.scrollbar.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/hold_to_confirm.rs b/core/embed/rust/src/ui/model_tr/component/hold_to_confirm.rs index 5cd104cb3c..7857c864a0 100644 --- a/core/embed/rust/src/ui/model_tr/component/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/model_tr/component/hold_to_confirm.rs @@ -120,10 +120,6 @@ impl Component for HoldToConfirm { None } - fn paint(&mut self) { - self.loader.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.loader.render(target); } diff --git a/core/embed/rust/src/ui/model_tr/component/homescreen.rs b/core/embed/rust/src/ui/model_tr/component/homescreen.rs index 6750ffe6eb..a5342725b0 100644 --- a/core/embed/rust/src/ui/model_tr/component/homescreen.rs +++ b/core/embed/rust/src/ui/model_tr/component/homescreen.rs @@ -7,10 +7,7 @@ use crate::{ component::{Child, Component, Event, EventCtx, Label}, constant::{HEIGHT, WIDTH}, display::{ - self, image::{ImageInfo, ToifFormat}, - rect_fill, - toif::Toif, Font, Icon, }, event::USBEvent, @@ -22,8 +19,8 @@ use crate::{ }; use super::{ - super::constant, common::display_center, theme, ButtonController, ButtonControllerMsg, - ButtonLayout, ButtonPos, CancelConfirmMsg, LoaderMsg, ProgressLoader, + super::constant, theme, ButtonController, ButtonControllerMsg, ButtonLayout, ButtonPos, + CancelConfirmMsg, LoaderMsg, ProgressLoader, }; const AREA: Rect = constant::screen(); @@ -42,15 +39,6 @@ const COINJOIN_CORNER: Point = AREA.top_right().ofs(Offset::new(-2, 2)); const HOLD_TO_LOCK_MS: u32 = 1000; -fn paint_default_image() { - theme::ICON_LOGO.draw( - TOP_CENTER + Offset::y(LOGO_ICON_TOP_MARGIN), - Alignment2D::TOP_CENTER, - theme::FG, - theme::BG, - ); -} - fn render_default_image<'s>(target: &mut impl Renderer<'s>) { shape::ToifImage::new( TOP_CENTER + Offset::y(LOGO_ICON_TOP_MARGIN), @@ -106,17 +94,6 @@ impl Homescreen { } } - fn paint_homescreen_image(&self) { - if let Some(image) = self.custom_image { - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let toif = unwrap!(Toif::new(unsafe { image.data() })); - toif.draw(TOP_CENTER, Alignment2D::TOP_CENTER, theme::FG, theme::BG); - } else { - paint_default_image(); - } - } - fn render_homescreen_image<'s>(&'s self, target: &mut impl Renderer<'s>) { if let Some(image) = self.custom_image { shape::ToifImage::new_image(TOP_CENTER, image) @@ -128,37 +105,6 @@ impl Homescreen { } } - fn paint_notification(&self) { - let baseline = TOP_CENTER + Offset::y(NOTIFICATION_FONT.line_height()); - if !usb_configured() { - self.fill_notification_background(); - // TODO: fill warning icons here as well? - TR::homescreen__title_no_usb_connection - .map_translated(|t| display_center(baseline, t, NOTIFICATION_FONT)); - } else if let Some((notification, _level)) = &self.notification { - self.fill_notification_background(); - notification.map(|c| display_center(baseline, c, NOTIFICATION_FONT)); - // Painting warning icons in top corners when the text is short enough not to - // collide with them - let icon_width = NOTIFICATION_ICON.toif.width(); - let text_width = notification.map(|c| NOTIFICATION_FONT.text_width(c)); - if AREA.width() >= text_width + (icon_width + 1) * 2 { - NOTIFICATION_ICON.draw( - AREA.top_left(), - Alignment2D::TOP_LEFT, - theme::FG, - theme::BG, - ); - NOTIFICATION_ICON.draw( - AREA.top_right(), - Alignment2D::TOP_RIGHT, - theme::FG, - theme::BG, - ); - } - } - } - fn render_notification<'s>(&'s self, target: &mut impl Renderer<'s>) { let baseline = TOP_CENTER + Offset::y(NOTIFICATION_FONT.line_height()); if !usb_configured() { @@ -204,16 +150,6 @@ impl Homescreen { } } - fn paint_label(&mut self) { - // paint black background to place the label - let mut outset = Insets::uniform(LABEL_OUTSET); - // the margin at top is bigger (caused by text-height vs line-height?) - // compensate by shrinking the outset - outset.top -= 5; - rect_fill(self.label.text_area().outset(outset), theme::BG); - self.label.paint(); - } - fn render_label<'s>(&'s self, target: &mut impl Renderer<'s>) { // paint black background to place the label let mut outset = Insets::uniform(LABEL_OUTSET); @@ -227,11 +163,6 @@ impl Homescreen { self.label.render(target); } - /// So that notification is well visible even on homescreen image - fn fill_notification_background(&self) { - rect_fill(AREA.split_top(NOTIFICATION_HEIGHT).0, theme::BG); - } - fn event_usb(&mut self, ctx: &mut EventCtx, event: Event) { if let Event::USB(USBEvent::Connected(_)) = event { ctx.request_paint(); @@ -283,27 +214,6 @@ impl Component for Homescreen { None } - fn paint(&mut self) { - // Redraw the whole screen when the screen changes (loader vs homescreen) - if self.show_loader { - if !matches!(self.current_screen, CurrentScreen::Loader) { - display::clear(); - self.current_screen = CurrentScreen::Loader; - } - self.loader.paint(); - } else { - if !matches!(self.current_screen, CurrentScreen::Homescreen) { - display::clear(); - self.current_screen = CurrentScreen::Homescreen; - } - // Painting the homescreen image first, as the notification and label - // should be "on top of it" - self.paint_homescreen_image(); - self.paint_notification(); - self.paint_label(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // Redraw the whole screen when the screen changes (loader vs homescreen) if self.show_loader { @@ -366,29 +276,6 @@ impl Component for Lockscreen<'_> { None } - fn paint(&mut self) { - if self.screensaver { - // keep screen blank - return; - } - theme::ICON_LOCK.draw( - TOP_CENTER + Offset::y(LOCK_ICON_TOP_MARGIN), - Alignment2D::TOP_CENTER, - theme::FG, - theme::BG, - ); - self.instruction.paint(); - self.label.paint(); - if let Some(i) = &self.coinjoin_icon { - i.draw( - COINJOIN_CORNER, - Alignment2D::TOP_RIGHT, - theme::FG, - theme::BG, - ) - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if self.screensaver { // keep screen blank @@ -455,24 +342,6 @@ impl Component for ConfirmHomescreen { None } - fn paint(&mut self) { - if self.image.is_empty() { - paint_default_image(); - } else { - // Drawing the image full-screen first and then other things on top - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let toif_data = unwrap!(Toif::new(unsafe { self.image.data() })); - toif_data.draw(TOP_CENTER, Alignment2D::TOP_CENTER, theme::FG, theme::BG); - }; - // Need to make all the title background black, so the title text is well - // visible - let title_area = self.title.inner().area(); - rect_fill(title_area, theme::BG); - self.title.paint(); - self.buttons.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if self.image.is_empty() { render_default_image(target); diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/choice.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/choice.rs index 4cd681b775..a27d71ee69 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/choice.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/choice.rs @@ -12,18 +12,12 @@ use super::super::{ const DEFAULT_ITEMS_DISTANCE: i16 = 10; pub trait Choice { - // Only `paint_center` is required, the rest is optional - // and therefore has a default implementation. - fn paint_center(&self, area: Rect, inverse: bool); - fn render_center<'s>(&self, target: &mut impl Renderer<'s>, _area: Rect, _inverse: bool); fn width_center(&self) -> i16 { 0 } - fn paint_side(&self, _area: Rect) {} - fn render_side<'s>(&self, _target: &mut impl Renderer<'s>, _area: Rect) {} fn width_side(&self) -> i16 { @@ -218,43 +212,6 @@ where } } - /// Display current, previous and next choices according to - /// the current ChoiceItem. - fn paint_choices(&mut self) { - // Getting the row area for the choices - so that displaying - // items in the used font will show them in the middle vertically. - let area_height_half = self.pad.area.height() / 2; - let font_size_half = theme::FONT_CHOICE_ITEMS.allcase_text_height() / 2; - let center_row_area = self - .pad - .area - .split_top(area_height_half) - .0 - .outset(Insets::bottom(font_size_half)); - - // Drawing the current item in the middle. - self.show_current_choice(center_row_area); - - // Not drawing the rest when not wanted - if self.show_only_one_item { - return; - } - - // Getting the remaining left and right areas. - let center_width = self.get_current_item().width_center(); - let (left_area, _center_area, right_area) = center_row_area.split_center(center_width); - - // Possibly drawing on the left side. - if self.has_previous_choice() || self.is_carousel { - self.show_left_choices(left_area); - } - - // Possibly drawing on the right side. - if self.has_next_choice() || self.is_carousel { - self.show_right_choices(right_area); - } - } - /// Display current, previous and next choices according to /// the current ChoiceItem. fn render_choices<'s>(&'s self, target: &mut impl Renderer<'s>) { @@ -270,7 +227,7 @@ where .outset(Insets::bottom(font_size_half)); // Drawing the current item in the middle. - self.show_current_choice2(target, center_row_area); + self.show_current_choice(target, center_row_area); // Not drawing the rest when not wanted if self.show_only_one_item { @@ -283,12 +240,12 @@ where // Possibly drawing on the left side. if self.has_previous_choice() || self.is_carousel { - self.show_left_choices2(target, left_area); + self.show_left_choices(target, left_area); } // Possibly drawing on the right side. if self.has_next_choice() || self.is_carousel { - self.show_right_choices2(target, right_area); + self.show_right_choices(target, right_area); } } @@ -335,62 +292,14 @@ where } /// Display the current choice in the middle. - fn show_current_choice(&mut self, area: Rect) { - self.get_current_item() - .paint_center(area, self.inverse_selected_item); - } - - /// Display the current choice in the middle. - fn show_current_choice2<'s>(&'s self, target: &mut impl Renderer<'s>, area: Rect) { + fn show_current_choice<'s>(&'s self, target: &mut impl Renderer<'s>, area: Rect) { self.get_current_item() .render_center(target, area, self.inverse_selected_item); } /// Display all the choices fitting on the left side. /// Going as far as possible. - fn show_left_choices(&self, area: Rect) { - // NOTE: page index can get negative here, so having it as i16 instead of usize - let mut page_index = self.page_counter as i16 - 1; - let mut current_area = area.split_right(self.items_distance).0; - while current_area.width() > 0 { - // Breaking out of the loop if we exhausted left items - // and the carousel mode is not enabled. - if page_index < 0 { - if self.is_carousel { - // Moving to the last page. - page_index = self.last_page_index() as i16; - } else { - break; - } - } - - let (choice, _) = self.choices.get(page_index as usize); - let choice_width = choice.width_side(); - - if current_area.width() <= choice_width && !self.show_incomplete { - // early break for an item that will not fit the remaining space - break; - } - - // We need to calculate the area explicitly because we want to allow it - // to exceed the bounds of the original area. - let choice_area = Rect::from_top_right_and_size( - current_area.top_right(), - Offset::new(choice_width, current_area.height()), - ); - choice.paint_side(choice_area); - - // Updating loop variables. - current_area = current_area - .split_right(choice_width + self.items_distance) - .0; - page_index -= 1; - } - } - - /// Display all the choices fitting on the left side. - /// Going as far as possible. - fn show_left_choices2<'s>(&'s self, target: &mut impl Renderer<'s>, area: Rect) { + fn show_left_choices<'s>(&'s self, target: &mut impl Renderer<'s>, area: Rect) { // NOTE: page index can get negative here, so having it as i16 instead of usize let mut page_index = self.page_counter as i16 - 1; let mut current_area = area.split_right(self.items_distance).0; @@ -432,48 +341,7 @@ where /// Display all the choices fitting on the right side. /// Going as far as possible. - fn show_right_choices(&self, area: Rect) { - let mut page_index = self.page_counter + 1; - let mut current_area = area.split_left(self.items_distance).1; - while current_area.width() > 0 { - // Breaking out of the loop if we exhausted right items - // and the carousel mode is not enabled. - if page_index > self.last_page_index() { - if self.is_carousel { - // Moving to the first page. - page_index = 0; - } else { - break; - } - } - - let (choice, _) = self.choices.get(page_index); - let choice_width = choice.width_side(); - - if current_area.width() <= choice_width && !self.show_incomplete { - // early break for an item that will not fit the remaining space - break; - } - - // We need to calculate the area explicitly because we want to allow it - // to exceed the bounds of the original area. - let choice_area = Rect::from_top_left_and_size( - current_area.top_left(), - Offset::new(choice_width, current_area.height()), - ); - choice.paint_side(choice_area); - - // Updating loop variables. - current_area = current_area - .split_left(choice_width + self.items_distance) - .1; - page_index += 1; - } - } - - /// Display all the choices fitting on the right side. - /// Going as far as possible. - fn show_right_choices2<'s>(&'s self, target: &mut impl Renderer<'s>, area: Rect) { + fn show_right_choices<'s>(&'s self, target: &mut impl Renderer<'s>, area: Rect) { let mut page_index = self.page_counter + 1; let mut current_area = area.split_left(self.items_distance).1; while current_area.width() > 0 { @@ -714,12 +582,6 @@ where None } - fn paint(&mut self) { - self.pad.paint(); - self.buttons.paint(); - self.paint_choices(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); self.buttons.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/choice_item.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/choice_item.rs index e40ce39d2e..d260cd3b58 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/choice_item.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/choice_item.rs @@ -1,7 +1,7 @@ use crate::{ strutil::ShortString, ui::{ - display::{self, rect_fill, rect_fill_corners, rect_outline_rounded, Font, Icon}, + display::{Font, Icon}, geometry::{Alignment2D, Offset, Rect}, shape, shape::Renderer, @@ -90,25 +90,6 @@ impl ChoiceItem { } impl Choice for ChoiceItem { - /// Painting the item as the main choice in the middle. - /// Showing both the icon and text, if the icon is available. - fn paint_center(&self, area: Rect, inverse: bool) { - let width = text_icon_width(Some(self.text.as_ref()), self.icon, self.font); - paint_rounded_highlight( - area, - Offset::new(width, self.font.allcase_text_height()), - inverse, - ); - paint_text_icon( - area, - width, - Some(self.text.as_ref()), - self.icon, - self.font, - inverse, - ); - } - /// Painting the item as the main choice in the middle. /// Showing both the icon and text, if the icon is available. fn render_center<'s>(&self, target: &mut impl Renderer<'s>, area: Rect, inverse: bool) { @@ -142,12 +123,6 @@ impl Choice for ChoiceItem { text_icon_width(self.side_text(), self.icon, self.font) } - /// Painting smaller version of the item on the side. - fn paint_side(&self, area: Rect) { - let width = text_icon_width(self.side_text(), self.icon, self.font); - paint_text_icon(area, width, self.side_text(), self.icon, self.font, false); - } - /// Painting smaller version of the item on the side. fn render_side<'s>(&self, target: &mut impl Renderer<'s>, area: Rect) { let width = text_icon_width(self.side_text(), self.icon, self.font); @@ -173,21 +148,6 @@ impl Choice for ChoiceItem { } } -fn paint_rounded_highlight(area: Rect, size: Offset, inverse: bool) { - let bound = theme::BUTTON_OUTLINE; - let left_bottom = area.bottom_center() + Offset::new(-size.x / 2 - bound, bound + 1); - let x_size = size.x + 2 * bound; - let y_size = size.y + 2 * bound; - let outline_size = Offset::new(x_size, y_size); - let outline = Rect::from_bottom_left_and_size(left_bottom, outline_size); - if inverse { - rect_fill(outline, theme::FG); - rect_fill_corners(outline, theme::BG); - } else { - rect_outline_rounded(outline, theme::FG, theme::BG, 1); - } -} - fn render_rounded_highlight<'s>( target: &mut impl Renderer<'s>, area: Rect, @@ -230,38 +190,6 @@ fn text_icon_width(text: Option<&str>, icon: Option, font: Font) -> i16 { } } -fn paint_text_icon( - area: Rect, - width: i16, - text: Option<&str>, - icon: Option, - font: Font, - inverse: bool, -) { - let fg_color = if inverse { theme::BG } else { theme::FG }; - let bg_color = if inverse { theme::FG } else { theme::BG }; - - let mut baseline = area.bottom_center() - Offset::x(width / 2); - if let Some(icon) = icon { - let height_diff = font.allcase_text_height() - icon.toif.height(); - let vertical_offset = Offset::y(-height_diff / 2); - icon.draw( - baseline + vertical_offset, - Alignment2D::BOTTOM_LEFT, - fg_color, - bg_color, - ); - baseline = baseline + Offset::x(icon.toif.width() + ICON_RIGHT_PADDING); - } - - if let Some(text) = text { - // Possibly shifting the baseline left, when there is a text bearing. - // This is to center the text properly. - baseline = baseline - Offset::x(font.start_x_bearing(text)); - display::text_left(baseline, text, font, fg_color, bg_color); - } -} - fn render_text_icon<'s>( target: &mut impl Renderer<'s>, area: Rect, diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/number_input.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/number_input.rs index 83f944bbe0..04e54f921d 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/number_input.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/number_input.rs @@ -79,10 +79,6 @@ impl Component for NumberInput { self.choice_page.event(ctx, event).map(|evt| evt.0) } - fn paint(&mut self) { - self.choice_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.choice_page.render(target); } diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/passphrase.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/passphrase.rs index 9fb05a2b5a..b0335b7573 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/passphrase.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/passphrase.rs @@ -448,11 +448,6 @@ impl Component for PassphraseEntry { None } - fn paint(&mut self) { - self.passphrase_dots.paint(); - self.choice_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.passphrase_dots.render(target); self.choice_page.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/pin.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/pin.rs index ab2de7be0e..5336282a80 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/pin.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/pin.rs @@ -316,12 +316,6 @@ impl Component for PinEntry<'_> { None } - fn paint(&mut self) { - self.header_line.paint(); - self.pin_line.paint(); - self.choice_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.header_line.render(target); self.pin_line.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/simple_choice.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/simple_choice.rs index f322c8cf17..46d60429b2 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/simple_choice.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/simple_choice.rs @@ -113,10 +113,6 @@ impl Component for SimpleChoice { self.choice_page.event(ctx, event).map(|evt| evt.0) } - fn paint(&mut self) { - self.choice_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.choice_page.render(target); } diff --git a/core/embed/rust/src/ui/model_tr/component/input_methods/wordlist.rs b/core/embed/rust/src/ui/model_tr/component/input_methods/wordlist.rs index df622a01d5..937cc056fb 100644 --- a/core/embed/rust/src/ui/model_tr/component/input_methods/wordlist.rs +++ b/core/embed/rust/src/ui/model_tr/component/input_methods/wordlist.rs @@ -308,11 +308,6 @@ impl Component for WordlistEntry { None } - fn paint(&mut self) { - self.chosen_letters.paint(); - self.choice_page.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.chosen_letters.render(target); self.choice_page.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/loader.rs b/core/embed/rust/src/ui/model_tr/component/loader.rs index 799bfb19a9..70f2469db9 100644 --- a/core/embed/rust/src/ui/model_tr/component/loader.rs +++ b/core/embed/rust/src/ui/model_tr/component/loader.rs @@ -153,20 +153,6 @@ impl Loader { matches!(self.progress(now), Some(display::LOADER_MIN)) } - pub fn paint_loader(&mut self, style: &LoaderStyle, done: i32) { - // NOTE: need to calculate this in `i32`, it would overflow using `i16` - let invert_from = ((self.area.width() as i32 + 1) * done) / (display::LOADER_MAX as i32); - - display::bar_with_text_and_fill( - self.area, - Some(&self.text_overlay), - style.fg_color, - style.bg_color, - -1, - invert_from as i16, - ); - } - pub fn render_loader<'s>( &'s self, target: &mut impl Renderer<'s>, @@ -249,28 +235,6 @@ impl Component for Loader { None } - fn paint(&mut self) { - // TODO: Consider passing the current instant along with the event -- that way, - // we could synchronize painting across the component tree. Also could be useful - // in automated tests. - // In practice, taking the current instant here is more precise in case some - // other component in the tree takes a long time to draw. - let now = Instant::now(); - - if let State::Initial = self.state { - self.paint_loader(self.styles.normal, 0); - } else if let State::Grown = self.state { - self.paint_loader(self.styles.normal, display::LOADER_MAX as i32); - } else { - let progress = self.progress(now); - if let Some(done) = progress { - self.paint_loader(self.styles.normal, done as i32); - } else { - self.paint_loader(self.styles.normal, 0); - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // TODO: Consider passing the current instant along with the event -- that way, // we could synchronize painting across the component tree. Also could be useful @@ -389,10 +353,6 @@ impl Component for ProgressLoader { None } - fn paint(&mut self) { - self.loader.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.loader.render(target); } diff --git a/core/embed/rust/src/ui/model_tr/component/mod.rs b/core/embed/rust/src/ui/model_tr/component/mod.rs index 2fdc1b8227..5f3ee9d654 100644 --- a/core/embed/rust/src/ui/model_tr/component/mod.rs +++ b/core/embed/rust/src/ui/model_tr/component/mod.rs @@ -1,7 +1,6 @@ pub mod bl_confirm; mod button; mod button_controller; -mod common; mod error; mod hold_to_confirm; mod input_methods; diff --git a/core/embed/rust/src/ui/model_tr/component/page.rs b/core/embed/rust/src/ui/model_tr/component/page.rs index 7179367bb5..836d9d4c17 100644 --- a/core/embed/rust/src/ui/model_tr/component/page.rs +++ b/core/embed/rust/src/ui/model_tr/component/page.rs @@ -254,12 +254,6 @@ where None } - fn paint(&mut self) { - self.pad.paint(); - self.content.paint(); - self.buttons.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); self.content.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/progress.rs b/core/embed/rust/src/ui/model_tr/component/progress.rs index 045078f336..081e7e9cb9 100644 --- a/core/embed/rust/src/ui/model_tr/component/progress.rs +++ b/core/embed/rust/src/ui/model_tr/component/progress.rs @@ -9,7 +9,7 @@ use crate::{ Child, Component, Event, EventCtx, Label, Never, Pad, }, constant, - display::{self, Font, Icon, LOADER_MAX}, + display::{Font, Icon, LOADER_MAX}, geometry::{Alignment2D, Offset, Rect}, model_tr::cshape, shape, @@ -134,29 +134,6 @@ impl Component for Progress { None } - fn paint(&mut self) { - self.title.paint(); - if self.indeterminate { - display::loader_indeterminate( - self.value, - self.loader_y_offset, - theme::FG, - theme::BG, - None, - ); - } else { - display::loader( - self.value, - self.loader_y_offset, - theme::FG, - theme::BG, - Some((self.icon, theme::FG)), - ); - } - self.description_pad.paint(); - self.description.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.title.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/result.rs b/core/embed/rust/src/ui/model_tr/component/result.rs index 32f20f418b..1956ed52b6 100644 --- a/core/embed/rust/src/ui/model_tr/component/result.rs +++ b/core/embed/rust/src/ui/model_tr/component/result.rs @@ -95,21 +95,6 @@ impl Component for ResultScreen<'_> { None } - fn paint(&mut self) { - self.bg.paint(); - self.small_pad.paint(); - - self.icon.draw( - screen().top_center() + Offset::y(ICON_TOP), - Alignment2D::CENTER, - self.fg_color, - self.bg_color, - ); - - self.message_top.paint(); - self.message_bottom.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.small_pad.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/scrollbar.rs b/core/embed/rust/src/ui/model_tr/component/scrollbar.rs index 3e812ee91a..04514382b2 100644 --- a/core/embed/rust/src/ui/model_tr/component/scrollbar.rs +++ b/core/embed/rust/src/ui/model_tr/component/scrollbar.rs @@ -1,6 +1,5 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never, Pad, Paginate}, - display, geometry::{Offset, Point, Rect}, shape, shape::Renderer, @@ -66,45 +65,6 @@ impl ScrollBar { self.page_count = page_count; } - /// Create a (seemingly circular) dot given its top left point. - /// Make it full when it is active, otherwise paint just the perimeter and - /// leave center empty. - fn paint_dot(&self, dot_type: &DotType, top_right: Point) { - let full_square = - Rect::from_top_right_and_size(top_right, Offset::uniform(Self::MAX_DOT_SIZE)); - - match dot_type { - DotType::BigFull | DotType::Big => { - // FG - painting the full square - display::rect_fill(full_square, theme::FG); - - // BG - erase four corners - display::rect_fill_corners(full_square, theme::BG); - - // BG - erasing the middle when not full - if matches!(dot_type, DotType::Big) { - display::rect_fill(full_square.shrink(1), theme::BG) - } - } - DotType::Middle => { - let middle_square = full_square.shrink(1); - - // FG - painting the middle square - display::rect_fill(middle_square, theme::FG); - - // BG - erase four corners - display::rect_fill_corners(middle_square, theme::BG); - - // BG - erasing the middle - display::rect_fill(middle_square.shrink(1), theme::BG) - } - DotType::Small => { - // FG - painting the small square - display::rect_fill(full_square.shrink(2), theme::FG) - } - } - } - /// Create a (seemingly circular) dot given its top left point. /// Make it full when it is active, otherwise paint just the perimeter and /// leave center empty. @@ -225,15 +185,6 @@ impl ScrollBar { dots } - /// Drawing the dots horizontally and aligning to the right. - fn paint_horizontal(&mut self) { - let mut top_right = self.pad.area.top_right(); - for dot in self.get_drawable_dots().iter().rev() { - self.paint_dot(dot, top_right); - top_right.x -= Self::DOTS_INTERVAL; - } - } - fn render_horizontal<'s>(&'s self, target: &mut impl Renderer<'s>) { let mut top_right = self.pad.area.top_right(); for dot in self.get_drawable_dots().iter().rev() { @@ -261,18 +212,6 @@ impl Component for ScrollBar { None } - /// Displaying one dot for each page. - fn paint(&mut self) { - // Not showing the scrollbar dot when there is only one page - if self.page_count <= 1 { - return; - } - - self.pad.clear(); - self.pad.paint(); - self.paint_horizontal(); - } - /// Displaying one dot for each page. fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // Not showing the scrollbar dot when there is only one page diff --git a/core/embed/rust/src/ui/model_tr/component/share_words.rs b/core/embed/rust/src/ui/model_tr/component/share_words.rs index 0ec10399d3..4a603db85b 100644 --- a/core/embed/rust/src/ui/model_tr/component/share_words.rs +++ b/core/embed/rust/src/ui/model_tr/component/share_words.rs @@ -3,8 +3,7 @@ use crate::{ translations::TR, ui::{ component::{ - text::util::{text_multiline, text_multiline2}, - Child, Component, Event, EventCtx, Never, Paginate, + text::util::text_multiline, Child, Component, Event, EventCtx, Never, Paginate, }, display::Font, geometry::{Alignment, Offset, Rect}, @@ -16,7 +15,7 @@ use heapless::Vec; #[cfg(feature = "ui_debug")] use ufmt::uwrite; -use super::{common::display_left, scrollbar::SCROLLBAR_SPACE, theme, ScrollBar}; +use super::{scrollbar::SCROLLBAR_SPACE, theme, ScrollBar}; const WORDS_PER_PAGE: usize = 3; const EXTRA_LINE_HEIGHT: i16 = -2; @@ -75,23 +74,10 @@ impl<'a> ShareWords<'a> { }) } - /// Display the final page with user confirmation. - fn paint_final_page(&mut self) { - let final_text = self.get_final_text(); - text_multiline( - self.area.split_top(INFO_TOP_OFFSET).1, - final_text.as_str().into(), - Font::NORMAL, - theme::FG, - theme::BG, - Alignment::Start, - ); - } - /// Display the final page with user confirmation. fn render_final_page<'s>(&'s self, target: &mut impl Renderer<'s>) { let final_text = self.get_final_text(); - text_multiline2( + text_multiline( target, self.area.split_top(INFO_TOP_OFFSET).1, final_text.as_str().into(), @@ -102,26 +88,6 @@ impl<'a> ShareWords<'a> { ); } - /// Display current set of recovery words. - fn paint_words(&mut self) { - let mut y_offset = 0; - // Showing the word index and the words itself - for i in 0..WORDS_PER_PAGE { - y_offset += NUMBER_FONT.line_height() + EXTRA_LINE_HEIGHT; - let index = self.word_index() + i; - if index >= self.share_words.len() { - break; - } - let baseline = self.area.top_left() + Offset::y(y_offset); - let ordinal = uformat!("{}.", index + 1); - display_left(baseline + Offset::x(NUMBER_X_OFFSET), &ordinal, NUMBER_FONT); - let word = &self.share_words[index]; - word.map(|w| { - display_left(baseline + Offset::x(WORD_X_OFFSET), w, WORD_FONT); - }); - } - } - /// Display current set of recovery words. fn render_words<'s>(&'s self, target: &mut impl Renderer<'s>) { let mut y_offset = 0; @@ -171,17 +137,6 @@ impl<'a> Component for ShareWords<'a> { None } - fn paint(&mut self) { - // Showing scrollbar in all cases - // Individual pages are responsible for not colliding with it - self.scrollbar.paint(); - if self.is_final_page() { - self.paint_final_page(); - } else { - self.paint_words(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // Showing scrollbar in all cases // Individual pages are responsible for not colliding with it diff --git a/core/embed/rust/src/ui/model_tr/component/show_more.rs b/core/embed/rust/src/ui/model_tr/component/show_more.rs index 8f8dae0f65..f846990e24 100644 --- a/core/embed/rust/src/ui/model_tr/component/show_more.rs +++ b/core/embed/rust/src/ui/model_tr/component/show_more.rs @@ -75,11 +75,6 @@ where None } - fn paint(&mut self) { - self.content.paint(); - self.buttons.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.content.render(target); self.buttons.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/title.rs b/core/embed/rust/src/ui/model_tr/component/title.rs index a34e4a288d..e79a958442 100644 --- a/core/embed/rust/src/ui/model_tr/component/title.rs +++ b/core/embed/rust/src/ui/model_tr/component/title.rs @@ -3,7 +3,6 @@ use crate::{ time::Instant, ui::{ component::{Component, Event, EventCtx, Marquee, Never}, - display, geometry::{Alignment, Offset, Rect}, shape, shape::Renderer, @@ -52,15 +51,6 @@ impl Title { } } - /// Display title/header at the top left of the given area. - pub fn paint_header_left(title: &TString<'static>, area: Rect) { - let text_height = theme::FONT_HEADER.text_height(); - let title_baseline = area.top_left() + Offset::y(text_height - 1); - title.map(|s| { - display::text_left(title_baseline, s, theme::FONT_HEADER, theme::FG, theme::BG) - }); - } - /// Display title/header at the top left of the given area. pub fn render_header_left<'s>( target: &mut impl Renderer<'s>, @@ -77,15 +67,6 @@ impl Title { }); } - /// Display title/header centered at the top of the given area. - pub fn paint_header_centered(title: &TString<'static>, area: Rect) { - let text_height = theme::FONT_HEADER.text_height(); - let title_baseline = area.top_center() + Offset::y(text_height - 1); - title.map(|s| { - display::text_center(title_baseline, s, theme::FONT_HEADER, theme::FG, theme::BG) - }); - } - /// Display title/header centered at the top of the given area. pub fn render_header_centered<'s>( target: &mut impl Renderer<'s>, @@ -125,16 +106,6 @@ impl Component for Title { None } - fn paint(&mut self) { - if self.needs_marquee { - self.marquee.paint(); - } else if self.centered { - Self::paint_header_centered(&self.title, self.area); - } else { - Self::paint_header_left(&self.title, self.area); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if self.needs_marquee { self.marquee.render(target); diff --git a/core/embed/rust/src/ui/model_tr/component/welcome_screen.rs b/core/embed/rust/src/ui/model_tr/component/welcome_screen.rs index a824d85e77..ff21841ef2 100644 --- a/core/embed/rust/src/ui/model_tr/component/welcome_screen.rs +++ b/core/embed/rust/src/ui/model_tr/component/welcome_screen.rs @@ -35,26 +35,6 @@ impl Component for WelcomeScreen { None } - fn paint(&mut self) { - theme::ICON_DEVICE_NAME.draw( - self.area.bottom_center() - Offset::y(5), - Alignment2D::BOTTOM_CENTER, - theme::FG, - theme::BG, - ); - let icon = if self.empty_lock { - theme::ICON_LOGO_EMPTY - } else { - theme::ICON_LOGO - }; - icon.draw( - self.area.top_center() + Offset::y(ICON_TOP_MARGIN), - Alignment2D::TOP_CENTER, - theme::FG, - theme::BG, - ); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { shape::ToifImage::new( self.area.bottom_center() - Offset::y(5), diff --git a/core/embed/rust/src/ui/model_tr/res/arrow_down.toif b/core/embed/rust/src/ui/model_tr/res/arrow_down.toif index 829b50e9a3..790976e6c4 100644 Binary files a/core/embed/rust/src/ui/model_tr/res/arrow_down.toif and b/core/embed/rust/src/ui/model_tr/res/arrow_down.toif differ diff --git a/core/embed/rust/src/ui/model_tr/res/arrow_down_o.toif b/core/embed/rust/src/ui/model_tr/res/arrow_down_o.toif deleted file mode 100644 index 790976e6c4..0000000000 Binary files a/core/embed/rust/src/ui/model_tr/res/arrow_down_o.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tr/res/arrow_up.toif b/core/embed/rust/src/ui/model_tr/res/arrow_up.toif index 848a79b100..03930d53c6 100644 Binary files a/core/embed/rust/src/ui/model_tr/res/arrow_up.toif and b/core/embed/rust/src/ui/model_tr/res/arrow_up.toif differ diff --git a/core/embed/rust/src/ui/model_tr/res/arrow_up_o.toif b/core/embed/rust/src/ui/model_tr/res/arrow_up_o.toif deleted file mode 100644 index 03930d53c6..0000000000 Binary files a/core/embed/rust/src/ui/model_tr/res/arrow_up_o.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tr/res/cancel.toif b/core/embed/rust/src/ui/model_tr/res/cancel.toif index cdffa44526..6b7971a365 100644 Binary files a/core/embed/rust/src/ui/model_tr/res/cancel.toif and b/core/embed/rust/src/ui/model_tr/res/cancel.toif differ diff --git a/core/embed/rust/src/ui/model_tr/res/cancel_o.toif b/core/embed/rust/src/ui/model_tr/res/cancel_o.toif deleted file mode 100644 index 6b7971a365..0000000000 Binary files a/core/embed/rust/src/ui/model_tr/res/cancel_o.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tr/res/delete.toif b/core/embed/rust/src/ui/model_tr/res/delete.toif index 04cf849f95..763945b55f 100644 Binary files a/core/embed/rust/src/ui/model_tr/res/delete.toif and b/core/embed/rust/src/ui/model_tr/res/delete.toif differ diff --git a/core/embed/rust/src/ui/model_tr/res/delete_o.toif b/core/embed/rust/src/ui/model_tr/res/delete_o.toif deleted file mode 100644 index 763945b55f..0000000000 Binary files a/core/embed/rust/src/ui/model_tr/res/delete_o.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tr/res/next_page.toif b/core/embed/rust/src/ui/model_tr/res/next_page.toif index 8e892e4084..2efb606dc0 100644 Binary files a/core/embed/rust/src/ui/model_tr/res/next_page.toif and b/core/embed/rust/src/ui/model_tr/res/next_page.toif differ diff --git a/core/embed/rust/src/ui/model_tr/res/next_page_o.toif b/core/embed/rust/src/ui/model_tr/res/next_page_o.toif deleted file mode 100644 index 2efb606dc0..0000000000 Binary files a/core/embed/rust/src/ui/model_tr/res/next_page_o.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tr/res/warning.toif b/core/embed/rust/src/ui/model_tr/res/warning.toif index b9506149be..f6fd6c78c0 100644 Binary files a/core/embed/rust/src/ui/model_tr/res/warning.toif and b/core/embed/rust/src/ui/model_tr/res/warning.toif differ diff --git a/core/embed/rust/src/ui/model_tr/res/warning_o.toif b/core/embed/rust/src/ui/model_tr/res/warning_o.toif deleted file mode 100644 index f6fd6c78c0..0000000000 Binary files a/core/embed/rust/src/ui/model_tr/res/warning_o.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tr/screens.rs b/core/embed/rust/src/ui/model_tr/screens.rs index 9bf323b681..347ad2eb33 100644 --- a/core/embed/rust/src/ui/model_tr/screens.rs +++ b/core/embed/rust/src/ui/model_tr/screens.rs @@ -2,7 +2,6 @@ use crate::ui::{ component::base::Component, constant::screen, display, model_tr::component::WelcomeScreen, }; -#[cfg(feature = "new_rendering")] use crate::ui::{display::Color, shape::render_on_display}; use super::{component::ErrorScreen, constant}; @@ -11,13 +10,10 @@ pub fn screen_fatal_error(title: &str, msg: &str, footer: &str) { let mut frame = ErrorScreen::new(title.into(), msg.into(), footer.into()); frame.place(constant::screen()); - #[cfg(feature = "new_rendering")] render_on_display(None, Some(Color::black()), |target| { frame.render(target); }); - #[cfg(not(feature = "new_rendering"))] - frame.paint(); display::refresh(); } @@ -25,19 +21,9 @@ pub fn screen_boot_stage_2() { let mut frame = WelcomeScreen::new(false); frame.place(screen()); - #[cfg(feature = "new_rendering")] - { - display::sync(); - render_on_display(None, Some(Color::black()), |target| { - frame.render(target); - }); - display::refresh(); - } - - #[cfg(not(feature = "new_rendering"))] - { - display::sync(); - frame.paint(); - display::refresh(); - } + display::sync(); + render_on_display(None, Some(Color::black()), |target| { + frame.render(target); + }); + display::refresh(); } diff --git a/core/embed/rust/src/ui/model_tr/theme/mod.rs b/core/embed/rust/src/ui/model_tr/theme/mod.rs index df9be8f458..5874a39053 100644 --- a/core/embed/rust/src/ui/model_tr/theme/mod.rs +++ b/core/embed/rust/src/ui/model_tr/theme/mod.rs @@ -71,68 +71,25 @@ include_icon!(ICON_ARROW_LEFT, "model_tr/res/arrow_left.toif"); // 4*7 include_icon!(ICON_ARROW_LEFT_BIG, "model_tr/res/arrow_left_big.toif"); // 8*7 include_icon!(ICON_ARROW_RIGHT, "model_tr/res/arrow_right.toif"); // 4*7 include_icon!(ICON_ARROW_RIGHT_FAT, "model_tr/res/arrow_right_fat.toif"); // 4*8 -#[cfg(not(feature = "new_rendering"))] -include_icon!( - ICON_ARROW_UP, - "model_tr/res/arrow_up.toif", - empty_right_col = true -); // 8*4 -#[cfg(feature = "new_rendering")] -include_icon!(ICON_ARROW_UP, "model_tr/res/arrow_up_o.toif"); // 8*4 -#[cfg(not(feature = "new_rendering"))] -include_icon!( - ICON_ARROW_DOWN, - "model_tr/res/arrow_down.toif", - empty_right_col = true -); // 8*4 -#[cfg(feature = "new_rendering")] -include_icon!(ICON_ARROW_DOWN, "model_tr/res/arrow_down_o.toif"); // 7*4 +include_icon!(ICON_ARROW_UP, "model_tr/res/arrow_up.toif"); // 8*4 +include_icon!(ICON_ARROW_DOWN, "model_tr/res/arrow_down.toif"); // 7*4 include_icon!(ICON_ARROW_BACK_UP, "model_tr/res/arrow_back_up.toif"); // 8*8 include_icon!(ICON_BIN, "model_tr/res/bin.toif"); // 10*10 -#[cfg(not(feature = "new_rendering"))] -include_icon!( - ICON_CANCEL, - "model_tr/res/cancel.toif", - empty_right_col = true -); // 7*7 -#[cfg(feature = "new_rendering")] -include_icon!(ICON_CANCEL, "model_tr/res/cancel_o.toif"); // 7*7 +include_icon!(ICON_CANCEL, "model_tr/res/cancel.toif"); // 7*7 include_icon!(ICON_COINJOIN, "model_tr/res/coinjoin.toif"); // 12*12 -#[cfg(not(feature = "new_rendering"))] -include_icon!( - ICON_DELETE, - "model_tr/res/delete.toif", - empty_right_col = true -); // 9*7 -#[cfg(feature = "new_rendering")] -include_icon!(ICON_DELETE, "model_tr/res/delete_o.toif"); // 9*7 +include_icon!(ICON_DELETE, "model_tr/res/delete.toif"); // 9*7 include_icon!(ICON_DEVICE_NAME, "model_tr/res/device_name.toif"); // 116*18 include_icon!(ICON_EYE, "model_tr/res/eye_round.toif"); // 12*7 include_icon!(ICON_LOCK, "model_tr/res/lock.toif"); // 10*10 include_icon!(ICON_LOCK_SMALL, "model_tr/res/lock_small.toif"); // 6*7 include_icon!(ICON_LOGO, "model_tr/res/logo_22_33.toif"); // 22*33 include_icon!(ICON_LOGO_EMPTY, "model_tr/res/logo_22_33_empty.toif"); -#[cfg(not(feature = "new_rendering"))] -include_icon!( - ICON_NEXT_PAGE, - "model_tr/res/next_page.toif", - empty_right_col = true -); // 10*8 -#[cfg(feature = "new_rendering")] -include_icon!(ICON_NEXT_PAGE, "model_tr/res/next_page_o.toif"); // 9*8 +include_icon!(ICON_NEXT_PAGE, "model_tr/res/next_page.toif"); // 9*8 include_icon!(ICON_PREV_PAGE, "model_tr/res/prev_page.toif"); // 8*10 include_icon!(ICON_SPACE, "model_tr/res/space.toif"); // 12*3 include_icon!(ICON_TICK, "model_tr/res/tick.toif"); // 8*6 include_icon!(ICON_TICK_FAT, "model_tr/res/tick_fat.toif"); // 8*6 -#[cfg(not(feature = "new_rendering"))] -include_icon!( - ICON_WARNING, - "model_tr/res/warning.toif", - empty_right_col = true -); // 12*12 -#[cfg(feature = "new_rendering")] -include_icon!(ICON_WARNING, "model_tr/res/warning_o.toif"); // 11*12 - +include_icon!(ICON_WARNING, "model_tr/res/warning.toif"); // 11*12 include_icon!(ICON_WARN_TITLE, "model_tr/res/bld_header_warn.toif"); // checklist settings diff --git a/core/embed/rust/src/ui/model_tt/bootloader/intro.rs b/core/embed/rust/src/ui/model_tt/bootloader/intro.rs index b66d2b11bf..f65b74b59b 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/intro.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/intro.rs @@ -97,15 +97,6 @@ impl<'a> Component for Intro<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - self.title.paint(); - self.text.paint(); - self.warn.paint(); - self.host.paint(); - self.menu.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.title.render(target); diff --git a/core/embed/rust/src/ui/model_tt/bootloader/menu.rs b/core/embed/rust/src/ui/model_tt/bootloader/menu.rs index 37049aa70a..9838381340 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/menu.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/menu.rs @@ -101,14 +101,6 @@ impl Component for Menu { None } - fn paint(&mut self) { - self.bg.paint(); - self.title.paint(); - self.close.paint(); - self.reboot.paint(); - self.reset.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.title.render(target); diff --git a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs index e83c6f9369..939d05b7bb 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs @@ -31,10 +31,6 @@ use super::{ use crate::ui::{ui_features::UIFeaturesBootloader, UIFeaturesCommon}; -#[cfg(not(feature = "new_rendering"))] -use super::theme::BLACK; - -#[cfg(feature = "new_rendering")] use crate::ui::{ display::toif::Toif, geometry::{Alignment, Alignment2D, Offset}, @@ -42,18 +38,14 @@ use crate::ui::{ shape::render_on_display, }; -#[cfg(feature = "new_rendering")] use ufmt::uwrite; -#[cfg(feature = "new_rendering")] use super::theme::bootloader::BLD_WARN_COLOR; use intro::Intro; use menu::Menu; -#[cfg(feature = "new_rendering")] use super::cshape::{render_loader, LoaderRange}; -#[cfg(feature = "new_rendering")] use crate::ui::display::LOADER_MAX; pub mod intro; @@ -67,35 +59,6 @@ const RECONNECT_MESSAGE: &str = "PLEASE RECONNECT\nTHE DEVICE"; const SCREEN: Rect = ModelTTFeatures::SCREEN; impl ModelTTFeatures { - #[cfg(not(feature = "new_rendering"))] - fn screen_progress( - text: &str, - progress: u16, - initialize: bool, - fg_color: Color, - bg_color: Color, - icon: Option<(Icon, Color)>, - ) { - if initialize { - Self::fadeout(); - display::rect_fill(SCREEN, bg_color); - } - - display::text_center( - Point::new(SCREEN.width() / 2, SCREEN.height() - 45), - text, - Font::NORMAL, - fg_color, - bg_color, - ); - display::loader(progress, -20, fg_color, bg_color, icon); - display::refresh(); - if initialize { - Self::fadein(); - } - } - - #[cfg(feature = "new_rendering")] fn screen_progress( text: &str, progress: u16, @@ -176,17 +139,6 @@ impl UIFeaturesBootloader for ModelTTFeatures { show(&mut frame, true); } - #[cfg(not(feature = "new_rendering"))] - fn bld_continue_label(bg_color: Color) { - display::text_center( - Point::new(SCREEN.width() / 2, SCREEN.height() - 5), - "click to continue ...", - Font::NORMAL, - BLD_FG, - bg_color, - ); - } - fn screen_install_success(restart_seconds: u8, initial_setup: bool, complete_draw: bool) { let mut reboot_msg = BootloaderString::new(); @@ -330,9 +282,6 @@ impl UIFeaturesBootloader for ModelTTFeatures { Self::fadeout(); } - #[cfg(not(feature = "new_rendering"))] - display::rect_fill(SCREEN, BLACK); - let mut frame = WelcomeScreen::new(true); show(&mut frame, false); @@ -398,7 +347,6 @@ impl UIFeaturesBootloader for ModelTTFeatures { show(&mut frame, true); } - #[cfg(feature = "new_rendering")] fn screen_boot( warning: bool, vendor_str: Option<&str>, diff --git a/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs b/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs index 0e2e3302fb..6eea6e8eea 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs @@ -1,11 +1,11 @@ use crate::ui::{ component::{Component, Event, EventCtx, Never, Pad}, constant::screen, - display::{self, toif::Toif, Font, Icon}, + display::{toif::Toif, Font}, geometry::{Alignment, Alignment2D, Offset, Rect}, model_tt::theme::{ bootloader::{START_URL, WELCOME_COLOR}, - BLACK, GREY_MEDIUM, WHITE, + GREY_MEDIUM, WHITE, }, shape, shape::Renderer, @@ -35,30 +35,6 @@ impl Component for Welcome { None } - fn paint(&mut self) { - self.bg.paint(); - display::text_center( - screen().top_center() + Offset::y(102), - "Get started with", - Font::NORMAL, - GREY_MEDIUM, - BLACK, - ); - display::text_center( - screen().top_center() + Offset::y(126), - "your Trezor at", - Font::NORMAL, - GREY_MEDIUM, - BLACK, - ); - Icon::new(START_URL).draw( - screen().top_center() + Offset::y(135), - Alignment2D::TOP_CENTER, - WHITE, - BLACK, - ); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/address_details.rs b/core/embed/rust/src/ui/model_tt/component/address_details.rs index 69b936299e..66c5433761 100644 --- a/core/embed/rust/src/ui/model_tt/component/address_details.rs +++ b/core/embed/rust/src/ui/model_tt/component/address_details.rs @@ -169,14 +169,6 @@ impl Component for AddressDetails { } } - fn paint(&mut self) { - match self.current_page { - 0 => self.qr_code.paint(), - 1 => self.details.paint(), - _ => self.xpub_view.paint(), - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { match self.current_page { 0 => self.qr_code.render(target), diff --git a/core/embed/rust/src/ui/model_tt/component/bl_confirm.rs b/core/embed/rust/src/ui/model_tt/component/bl_confirm.rs index 30526f3b66..cd66ef34f5 100644 --- a/core/embed/rust/src/ui/model_tt/component/bl_confirm.rs +++ b/core/embed/rust/src/ui/model_tt/component/bl_confirm.rs @@ -204,42 +204,6 @@ impl Component for Confirm<'_> { None } - fn paint(&mut self) { - self.bg.paint(); - self.content_pad.paint(); - - if let Some(info) = self.info.as_mut() { - if self.show_info { - info.close_button.paint(); - info.title.paint(); - info.text.paint(); - self.left_button.paint(); - self.right_button.paint(); - // short-circuit before painting the main components - return; - } else { - info.info_button.paint(); - // pass through to the rest of the paint - } - } - - self.message.paint(); - self.alert.paint(); - self.left_button.paint(); - self.right_button.paint(); - match &mut self.title { - ConfirmTitle::Text(label) => label.paint(), - ConfirmTitle::Icon(icon) => { - icon.draw( - Point::new(screen().center().x, ICON_TOP), - Alignment2D::TOP_CENTER, - WHITE, - self.bg_color, - ); - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.content_pad.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/button.rs b/core/embed/rust/src/ui/model_tt/component/button.rs index 1625055898..978025a379 100644 --- a/core/embed/rust/src/ui/model_tt/component/button.rs +++ b/core/embed/rust/src/ui/model_tt/component/button.rs @@ -7,7 +7,7 @@ use crate::{ component::{ Component, ComponentExt, Event, EventCtx, FixedHeightBar, MsgMap, Split, Timer, }, - display::{self, toif::Icon, Color, Font}, + display::{toif::Icon, Color, Font}, event::TouchEvent, geometry::{Alignment2D, Insets, Offset, Point, Rect}, shape::{self, Renderer}, @@ -164,38 +164,6 @@ impl Button { } } - pub fn paint_background(&self, style: &ButtonStyle) { - match &self.content { - ButtonContent::IconBlend(_, _, _) => {} - _ => { - if style.border_width > 0 { - // Paint the border and a smaller background on top of it. - display::rect_fill_rounded( - self.area, - style.border_color, - style.background_color, - style.border_radius, - ); - display::rect_fill_rounded( - self.area.inset(Insets::uniform(style.border_width)), - style.button_color, - style.border_color, - style.border_radius, - ); - } else { - // We do not need to draw an explicit border in this case, just a - // bigger background. - display::rect_fill_rounded( - self.area, - style.button_color, - style.background_color, - style.border_radius, - ); - } - } - } - } - pub fn render_background<'s>(&self, target: &mut impl Renderer<'s>, style: &ButtonStyle) { match &self.content { ButtonContent::IconBlend(_, _, _) => {} @@ -208,45 +176,6 @@ impl Button { } } - pub fn paint_content(&self, style: &ButtonStyle) { - match &self.content { - ButtonContent::Empty => {} - ButtonContent::Text(text) => { - let width = text.map(|c| style.font.text_width(c)); - let height = style.font.text_height(); - let start_of_baseline = self.area.center() - + Offset::new(-width / 2, height / 2) - + Offset::y(Self::BASELINE_OFFSET); - text.map(|text| { - display::text_left( - start_of_baseline, - text, - style.font, - style.text_color, - style.button_color, - ); - }); - } - ButtonContent::Icon(icon) => { - icon.draw( - self.area.center(), - Alignment2D::CENTER, - style.text_color, - style.button_color, - ); - } - ButtonContent::IconAndText(child) => { - child.paint(self.area, self.style(), Self::BASELINE_OFFSET); - } - ButtonContent::IconBlend(bg, fg, offset) => display::icon_over_icon( - Some(self.area), - (*bg, Offset::zero(), style.button_color), - (*fg, *offset, style.text_color), - style.background_color, - ), - } - } - pub fn render_content<'s>(&self, target: &mut impl Renderer<'s>, style: &ButtonStyle) { match &self.content { ButtonContent::Empty => {} @@ -368,12 +297,6 @@ impl Component for Button { None } - fn paint(&mut self) { - let style = self.style(); - self.paint_background(style); - self.paint_content(style); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let style = self.style(); self.render_background(target, style); @@ -591,53 +514,6 @@ impl IconText { Self { text, icon } } - pub fn paint(&self, area: Rect, style: &ButtonStyle, baseline_offset: i16) { - let width = style.font.text_width(self.text); - let height = style.font.text_height(); - - let mut use_icon = false; - let mut use_text = false; - - let mut icon_pos = Point::new( - area.top_left().x + ((Self::ICON_SPACE + Self::ICON_MARGIN) / 2), - area.center().y, - ); - let mut text_pos = - area.center() + Offset::new(-width / 2, height / 2) + Offset::y(baseline_offset); - - if area.width() > (Self::ICON_SPACE + Self::TEXT_MARGIN + width) { - //display both icon and text - text_pos = Point::new(area.top_left().x + Self::ICON_SPACE, text_pos.y); - use_text = true; - use_icon = true; - } else if area.width() > (width + Self::TEXT_MARGIN) { - use_text = true; - } else { - //if we can't fit the text, retreat to centering the icon - icon_pos = area.center(); - use_icon = true; - } - - if use_text { - display::text_left( - text_pos, - self.text, - style.font, - style.text_color, - style.button_color, - ); - } - - if use_icon { - self.icon.draw( - icon_pos, - Alignment2D::CENTER, - style.text_color, - style.button_color, - ); - } - } - pub fn render<'s>( &self, target: &mut impl Renderer<'s>, diff --git a/core/embed/rust/src/ui/model_tt/component/coinjoin_progress.rs b/core/embed/rust/src/ui/model_tt/component/coinjoin_progress.rs index 4837c88ac9..a6f194dafb 100644 --- a/core/embed/rust/src/ui/model_tt/component/coinjoin_progress.rs +++ b/core/embed/rust/src/ui/model_tt/component/coinjoin_progress.rs @@ -10,7 +10,6 @@ use crate::{ base::Never, Bar, Child, Component, ComponentExt, Empty, Event, EventCtx, Label, Split, }, constant, - display::loader::{loader_circular_uncompress, LoaderDimensions}, geometry::{Insets, Offset, Rect}, shape, shape::Renderer, @@ -111,20 +110,6 @@ where None } - fn paint(&mut self) { - self.content.paint(); - loader_circular_uncompress( - LoaderDimensions::new(LOADER_OUTER, LOADER_INNER), - LOADER_OFFSET, - theme::FG, - theme::BG, - self.value, - self.indeterminate, - None, - ); - self.label.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.content.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/dialog.rs b/core/embed/rust/src/ui/model_tt/component/dialog.rs index 23679a4921..9301db912a 100644 --- a/core/embed/rust/src/ui/model_tt/component/dialog.rs +++ b/core/embed/rust/src/ui/model_tt/component/dialog.rs @@ -68,11 +68,6 @@ where .or_else(|| self.controls.event(ctx, event).map(Self::Msg::Controls)) } - fn paint(&mut self) { - self.content.paint(); - self.controls.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.content.render(target); self.controls.render(target); @@ -191,12 +186,6 @@ where self.controls.event(ctx, event).map(Self::Msg::Controls) } - fn paint(&mut self) { - self.image.paint(); - self.paragraphs.paint(); - self.controls.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.image.render(target); self.paragraphs.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/error.rs b/core/embed/rust/src/ui/model_tt/component/error.rs index 12d2bf064b..8f638b143e 100644 --- a/core/embed/rust/src/ui/model_tt/component/error.rs +++ b/core/embed/rust/src/ui/model_tt/component/error.rs @@ -77,21 +77,6 @@ impl<'a> Component for ErrorScreen<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - - let icon = ICON_WARNING40; - icon.draw( - Point::new(screen().center().x, ICON_TOP), - Alignment2D::TOP_CENTER, - WHITE, - FATAL_ERROR_COLOR, - ); - self.title.paint(); - self.message.paint(); - self.footer.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/fido.rs b/core/embed/rust/src/ui/model_tt/component/fido.rs index 2cb10950dc..84fcd3c701 100644 --- a/core/embed/rust/src/ui/model_tt/component/fido.rs +++ b/core/embed/rust/src/ui/model_tt/component/fido.rs @@ -184,36 +184,6 @@ where None } - fn paint(&mut self) { - self.icon.paint(); - self.controls.paint(); - self.app_name.paint(); - - if self.scrollbar.page_count > 1 { - self.scrollbar.paint(); - } - - // Erasing the old text content before writing the new one. - let account_name_area = self.account_name.area(); - let real_area = account_name_area - .with_height(account_name_area.height() + self.account_name.font().text_baseline() + 1); - display::rect_fill(real_area, theme::BG); - - // Account name is optional. - // Showing it only if it differs from app name. - // (Dummy requests usually have some text as both app_name and account_name.) - let account_name = self.account_name.text(); - let app_name = self.app_name.text(); - if !account_name.is_empty() && account_name != app_name { - self.account_name.paint(); - } - - if self.fade.take() { - // Note that this is blocking and takes some time. - display::fade_backlight(theme::backlight::get_backlight_normal()); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.icon.render(target); self.controls.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/frame.rs b/core/embed/rust/src/ui/model_tt/component/frame.rs index d989204e61..68a550cc4c 100644 --- a/core/embed/rust/src/ui/model_tt/component/frame.rs +++ b/core/embed/rust/src/ui/model_tt/component/frame.rs @@ -170,13 +170,6 @@ where self.content.event(ctx, event).map(FrameMsg::Content) } - fn paint(&mut self) { - self.title.paint(); - self.subtitle.paint(); - self.button.paint(); - self.content.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.title.render(target); self.subtitle.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/homescreen/mod.rs b/core/embed/rust/src/ui/model_tt/component/homescreen.rs similarity index 71% rename from core/embed/rust/src/ui/model_tt/component/homescreen/mod.rs rename to core/embed/rust/src/ui/model_tt/component/homescreen.rs index 4fd8f6f639..ba49a70083 100644 --- a/core/embed/rust/src/ui/model_tt/component/homescreen/mod.rs +++ b/core/embed/rust/src/ui/model_tt/component/homescreen.rs @@ -1,5 +1,3 @@ -mod render; - use crate::{ io::BinaryData, strutil::TString, @@ -7,11 +5,10 @@ use crate::{ translations::TR, trezorhal::usb::usb_configured, ui::{ - component::{Component, Event, EventCtx, Pad, Timer}, + component::{text::TextStyle, Component, Event, EventCtx, Pad, Timer}, display::{ - self, image::{ImageInfo, ToifFormat}, - toif::{Icon, Toif}, + toif::Icon, Color, Font, }, event::{TouchEvent, USBEvent}, @@ -22,20 +19,7 @@ use crate::{ }, }; -use crate::{ - trezorhal::{buffers::BufferJpegWork, uzlib::UZLIB_WINDOW_SIZE}, - ui::{ - constant::HEIGHT, - display::tjpgd::BufferInput, - model_tt::component::homescreen::render::{ - HomescreenJpeg, HomescreenToif, HOMESCREEN_TOIF_SIZE, - }, - }, -}; -use render::{ - homescreen, homescreen_blurred, HomescreenNotification, HomescreenText, - HOMESCREEN_IMAGE_HEIGHT, HOMESCREEN_IMAGE_WIDTH, -}; +use crate::ui::constant::{HEIGHT, WIDTH}; use super::{theme, Loader, LoaderMsg}; @@ -49,6 +33,24 @@ const COINJOIN_Y: i16 = 30; const LOADER_OFFSET: Offset = Offset::y(-10); const LOADER_DELAY: Duration = Duration::from_millis(500); const LOADER_DURATION: Duration = Duration::from_millis(2000); +const HOMESCREEN_IMAGE_WIDTH: i16 = WIDTH; +const HOMESCREEN_IMAGE_HEIGHT: i16 = HEIGHT; +const HOMESCREEN_TOIF_SIZE: i16 = 144; + +#[derive(Clone, Copy)] +pub struct HomescreenText<'a> { + pub text: TString<'a>, + pub style: TextStyle, + pub offset: Offset, + pub icon: Option, +} + +#[derive(Clone, Copy)] +pub struct HomescreenNotification { + pub text: TString<'static>, + pub icon: Icon, + pub color: Color, +} pub struct Homescreen { label: TString<'static>, @@ -113,19 +115,6 @@ impl Homescreen { } } - fn paint_loader(&mut self) { - TR::progress__locking_device.map_translated(|t| { - display::text_center( - TOP_CENTER + Offset::y(HOLD_Y), - t, - Font::NORMAL, - theme::FG, - theme::BG, - ) - }); - self.loader.paint() - } - fn render_loader<'s>(&'s self, target: &mut impl Renderer<'s>) { TR::progress__locking_device.map_translated(|t| { shape::Text::new(TOP_CENTER + Offset::y(HOLD_Y), t) @@ -209,56 +198,6 @@ impl Component for Homescreen { } } - fn paint(&mut self) { - self.pad.paint(); - if self.loader.is_animating() || self.loader.is_completely_grown(Instant::now()) { - self.paint_loader(); - } else { - let mut label_style = theme::TEXT_DEMIBOLD; - label_style.text_color = theme::FG; - - let text = HomescreenText { - text: self.label, - style: label_style, - offset: Offset::y(LABEL_Y), - icon: None, - }; - - let notification = self.get_notification(); - - match ImageInfo::parse(self.image) { - ImageInfo::Jpeg(_) => { - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let input = BufferInput(unsafe { self.image.data() }); - let mut pool = BufferJpegWork::get_cleared(); - let mut hs_img = HomescreenJpeg::new(input, pool.buffer.as_mut_slice()); - homescreen( - &mut hs_img, - &[text], - notification, - self.paint_notification_only, - ); - } - ImageInfo::Toif(_) => { - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let input = unwrap!(Toif::new(unsafe { self.image.data() })); - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut hs_img = - HomescreenToif::new(input.decompression_context(Some(&mut window))); - homescreen( - &mut hs_img, - &[text], - notification, - self.paint_notification_only, - ); - } - _ => {} - } - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); if self.loader.is_animating() || self.loader.is_completely_grown(Instant::now()) { @@ -379,72 +318,6 @@ impl Component for Lockscreen<'_> { None } - fn paint(&mut self) { - let (locked, tap) = if self.bootscreen { - ( - TR::lockscreen__title_not_connected, - TR::lockscreen__tap_to_connect, - ) - } else { - (TR::lockscreen__title_locked, TR::lockscreen__tap_to_unlock) - }; - - let mut label_style = theme::TEXT_DEMIBOLD; - label_style.text_color = theme::GREY_LIGHT; - - let mut texts: &[HomescreenText] = &[ - HomescreenText { - text: "".into(), - style: theme::TEXT_NORMAL, - offset: Offset::new(2, COINJOIN_Y), - icon: Some(theme::ICON_COINJOIN), - }, - HomescreenText { - text: locked.into(), - style: theme::TEXT_BOLD, - offset: Offset::y(LOCKED_Y), - icon: Some(theme::ICON_LOCK), - }, - HomescreenText { - text: tap.into(), - style: theme::TEXT_NORMAL, - offset: Offset::y(TAP_Y), - icon: None, - }, - HomescreenText { - text: self.label, - style: label_style, - offset: Offset::y(LABEL_Y), - icon: None, - }, - ]; - - if !self.coinjoin_authorized { - texts = &texts[1..]; - } - - match ImageInfo::parse(self.image) { - ImageInfo::Jpeg(_) => { - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let input = BufferInput(unsafe { self.image.data() }); - let mut pool = BufferJpegWork::get_cleared(); - let mut hs_img = HomescreenJpeg::new(input, pool.buffer.as_mut_slice()); - homescreen_blurred(&mut hs_img, texts); - } - ImageInfo::Toif(_) => { - // SAFETY: We expect no existing mutable reference. Resulting reference is - // discarded before returning to micropython. - let input = unwrap!(Toif::new(unsafe { self.image.data() })); - let mut window = [0; UZLIB_WINDOW_SIZE]; - let mut hs_img = - HomescreenToif::new(input.decompression_context(Some(&mut window))); - homescreen_blurred(&mut hs_img, texts); - } - _ => {} - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let center = constant::screen().center(); diff --git a/core/embed/rust/src/ui/model_tt/component/homescreen/render.rs b/core/embed/rust/src/ui/model_tt/component/homescreen/render.rs deleted file mode 100644 index b50b5f28b6..0000000000 --- a/core/embed/rust/src/ui/model_tt/component/homescreen/render.rs +++ /dev/null @@ -1,768 +0,0 @@ -use crate::{ - strutil::TString, - trezorhal::{ - buffers::{ - BufferBlurring, BufferBlurringTotals, BufferJpeg, BufferLine16bpp, BufferLine4bpp, - BufferText, - }, - display, - dma2d::{dma2d_setup_4bpp_over_16bpp, dma2d_start_blend, dma2d_wait_for_transfer}, - uzlib::UzlibContext, - }, - ui::{ - component::text::TextStyle, - constant::{screen, HEIGHT, WIDTH}, - display::{ - position_buffer, rect_fill_rounded_buffer, set_window, - tjpgd::{BufferInput, BufferOutput, JDEC}, - Color, Icon, - }, - geometry::{Offset, Point, Rect}, - model_tt::theme, - util::icon_text_center, - }, -}; - -#[derive(Clone, Copy)] -pub struct HomescreenText<'a> { - pub text: TString<'a>, - pub style: TextStyle, - pub offset: Offset, - pub icon: Option, -} - -#[derive(Clone, Copy)] -pub struct HomescreenNotification { - pub text: TString<'static>, - pub icon: Icon, - pub color: Color, -} - -#[derive(Clone, Copy)] -struct HomescreenTextInfo { - pub text_area: Rect, - pub text_width: i16, - pub text_color: Color, - pub icon_area: Option, -} - -pub const HOMESCREEN_IMAGE_WIDTH: i16 = WIDTH; -pub const HOMESCREEN_IMAGE_HEIGHT: i16 = HEIGHT; -pub const HOMESCREEN_TOIF_SIZE: i16 = 144; -pub const HOMESCREEN_TOIF_Y_OFFSET: i16 = 27; -pub const HOMESCREEN_TOIF_X_OFFSET: usize = - ((WIDTH as usize).saturating_sub(HOMESCREEN_TOIF_SIZE as usize)) / 2; - -const HOMESCREEN_MAX_ICON_SIZE: i16 = 20; -const NOTIFICATION_HEIGHT: i16 = 36; -const NOTIFICATION_BORDER: i16 = 6; -const TEXT_ICON_SPACE: i16 = 2; - -const HOMESCREEN_DIM_HEIGHT: i16 = 35; -const HOMESCREEN_DIM_START: i16 = HOMESCREEN_IMAGE_HEIGHT - 42; -const HOMESCREEN_DIM: f32 = 0.65; -const HOMESCREEN_DIM_BORDER: i16 = theme::BUTTON_SPACING; - -const LOCKSCREEN_DIM: f32 = 0.55; -const LOCKSCREEN_DIM_BG: f32 = 0.0; -const LOCKSCREEN_DIM_ALL: bool = true; - -const BLUR_SIZE: usize = 9; -const BLUR_DIV: u32 = - ((65536_f32 * (1_f32 - LOCKSCREEN_DIM_BG)) as u32) / ((BLUR_SIZE * BLUR_SIZE) as u32); -const DECOMP_LINES: usize = BLUR_SIZE + 1; -const BLUR_RADIUS: i16 = (BLUR_SIZE / 2) as i16; - -const COLORS: usize = 3; -const RED_IDX: usize = 0; -const GREEN_IDX: usize = 1; -const BLUE_IDX: usize = 2; - -pub trait HomescreenDecompressor { - fn get_height(&self) -> i16; - fn decompress(&mut self); - fn get_data(&mut self) -> &mut BufferJpeg; -} - -pub struct HomescreenJpeg<'i> { - pub output: BufferOutput, - pub input: BufferInput<'i>, - pub jdec: Option>, -} - -impl<'i> HomescreenJpeg<'i> { - pub fn new(mut input: BufferInput<'i>, pool: &'i mut [u8]) -> Self { - Self { - output: BufferOutput::new(WIDTH, 16), - jdec: JDEC::new(&mut input, pool).ok(), - input, - } - } -} - -impl<'i> HomescreenDecompressor for HomescreenJpeg<'i> { - fn get_height(&self) -> i16 { - if let Some(dec) = self.jdec.as_ref() { - return dec.mcu_height(); - } - 1 - } - - fn decompress(&mut self) { - self.jdec - .as_mut() - .map(|dec| dec.decomp(&mut self.input, &mut self.output)); - } - - fn get_data(&mut self) -> &mut BufferJpeg { - self.output.buffer() - } -} - -pub struct HomescreenToif<'i> { - pub output: BufferOutput, - pub decomp_context: UzlibContext<'i>, - line: i16, -} - -impl<'i> HomescreenToif<'i> { - pub fn new(context: UzlibContext<'i>) -> Self { - Self { - output: BufferOutput::new(WIDTH, 16), - decomp_context: context, - line: 0, - } - } -} - -impl<'i> HomescreenDecompressor for HomescreenToif<'i> { - fn get_height(&self) -> i16 { - 1 - } - - fn decompress(&mut self) { - // SAFETY: Aligning to u8 slice is safe, because the original slice is aligned - // to 16 bits, therefore there are also no residuals (prefix/suffix). - // The data in the slices are integers, so these are valid for both u16 - // and u8. - if self.line >= HOMESCREEN_TOIF_Y_OFFSET - && self.line < HOMESCREEN_TOIF_Y_OFFSET + HOMESCREEN_TOIF_SIZE - { - let (_, workbuf, _) = unsafe { self.output.buffer().buffer.align_to_mut::() }; - let result = self.decomp_context.uncompress( - &mut workbuf[2 * HOMESCREEN_TOIF_X_OFFSET - ..2 * HOMESCREEN_TOIF_X_OFFSET + 2 * HOMESCREEN_TOIF_SIZE as usize], - ); - - if result.is_err() { - self.output.buffer().buffer.fill(0); - } else { - for i in 0..HOMESCREEN_TOIF_SIZE as usize { - workbuf.swap( - 2 * HOMESCREEN_TOIF_X_OFFSET + 2 * i, - 2 * HOMESCREEN_TOIF_X_OFFSET + 2 * i + 1, - ); - } - } - } else { - self.output.buffer().buffer.fill(0); - } - self.line += 1; - } - - fn get_data(&mut self) -> &mut BufferJpeg { - self.output.buffer() - } -} - -fn homescreen_get_fg_text( - y_tmp: i16, - text_info: HomescreenTextInfo, - text_buffer: &BufferText, - fg_buffer: &mut BufferLine4bpp, -) -> bool { - if y_tmp >= text_info.text_area.y0 && y_tmp < text_info.text_area.y1 { - let y_pos = y_tmp - text_info.text_area.y0; - position_buffer( - &mut fg_buffer.buffer, - &text_buffer.buffer[(y_pos * WIDTH / 2) as usize..((y_pos + 1) * WIDTH / 2) as usize], - 4, - text_info.text_area.x0, - text_info.text_width, - ); - } - - y_tmp == (text_info.text_area.y1 - 1) -} - -fn homescreen_get_fg_icon( - y_tmp: i16, - text_info: HomescreenTextInfo, - icon_data: &[u8], - fg_buffer: &mut BufferLine4bpp, -) { - if let Some(icon_area) = text_info.icon_area { - let icon_size = icon_area.size(); - if y_tmp >= icon_area.y0 && y_tmp < icon_area.y1 { - let y_pos = y_tmp - icon_area.y0; - position_buffer( - &mut fg_buffer.buffer, - &icon_data - [(y_pos * icon_size.x / 2) as usize..((y_pos + 1) * icon_size.x / 2) as usize], - 4, - icon_area.x0, - icon_size.x, - ); - } - } -} - -fn homescreen_position_text( - text: &HomescreenText, - buffer: &mut BufferText, - icon_buffer: &mut [u8], -) -> HomescreenTextInfo { - let text_width = text - .text - .map(|t| display::text_width(t, text.style.text_font.into())); - let font_max_height = display::text_max_height(text.style.text_font.into()); - let font_baseline = display::text_baseline(text.style.text_font.into()); - let text_width_clamped = text_width.clamp(0, screen().width()); - - let icon_size = if let Some(icon) = text.icon { - let size = icon.toif.size(); - assert!(size.x <= HOMESCREEN_MAX_ICON_SIZE); - assert!(size.y <= HOMESCREEN_MAX_ICON_SIZE); - icon.toif.uncompress(icon_buffer); - size - } else { - Offset::zero() - }; - - let text_top = screen().y0 + text.offset.y - font_max_height + font_baseline; - let text_bottom = screen().y0 + text.offset.y + font_baseline; - - let total_width = text_width_clamped + icon_size.x + TEXT_ICON_SPACE; - let icon_left = screen().center().x + text.offset.x - total_width / 2; - let text_left = icon_left + icon_size.x + TEXT_ICON_SPACE; - let text_right = screen().center().x + text.offset.x + total_width / 2; - - let text_area = Rect::new( - Point::new(text_left, text_top), - Point::new(text_right, text_bottom), - ); - - let icon_area = if text.icon.is_some() { - Some(Rect::from_top_left_and_size( - Point::new(icon_left, text_bottom - icon_size.y - font_baseline), - icon_size, - )) - } else { - None - }; - - text.text - .map(|t| display::text_into_buffer(t, text.style.text_font.into(), buffer, 0)); - - HomescreenTextInfo { - text_area, - text_width, - text_color: text.style.text_color, - icon_area, - } -} - -#[inline(always)] -fn homescreen_dim_area(x: i16, y: i16) -> bool { - y >= HOMESCREEN_DIM_START - && (y > HOMESCREEN_DIM_START + 1 - && y < (HOMESCREEN_DIM_START + HOMESCREEN_DIM_HEIGHT - 1) - && x > HOMESCREEN_DIM_BORDER - && x < WIDTH - HOMESCREEN_DIM_BORDER) - || (y > HOMESCREEN_DIM_START - && y < (HOMESCREEN_DIM_START + HOMESCREEN_DIM_HEIGHT) - && x > HOMESCREEN_DIM_BORDER + 1 - && x < WIDTH - (HOMESCREEN_DIM_BORDER + 1)) - || ((HOMESCREEN_DIM_START..=(HOMESCREEN_DIM_START + HOMESCREEN_DIM_HEIGHT)).contains(&y) - && x > HOMESCREEN_DIM_BORDER + 2 - && x < WIDTH - (HOMESCREEN_DIM_BORDER + 2)) -} - -fn homescreen_line_blurred( - icon_data: &[u8], - text_buffer: &mut BufferText, - fg_buffer: &mut BufferLine4bpp, - img_buffer: &mut BufferLine16bpp, - text_info: HomescreenTextInfo, - blurring: &BlurringContext, - y: i16, -) -> bool { - fg_buffer.buffer.fill(0); - for x in 0..HOMESCREEN_IMAGE_WIDTH { - let c = if LOCKSCREEN_DIM_ALL { - let x = x as usize; - - let coef = (65536_f32 * LOCKSCREEN_DIM) as u32; - - let r = (blurring.totals.buffer[RED_IDX][x] as u32 * BLUR_DIV) >> 16; - let g = (blurring.totals.buffer[GREEN_IDX][x] as u32 * BLUR_DIV) >> 16; - let b = (blurring.totals.buffer[BLUE_IDX][x] as u32 * BLUR_DIV) >> 16; - - let r = (((coef * r) >> 8) & 0xF800) as u16; - let g = (((coef * g) >> 13) & 0x07E0) as u16; - let b = (((coef * b) >> 19) & 0x001F) as u16; - - r | g | b - } else { - let x = x as usize; - - let r = (((blurring.totals.buffer[RED_IDX][x] as u32 * BLUR_DIV) >> 8) & 0xF800) as u16; - let g = - (((blurring.totals.buffer[GREEN_IDX][x] as u32 * BLUR_DIV) >> 13) & 0x07E0) as u16; - let b = - (((blurring.totals.buffer[BLUE_IDX][x] as u32 * BLUR_DIV) >> 19) & 0x001F) as u16; - r | g | b - }; - - let j = (2 * x) as usize; - img_buffer.buffer[j + 1] = (c >> 8) as u8; - img_buffer.buffer[j] = (c & 0xFF) as u8; - } - - let done = homescreen_get_fg_text(y, text_info, text_buffer, fg_buffer); - homescreen_get_fg_icon(y, text_info, icon_data, fg_buffer); - - dma2d_wait_for_transfer(); - dma2d_setup_4bpp_over_16bpp(text_info.text_color.into()); - unsafe { - dma2d_start_blend(&fg_buffer.buffer, &img_buffer.buffer, WIDTH); - } - - done -} - -#[allow(clippy::too_many_arguments)] -fn homescreen_line( - icon_data: &[u8], - text_buffer: &mut BufferText, - text_info: HomescreenTextInfo, - data_buffer: &mut BufferJpeg, - fg_buffer: &mut BufferLine4bpp, - img_buffer: &mut BufferLine16bpp, - mcu_height: i16, - y: i16, -) -> bool { - let image_data = get_data(data_buffer, y, mcu_height); - fg_buffer.buffer.fill(0); - - for x in 0..HOMESCREEN_IMAGE_WIDTH { - let d = image_data[x as usize]; - - let c = if homescreen_dim_area(x, y) { - let coef = (65536_f32 * HOMESCREEN_DIM) as u32; - - let r = (d & 0xF800) >> 8; - let g = (d & 0x07E0) >> 3; - let b = (d & 0x001F) << 3; - - let r = (((coef * r as u32) >> 8) & 0xF800) as u16; - let g = (((coef * g as u32) >> 13) & 0x07E0) as u16; - let b = (((coef * b as u32) >> 19) & 0x001F) as u16; - r | g | b - } else { - d - }; - - let j = 2 * x as usize; - img_buffer.buffer[j + 1] = (c >> 8) as u8; - img_buffer.buffer[j] = (c & 0xFF) as u8; - } - - let done = homescreen_get_fg_text(y, text_info, text_buffer, fg_buffer); - homescreen_get_fg_icon(y, text_info, icon_data, fg_buffer); - - dma2d_wait_for_transfer(); - dma2d_setup_4bpp_over_16bpp(text_info.text_color.into()); - unsafe { - dma2d_start_blend(&fg_buffer.buffer, &img_buffer.buffer, WIDTH); - } - - done -} - -fn homescreen_next_text( - texts: &[HomescreenText], - text_buffer: &mut BufferText, - icon_data: &mut [u8], - text_info: HomescreenTextInfo, - text_idx: usize, -) -> (HomescreenTextInfo, usize) { - let mut next_text_idx = text_idx; - let mut next_text_info = text_info; - - if next_text_idx < texts.len() { - if let Some(txt) = texts.get(next_text_idx) { - text_buffer.buffer.fill(0); - next_text_info = homescreen_position_text(txt, text_buffer, icon_data); - next_text_idx += 1; - } - } - - (next_text_info, next_text_idx) -} - -#[inline(always)] -fn update_accs_add(data: &[u16], idx: usize, acc_r: &mut u16, acc_g: &mut u16, acc_b: &mut u16) { - let d = data[idx]; - let r = (d & 0xF800) >> 8; - let g = (d & 0x07E0) >> 3; - let b = (d & 0x001F) << 3; - *acc_r += r; - *acc_g += g; - *acc_b += b; -} - -#[inline(always)] -fn update_accs_sub(data: &[u16], idx: usize, acc_r: &mut u16, acc_g: &mut u16, acc_b: &mut u16) { - let d = data[idx]; - let r = (d & 0xF800) >> 8; - let g = (d & 0x07E0) >> 3; - let b = (d & 0x001F) << 3; - *acc_r -= r; - *acc_g -= g; - *acc_b -= b; -} - -struct BlurringContext { - mem: BufferBlurring, - pub totals: BufferBlurringTotals, - line_num: i16, - add_idx: usize, - rem_idx: usize, -} - -impl BlurringContext { - pub fn new() -> Self { - Self { - mem: BufferBlurring::get_cleared(), - totals: BufferBlurringTotals::get_cleared(), - line_num: 0, - add_idx: 0, - rem_idx: 0, - } - } - - fn clear(&mut self) { - let lines = &mut self.mem.buffer[0..DECOMP_LINES]; - for (i, total) in self.totals.buffer.iter_mut().enumerate() { - for line in lines.iter_mut() { - line[i].fill(0); - } - total.fill(0); - } - } - - // computes color averages for one line of image data - fn compute_line_avgs(&mut self, buffer: &mut BufferJpeg, mcu_height: i16) { - let lines = &mut self.mem.buffer[0..DECOMP_LINES]; - let mut acc_r = 0; - let mut acc_g = 0; - let mut acc_b = 0; - let data = get_data(buffer, self.line_num, mcu_height); - - for i in -BLUR_RADIUS..=BLUR_RADIUS { - let ic = i.clamp(0, HOMESCREEN_IMAGE_WIDTH - 1) as usize; - update_accs_add(data, ic, &mut acc_r, &mut acc_g, &mut acc_b); - } - - for i in 0..HOMESCREEN_IMAGE_WIDTH { - lines[self.add_idx][RED_IDX][i as usize] = acc_r; - lines[self.add_idx][GREEN_IDX][i as usize] = acc_g; - lines[self.add_idx][BLUE_IDX][i as usize] = acc_b; - - // clamping handles left and right edges - let ic = (i - BLUR_RADIUS).clamp(0, HOMESCREEN_IMAGE_WIDTH - 1) as usize; - let ic2 = - (i + BLUR_SIZE as i16 - BLUR_RADIUS).clamp(0, HOMESCREEN_IMAGE_WIDTH - 1) as usize; - update_accs_add(data, ic2, &mut acc_r, &mut acc_g, &mut acc_b); - update_accs_sub(data, ic, &mut acc_r, &mut acc_g, &mut acc_b); - } - self.line_num += 1; - } - - // adds one line of averages to sliding total averages - fn vertical_avg_add(&mut self) { - let lines = &mut self.mem.buffer[0..DECOMP_LINES]; - for i in 0..HOMESCREEN_IMAGE_WIDTH as usize { - self.totals.buffer[RED_IDX][i] += lines[self.add_idx][RED_IDX][i]; - self.totals.buffer[GREEN_IDX][i] += lines[self.add_idx][GREEN_IDX][i]; - self.totals.buffer[BLUE_IDX][i] += lines[self.add_idx][BLUE_IDX][i]; - } - } - - // adds one line and removes one line of averages to/from sliding total averages - fn vertical_avg(&mut self) { - let lines = &mut self.mem.buffer[0..DECOMP_LINES]; - for i in 0..HOMESCREEN_IMAGE_WIDTH as usize { - self.totals.buffer[RED_IDX][i] += lines[self.add_idx][RED_IDX][i]; - self.totals.buffer[GREEN_IDX][i] += lines[self.add_idx][GREEN_IDX][i]; - self.totals.buffer[BLUE_IDX][i] += lines[self.add_idx][BLUE_IDX][i]; - self.totals.buffer[RED_IDX][i] -= lines[self.rem_idx][RED_IDX][i]; - self.totals.buffer[GREEN_IDX][i] -= lines[self.rem_idx][GREEN_IDX][i]; - self.totals.buffer[BLUE_IDX][i] -= lines[self.rem_idx][BLUE_IDX][i]; - } - } - - fn inc_add(&mut self) { - self.add_idx += 1; - if self.add_idx >= DECOMP_LINES { - self.add_idx = 0; - } - } - - fn inc_rem(&mut self) { - self.rem_idx += 1; - if self.rem_idx >= DECOMP_LINES { - self.rem_idx = 0; - } - } - - fn get_line_num(&self) -> i16 { - self.line_num - } -} - -#[inline(always)] -fn get_data(buffer: &mut BufferJpeg, line_num: i16, mcu_height: i16) -> &mut [u16] { - let data_start = ((line_num % mcu_height) * WIDTH) as usize; - let data_end = (((line_num % mcu_height) + 1) * WIDTH) as usize; - &mut buffer.buffer[data_start..data_end] -} - -pub fn homescreen_blurred(data: &mut dyn HomescreenDecompressor, texts: &[HomescreenText]) { - let mut icon_data = [0_u8; (HOMESCREEN_MAX_ICON_SIZE * HOMESCREEN_MAX_ICON_SIZE / 2) as usize]; - - let mut text_buffer = BufferText::get_cleared(); - let mut fg_buffer_0 = BufferLine4bpp::get_cleared(); - let mut img_buffer_0 = BufferLine16bpp::get_cleared(); - let mut fg_buffer_1 = BufferLine4bpp::get_cleared(); - let mut img_buffer_1 = BufferLine16bpp::get_cleared(); - - let mut next_text_idx = 1; - let mut text_info = - homescreen_position_text(unwrap!(texts.first()), &mut text_buffer, &mut icon_data); - - let mcu_height = data.get_height(); - data.decompress(); - - set_window(screen()); - - let mut blurring = BlurringContext::new(); - - // handling top edge case: preload the edge value N+1 times - blurring.compute_line_avgs(data.get_data(), mcu_height); - - for _ in 0..=BLUR_RADIUS { - blurring.vertical_avg_add(); - } - blurring.inc_add(); - - // load enough values to be able to compute first line averages - for _ in 0..BLUR_RADIUS { - blurring.compute_line_avgs(data.get_data(), mcu_height); - blurring.vertical_avg_add(); - blurring.inc_add(); - - if (blurring.get_line_num() % mcu_height) == 0 { - data.decompress(); - } - } - - for y in 0..HEIGHT { - // several lines have been already decompressed before this loop, adjust for - // that - if y < HOMESCREEN_IMAGE_HEIGHT - (BLUR_RADIUS + 1) { - blurring.compute_line_avgs(data.get_data(), mcu_height); - } - - let done = if y % 2 == 0 { - homescreen_line_blurred( - &icon_data, - &mut text_buffer, - &mut fg_buffer_0, - &mut img_buffer_0, - text_info, - &blurring, - y, - ) - } else { - homescreen_line_blurred( - &icon_data, - &mut text_buffer, - &mut fg_buffer_1, - &mut img_buffer_1, - text_info, - &blurring, - y, - ) - }; - - if done { - (text_info, next_text_idx) = homescreen_next_text( - texts, - &mut text_buffer, - &mut icon_data, - text_info, - next_text_idx, - ); - } - - blurring.vertical_avg(); - - // handling bottom edge case: stop incrementing counter, adding the edge value - // for the rest of image - // the extra -1 is to indicate that this was the last decompressed line, - // in the next pass the docompression and compute_line_avgs won't happen - if y < HOMESCREEN_IMAGE_HEIGHT - (BLUR_RADIUS + 1) - 1 { - blurring.inc_add(); - } - - if y == HOMESCREEN_IMAGE_HEIGHT { - // reached end of image, clear avgs (display black) - blurring.clear(); - } - - // only start incrementing remove index when enough lines have been loaded - if y >= (BLUR_RADIUS) { - blurring.inc_rem(); - } - - if (blurring.get_line_num() % mcu_height) == 0 && (blurring.get_line_num() < HEIGHT) { - data.decompress(); - } - } - dma2d_wait_for_transfer(); -} - -pub fn homescreen( - data: &mut dyn HomescreenDecompressor, - texts: &[HomescreenText], - notification: Option, - notification_only: bool, -) { - let mut icon_data = [0_u8; (HOMESCREEN_MAX_ICON_SIZE * HOMESCREEN_MAX_ICON_SIZE / 2) as usize]; - - let mut text_buffer = BufferText::get_cleared(); - let mut fg_buffer_0 = BufferLine4bpp::get_cleared(); - let mut img_buffer_0 = BufferLine16bpp::get_cleared(); - let mut fg_buffer_1 = BufferLine4bpp::get_cleared(); - let mut img_buffer_1 = BufferLine16bpp::get_cleared(); - - let mut next_text_idx = 0; - let mut text_info = if let Some(notification) = notification { - rect_fill_rounded_buffer( - Rect::from_top_left_and_size( - Point::new(NOTIFICATION_BORDER, 0), - Offset::new(WIDTH - NOTIFICATION_BORDER * 2, NOTIFICATION_HEIGHT), - ), - 2, - &mut text_buffer, - ); - let area = Rect::new( - Point::new(0, NOTIFICATION_BORDER), - Point::new(WIDTH, NOTIFICATION_HEIGHT + NOTIFICATION_BORDER), - ); - HomescreenTextInfo { - text_area: area, - text_width: WIDTH, - text_color: notification.color, - icon_area: None, - } - } else { - next_text_idx += 1; - homescreen_position_text(unwrap!(texts.first()), &mut text_buffer, &mut icon_data) - }; - - set_window(screen()); - - let mcu_height = data.get_height(); - - for y in 0..HEIGHT { - if (y % mcu_height) == 0 { - data.decompress(); - } - - let done = if y % 2 == 0 { - homescreen_line( - &icon_data, - &mut text_buffer, - text_info, - data.get_data(), - &mut fg_buffer_0, - &mut img_buffer_0, - mcu_height, - y, - ) - } else { - homescreen_line( - &icon_data, - &mut text_buffer, - text_info, - data.get_data(), - &mut fg_buffer_1, - &mut img_buffer_1, - mcu_height, - y, - ) - }; - - if done { - if notification.is_some() && next_text_idx == 0 { - //finished notification area, let interrupt and draw the text - let notification = unwrap!(notification); - - let style = TextStyle { - background_color: notification.color, - ..theme::TEXT_BOLD - }; - - dma2d_wait_for_transfer(); - - drop(fg_buffer_0); - drop(fg_buffer_1); - - icon_text_center( - text_info.text_area.center(), - notification.icon, - 8, - notification.text, - style, - Offset::new(1, -2), - ); - - fg_buffer_0 = BufferLine4bpp::get_cleared(); - fg_buffer_1 = BufferLine4bpp::get_cleared(); - - set_window( - screen() - .split_top(NOTIFICATION_HEIGHT + NOTIFICATION_BORDER) - .1, - ); - } - - if notification_only && next_text_idx == 0 { - dma2d_wait_for_transfer(); - return; - } - - (text_info, next_text_idx) = homescreen_next_text( - texts, - &mut text_buffer, - &mut icon_data, - text_info, - next_text_idx, - ); - } - } - dma2d_wait_for_transfer(); -} diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/bip39.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/bip39.rs index 906406303c..651d5bf7e2 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/bip39.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/bip39.rs @@ -2,12 +2,11 @@ use crate::{ trezorhal::bip39, ui::{ component::{text::common::TextBox, Component, Event, EventCtx}, - display, geometry::{Alignment2D, Offset, Rect}, model_tt::{ component::{ keyboard::{ - common::{paint_pending_marker, render_pending_marker, MultiTapKeyboard}, + common::{render_pending_marker, MultiTapKeyboard}, mnemonic::{MnemonicInput, MnemonicInputMsg, MNEMONIC_KEY_COUNT}, }, Button, ButtonContent, ButtonMsg, @@ -102,59 +101,6 @@ impl Component for Bip39Input { } } - fn paint(&mut self) { - let area = self.button.area(); - let style = self.button.style(); - - // First, paint the button background. - self.button.paint_background(style); - - // Paint the entered content (the prefix of the suggested word). - let text = self.textbox.content(); - let width = style.font.text_width(text); - // Content starts in the left-center point, offset by 16px to the right and 8px - // to the bottom. - let text_baseline = area.top_left().center(area.bottom_left()) + Offset::new(16, 8); - display::text_left( - text_baseline, - text, - style.font, - style.text_color, - style.button_color, - ); - - // Paint the rest of the suggested dictionary word. - if let Some(word) = self.suggested_word.and_then(|w| w.get(text.len()..)) { - let word_baseline = text_baseline + Offset::new(width, 0); - let style = self.button_suggestion.style(); - display::text_left( - word_baseline, - word, - style.font, - style.text_color, - style.button_color, - ); - } - - // Paint the pending marker. - if self.multi_tap.pending_key().is_some() { - paint_pending_marker(text_baseline, text, style.font, style.text_color); - } - - // Paint the icon. - if let ButtonContent::Icon(icon) = self.button.content() { - // Icon is painted in the right-center point, of expected size 16x16 pixels, and - // 16px from the right edge. - let icon_center = area.top_right().center(area.bottom_right()) - Offset::new(16 + 8, 0); - icon.draw( - icon_center, - Alignment2D::CENTER, - style.text_color, - style.button_color, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let area = self.button.area(); let style = self.button.style(); diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/common.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/common.rs index fe2d558589..e59cfb74d1 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/common.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/common.rs @@ -2,7 +2,7 @@ use crate::{ time::Duration, ui::{ component::{text::common::TextEdit, Event, EventCtx, Timer}, - display::{self, Color, Font}, + display::{Color, Font}, geometry::{Offset, Point, Rect}, shape, shape::Renderer, @@ -117,21 +117,6 @@ impl MultiTapKeyboard { } } -/// Create a visible "underscoring" of the last letter of a text. -pub fn paint_pending_marker(text_baseline: Point, text: &str, font: Font, color: Color) { - // Measure the width of the last character of input. - if let Some(last) = text.chars().last() { - let width = font.text_width(text); - let last_width = font.char_width(last); - // Draw the marker 2px under the start of the baseline of the last character. - let marker_origin = text_baseline + Offset::new(width - last_width, 2); - // Draw the marker 1px longer than the last character, and 3px thick. - let marker_rect = - Rect::from_top_left_and_size(marker_origin, Offset::new(last_width + 1, 3)); - display::rect_fill(marker_rect, color); - } -} - /// Create a visible "underscoring" of the last letter of a text. pub fn render_pending_marker<'s>( target: &mut impl Renderer<'s>, diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs index 94bbe5d7d1..9651bc95b5 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs @@ -1,7 +1,7 @@ use crate::{ strutil::TString, ui::{ - component::{maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe}, + component::{Child, Component, Event, EventCtx, Label, Maybe}, geometry::{Alignment2D, Grid, Offset, Rect}, model_tt::{ component::{Button, ButtonMsg, Swipe, SwipeDirection}, @@ -186,13 +186,6 @@ where None } - fn paint(&mut self) { - paint_overlapping(&mut [&mut self.prompt, &mut self.input, &mut self.back]); - for btn in &mut self.keys { - btn.paint(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { if self.input.inner().inner().is_empty() { self.prompt.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs index d1795c0b3c..e66d01871d 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs @@ -8,7 +8,7 @@ use crate::{ geometry::{Grid, Offset, Rect}, model_tt::component::{ button::{Button, ButtonContent, ButtonMsg}, - keyboard::common::{paint_pending_marker, render_pending_marker, MultiTapKeyboard}, + keyboard::common::{render_pending_marker, MultiTapKeyboard}, swipe::{Swipe, SwipeDirection}, theme, ScrollBar, }, @@ -294,20 +294,6 @@ impl Component for PassphraseKeyboard { None } - fn paint(&mut self) { - self.input.paint(); - self.scrollbar.paint(); - self.confirm.paint(); - self.back.paint(); - for btn in &mut self.keys { - btn.paint(); - } - if self.fade.take() { - // Note that this is blocking and takes some time. - display::fade_backlight(theme::backlight::get_backlight_normal()); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.input.render(target); self.scrollbar.render(target); @@ -351,46 +337,6 @@ impl Component for Input { None } - fn paint(&mut self) { - let style = theme::label_keyboard(); - - let text_baseline = self.area.top_left() + Offset::y(style.text_font.text_height()) - - Offset::y(style.text_font.text_baseline()); - - let text = self.textbox.content(); - - // Preparing the new text to be displayed. - // Possible optimization is to redraw the background only when pending character - // is replaced, or only draw rectangle over the pending character and - // marker. - display::rect_fill(self.area, theme::BG); - - // Find out how much text can fit into the textbox. - // Accounting for the pending marker, which draws itself one pixel longer than - // the last character - let available_area_width = self.area.width() - 1; - let text_to_display = - long_line_content_with_ellipsis(text, "...", style.text_font, available_area_width); - - display::text_left( - text_baseline, - &text_to_display, - style.text_font, - style.text_color, - style.background_color, - ); - - // Paint the pending marker. - if self.multi_tap.pending_key().is_some() { - paint_pending_marker( - text_baseline, - &text_to_display, - style.text_font, - style.text_color, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let style = theme::label_keyboard(); diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs index 3cd478ee25..6f4523b6ef 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs @@ -9,7 +9,7 @@ use crate::{ base::ComponentExt, text::TextStyle, Child, Component, Event, EventCtx, Label, Maybe, Never, Pad, Timer, }, - display::{self, Font}, + display::Font, event::TouchEvent, geometry::{Alignment, Alignment2D, Grid, Insets, Offset, Rect}, model_tt::component::{ @@ -248,26 +248,6 @@ impl Component for PinKeyboard<'_> { None } - fn paint(&mut self) { - self.erase_btn.paint(); - self.textbox_pad.paint(); - if self.textbox.inner().is_empty() { - if let Some(ref mut w) = self.major_warning { - w.paint(); - } else { - self.major_prompt.paint(); - } - self.minor_prompt.paint(); - self.cancel_btn.paint(); - } else { - self.textbox.paint(); - } - self.confirm_btn.paint(); - for btn in &mut self.digit_btns { - btn.paint(); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.erase_btn.render(target); self.textbox_pad.render(target); @@ -352,31 +332,6 @@ impl PinDots { &self.digits } - fn paint_digits(&self, area: Rect) { - let center = area.center() + Offset::y(Font::MONO.text_height() / 2); - let right = center + Offset::x(Font::MONO.text_width("0") * (MAX_VISIBLE_DOTS as i16) / 2); - let digits = self.digits.len(); - - if digits <= MAX_VISIBLE_DOTS { - display::text_center( - center, - &self.digits, - Font::MONO, - self.style.text_color, - self.style.background_color, - ); - } else { - let offset: usize = digits.saturating_sub(MAX_VISIBLE_DIGITS); - display::text_right( - right, - &self.digits[offset..], - Font::MONO, - self.style.text_color, - self.style.background_color, - ); - } - } - fn render_digits<'s>(&self, area: Rect, target: &mut impl Renderer<'s>) { let center = area.center() + Offset::y(Font::MONO.text_height() / 2); let right = center + Offset::x(Font::MONO.text_width("0") * (MAX_VISIBLE_DOTS as i16) / 2); @@ -398,50 +353,6 @@ impl PinDots { } } - fn paint_dots(&self, area: Rect) { - let mut cursor = self.size().snap(area.center(), Alignment2D::CENTER); - - let digits = self.digits.len(); - let dots_visible = digits.min(MAX_VISIBLE_DOTS); - let step = Self::DOT + Self::PADDING; - - // Jiggle when overflowed. - if digits > dots_visible && digits % 2 == 0 { - cursor.x += Self::TWITCH - } - - // Small leftmost dot. - if digits > dots_visible + 1 { - theme::DOT_SMALL.draw( - cursor - Offset::x(2 * step), - Alignment2D::TOP_LEFT, - self.style.text_color, - self.style.background_color, - ); - } - - // Greyed out dot. - if digits > dots_visible { - theme::DOT_ACTIVE.draw( - cursor - Offset::x(step), - Alignment2D::TOP_LEFT, - theme::GREY_LIGHT, - self.style.background_color, - ); - } - - // Draw a dot for each PIN digit. - for _ in 0..dots_visible { - theme::DOT_ACTIVE.draw( - cursor, - Alignment2D::TOP_LEFT, - self.style.text_color, - self.style.background_color, - ); - cursor.x += step; - } - } - fn render_dots<'s>(&self, area: Rect, target: &mut impl Renderer<'s>) { let mut cursor = self.size().snap(area.center(), Alignment2D::CENTER); @@ -511,16 +422,6 @@ impl Component for PinDots { } } - fn paint(&mut self) { - let dot_area = self.area.inset(HEADER_PADDING); - self.pad.paint(); - if self.display_digits { - self.paint_digits(dot_area) - } else { - self.paint_dots(dot_area) - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let dot_area = self.area.inset(HEADER_PADDING); self.pad.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs index 54d57b7b91..7c9517aa6b 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs @@ -8,12 +8,11 @@ use crate::{ text::common::{TextBox, TextEdit}, Component, Event, EventCtx, }, - display, geometry::{Alignment2D, Offset, Rect}, model_tt::{ component::{ keyboard::{ - common::{paint_pending_marker, render_pending_marker, MultiTapKeyboard}, + common::{render_pending_marker, MultiTapKeyboard}, mnemonic::{MnemonicInput, MnemonicInputMsg, MNEMONIC_KEY_COUNT}, }, Button, ButtonContent, ButtonMsg, @@ -121,70 +120,6 @@ impl Component for Slip39Input { None } - fn paint(&mut self) { - let area = self.button.area(); - let style = self.button.style(); - - // First, paint the button background. - self.button.paint_background(style); - - // Content starts in the left-center point, offset by 16px to the right and 8px - // to the bottom. - let text_baseline = area.top_left().center(area.bottom_left()) + Offset::new(16, 8); - - // To simplify things, we always copy the printed string here, even if it - // wouldn't be strictly necessary. - let mut text = ShortString::new(); - - if let Some(word) = self.final_word { - // We're done with input, paint the full word. - text.push_str(word) - .assert_if_debugging_ui("Text buffer is too small"); - } else { - // Paint an asterisk for each letter of input. - for ch in iter::repeat('*').take(self.textbox.content().len()) { - text.push(ch) - .assert_if_debugging_ui("Text buffer is too small"); - } - // If we're in the pending state, paint the pending character at the end. - if let (Some(key), Some(press)) = - (self.multi_tap.pending_key(), self.multi_tap.pending_press()) - { - assert!(!Self::keys()[key].is_empty()); - // Now we can be sure that the looped iterator will return a value. - let ch = unwrap!(Self::keys()[key].chars().cycle().nth(press)); - text.pop(); - text.push(ch) - .assert_if_debugging_ui("Text buffer is too small"); - } - } - display::text_left( - text_baseline, - text.as_str(), - style.font, - style.text_color, - style.button_color, - ); - - // Paint the pending marker. - if self.multi_tap.pending_key().is_some() && self.final_word.is_none() { - paint_pending_marker(text_baseline, text.as_str(), style.font, style.text_color); - } - - // Paint the icon. - if let ButtonContent::Icon(icon) = self.button.content() { - // Icon is painted in the right-center point, of expected size 16x16 pixels, and - // 16px from the right edge. - let icon_center = area.top_right().center(area.bottom_right()) - Offset::new(16 + 8, 0); - icon.draw( - icon_center, - Alignment2D::CENTER, - style.text_color, - style.button_color, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let area = self.button.area(); let style = self.button.style(); diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs index ac785b7f3f..8ca34fc6c5 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs @@ -55,10 +55,6 @@ impl Component for SelectWordCount { self.keypad.event(ctx, event) } - fn paint(&mut self) { - self.keypad.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.keypad.render(target) } @@ -110,12 +106,6 @@ impl Component for ValueKeypad { None } - fn paint(&mut self) { - for btn in self.buttons.iter_mut() { - btn.0.paint() - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { for btn in self.buttons.iter() { btn.0.render(target) diff --git a/core/embed/rust/src/ui/model_tt/component/loader.rs b/core/embed/rust/src/ui/model_tt/component/loader.rs index 2e8962f562..33868948f3 100644 --- a/core/embed/rust/src/ui/model_tt/component/loader.rs +++ b/core/embed/rust/src/ui/model_tt/component/loader.rs @@ -199,32 +199,6 @@ impl Component for Loader { None } - fn paint(&mut self) { - // TODO: Consider passing the current instant along with the event -- that way, - // we could synchronize painting across the component tree. Also could be useful - // in automated tests. - // In practice, taking the current instant here is more precise in case some - // other component in the tree takes a long time to draw. - let now = Instant::now(); - - if let Some(progress) = self.progress(now) { - let style = if progress < display::LOADER_MAX { - self.styles.normal - } else { - self.styles.active - }; - - self.pad.paint(); - display::loader( - progress, - self.offset_y, - style.loader_color, - style.background_color, - style.icon, - ); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // TODO: Consider passing the current instant along with the event -- that way, // we could synchronize painting across the component tree. Also could be useful diff --git a/core/embed/rust/src/ui/model_tt/component/number_input.rs b/core/embed/rust/src/ui/model_tt/component/number_input.rs index 0d342a639e..278ac178cd 100644 --- a/core/embed/rust/src/ui/model_tt/component/number_input.rs +++ b/core/embed/rust/src/ui/model_tt/component/number_input.rs @@ -9,7 +9,7 @@ use crate::{ text::paragraphs::{Paragraph, Paragraphs}, Child, Component, Event, EventCtx, Pad, }, - display::{self, Font}, + display::Font, geometry::{Alignment, Grid, Insets, Offset, Rect}, shape::{self, Renderer}, }, @@ -114,14 +114,6 @@ where None } - fn paint(&mut self) { - self.input.paint(); - self.paragraphs_pad.paint(); - self.paragraphs.paint(); - self.info_button.paint(); - self.confirm_button.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.input.render(target); self.paragraphs_pad.render(target); @@ -210,24 +202,6 @@ impl Component for NumberInput { None } - fn paint(&mut self) { - let mut buf = [0u8; 10]; - if let Some(text) = strutil::format_i64(self.value as i64, &mut buf) { - let digit_font = Font::DEMIBOLD; - let y_offset = digit_font.text_height() / 2 + Button::BASELINE_OFFSET; - display::rect_fill(self.area, theme::BG); - display::text_center( - self.area.center() + Offset::y(y_offset), - text, - digit_font, - theme::FG, - theme::BG, - ); - } - self.dec.paint(); - self.inc.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let mut buf = [0u8; 10]; diff --git a/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs b/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs index a4028dd993..e652f8ec83 100644 --- a/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs +++ b/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs @@ -1,7 +1,6 @@ use crate::ui::{ component::{base::ComponentExt, Child, Component, Event, EventCtx}, constant::screen, - display, event::TouchEvent, geometry::{Grid, Insets, Point, Rect}, shape::{self, Renderer}, @@ -72,12 +71,6 @@ impl Component for NumberInputSliderDialog { None } - fn paint(&mut self) { - self.input.paint(); - self.cancel_button.paint(); - self.confirm_button.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.input.render(target); self.cancel_button.render(target); @@ -152,13 +145,6 @@ impl Component for NumberInputSlider { None } - fn paint(&mut self) { - let val_pct = (100 * (self.value - self.min)) / (self.max - self.min); - let fill_to = (val_pct as i16 * self.area.width()) / 100; - - display::bar_with_text_and_fill(self.area, None, theme::FG, theme::BG, 0, fill_to as _); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let val_pct = (100 * (self.value - self.min)) / (self.max - self.min); diff --git a/core/embed/rust/src/ui/model_tt/component/page.rs b/core/embed/rust/src/ui/model_tt/component/page.rs index e00b12f649..2fe87c56e6 100644 --- a/core/embed/rust/src/ui/model_tt/component/page.rs +++ b/core/embed/rust/src/ui/model_tt/component/page.rs @@ -404,33 +404,6 @@ where button_result } - fn paint(&mut self) { - self.pad.paint(); - match &self.loader { - Some(l) if l.is_animating() => self.loader.paint(), - _ => { - self.content.paint(); - if self.scrollbar.has_pages() { - self.scrollbar.paint(); - } - } - } - if self.button_cancel.is_some() && self.is_cancel_visible() { - self.button_cancel.paint(); - } else { - self.button_prev.paint(); - } - if self.scrollbar.has_next_page() { - self.button_next.paint(); - } else { - self.button_confirm.paint(); - } - if let Some(val) = self.fade.take() { - // Note that this is blocking and takes some time. - display::fade_backlight(val); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); match &self.loader { diff --git a/core/embed/rust/src/ui/model_tt/component/progress.rs b/core/embed/rust/src/ui/model_tt/component/progress.rs index 699e00c427..5995f33f2d 100644 --- a/core/embed/rust/src/ui/model_tt/component/progress.rs +++ b/core/embed/rust/src/ui/model_tt/component/progress.rs @@ -13,7 +13,7 @@ use crate::{ text::paragraphs::{Paragraph, Paragraphs}, Child, Component, Event, EventCtx, Label, Never, Pad, }, - display::{self, Font, LOADER_MAX}, + display::{Font, LOADER_MAX}, geometry::{Insets, Offset, Rect}, model_tt::constant, shape::Renderer, @@ -95,23 +95,6 @@ impl Component for Progress { None } - fn paint(&mut self) { - self.title.paint(); - if self.indeterminate { - display::loader_indeterminate( - self.value, - self.loader_y_offset, - theme::FG, - theme::BG, - None, - ); - } else { - display::loader(self.value, self.loader_y_offset, theme::FG, theme::BG, None); - } - self.description_pad.paint(); - self.description.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.title.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/result.rs b/core/embed/rust/src/ui/model_tt/component/result.rs index e14d82c31e..50509ffb22 100644 --- a/core/embed/rust/src/ui/model_tt/component/result.rs +++ b/core/embed/rust/src/ui/model_tt/component/result.rs @@ -3,7 +3,7 @@ use crate::{ ui::{ component::{text::TextStyle, Child, Component, Event, EventCtx, Label, Never, Pad}, constant::screen, - display::{self, Color, Font, Icon}, + display::{Color, Font, Icon}, geometry::{Alignment2D, Insets, Offset, Point, Rect}, model_tt::theme::FG, shape, @@ -86,18 +86,6 @@ impl Component for ResultFooter<'_> { None } - fn paint(&mut self) { - // divider line - let bar = Rect::from_center_and_size( - Point::new(self.area.center().x, self.area.y0), - Offset::new(self.area.width(), 1), - ); - display::rect_fill(bar, self.style.divider_color); - - // footer text - self.text.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { // divider line let bar = Rect::from_center_and_size( @@ -169,20 +157,6 @@ impl<'a> Component for ResultScreen<'a> { None } - fn paint(&mut self) { - self.bg.paint(); - self.footer_pad.paint(); - - self.icon.draw( - Point::new(screen().center().x, ICON_CENTER_Y), - Alignment2D::CENTER, - self.style.fg_color, - self.style.bg_color, - ); - self.message.paint(); - self.footer.paint(); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.bg.render(target); self.footer_pad.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/scroll.rs b/core/embed/rust/src/ui/model_tt/component/scroll.rs index 3c611fdc9a..04d0e6b9ba 100644 --- a/core/embed/rust/src/ui/model_tt/component/scroll.rs +++ b/core/embed/rust/src/ui/model_tt/component/scroll.rs @@ -84,46 +84,6 @@ impl Component for ScrollBar { None } - fn paint(&mut self) { - fn dotsize(distance: usize, nhidden: usize) -> Icon { - match (nhidden.saturating_sub(distance)).min(2 - distance) { - 0 => theme::DOT_INACTIVE, - 1 => theme::DOT_INACTIVE_HALF, - _ => theme::DOT_INACTIVE_QUARTER, - } - } - - // Number of visible dots. - let num_shown = self.page_count.min(Self::MAX_DOTS); - // Page indices corresponding to the first (and last) dot. - let first_shown = self - .active_page - .saturating_sub(Self::MAX_DOTS / 2) - .min(self.page_count.saturating_sub(Self::MAX_DOTS)); - let last_shown = first_shown + num_shown - 1; - - let mut cursor = self.area.center() - - Offset::on_axis( - self.layout.axis, - Self::DOT_INTERVAL * (num_shown.saturating_sub(1) as i16) / 2, - ); - for i in first_shown..(last_shown + 1) { - let icon = if i == self.active_page { - theme::DOT_ACTIVE - } else if i <= first_shown + 1 { - let before_first_shown = first_shown; - dotsize(i - first_shown, before_first_shown) - } else if i >= last_shown - 1 { - let after_last_shown = self.page_count - 1 - last_shown; - dotsize(last_shown - i, after_last_shown) - } else { - theme::DOT_INACTIVE - }; - icon.draw(cursor, Alignment2D::CENTER, theme::FG, theme::BG); - cursor = cursor + Offset::on_axis(self.layout.axis, Self::DOT_INTERVAL); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { fn dotsize(distance: usize, nhidden: usize) -> Icon { match (nhidden.saturating_sub(distance)).min(2 - distance) { diff --git a/core/embed/rust/src/ui/model_tt/component/set_brightness.rs b/core/embed/rust/src/ui/model_tt/component/set_brightness.rs index 0de97478f1..a19ccc49f9 100644 --- a/core/embed/rust/src/ui/model_tt/component/set_brightness.rs +++ b/core/embed/rust/src/ui/model_tt/component/set_brightness.rs @@ -51,10 +51,6 @@ impl Component for SetBrightnessDialog { } } - fn paint(&mut self) { - self.0.paint() - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.0.render(target); } diff --git a/core/embed/rust/src/ui/model_tt/component/simple_page.rs b/core/embed/rust/src/ui/model_tt/component/simple_page.rs index 4941fef3fa..606f813045 100644 --- a/core/embed/rust/src/ui/model_tt/component/simple_page.rs +++ b/core/embed/rust/src/ui/model_tt/component/simple_page.rs @@ -155,18 +155,6 @@ where self.content.event(ctx, event).map(PageMsg::Content) } - fn paint(&mut self) { - self.pad.paint(); - self.content.paint(); - if self.scrollbar.has_pages() { - self.scrollbar.paint(); - } - if let Some(val) = self.fade.take() { - // Note that this is blocking and takes some time. - display::fade_backlight(val); - } - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { self.pad.render(target); self.content.render(target); diff --git a/core/embed/rust/src/ui/model_tt/component/swipe.rs b/core/embed/rust/src/ui/model_tt/component/swipe.rs index 5902c903ec..ce8476fcc2 100644 --- a/core/embed/rust/src/ui/model_tt/component/swipe.rs +++ b/core/embed/rust/src/ui/model_tt/component/swipe.rs @@ -158,7 +158,5 @@ impl Component for Swipe { None } - fn paint(&mut self) {} - fn render<'s>(&'s self, _target: &mut impl Renderer<'s>) {} } diff --git a/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs b/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs index 2a359ede10..6fef82e1ec 100644 --- a/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs +++ b/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs @@ -6,10 +6,7 @@ use crate::ui::{ shape::Renderer, }; #[cfg(feature = "bootloader")] -use crate::ui::{ - display::{toif::Toif, Icon}, - model_tt::theme::bootloader::DEVICE_NAME, -}; +use crate::ui::{display::toif::Toif, model_tt::theme::bootloader::DEVICE_NAME}; const TEXT_BOTTOM_MARGIN: i16 = 24; // matching the homescreen label margin const ICON_TOP_MARGIN: i16 = 48; @@ -47,35 +44,6 @@ impl Component for WelcomeScreen { None } - fn paint(&mut self) { - let logo = if self.empty_lock { - theme::ICON_LOGO_EMPTY - } else { - theme::ICON_LOGO - }; - logo.draw( - self.area.top_center() + Offset::y(ICON_TOP_MARGIN), - Alignment2D::TOP_CENTER, - theme::FG, - theme::BG, - ); - #[cfg(not(feature = "bootloader"))] - display::text_center( - self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN), - model::FULL_NAME, - MODEL_NAME_FONT, - theme::FG, - theme::BG, - ); - #[cfg(feature = "bootloader")] - Icon::new(DEVICE_NAME).draw( - self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN), - Alignment2D::BOTTOM_CENTER, - theme::FG, - theme::BG, - ); - } - fn render<'s>(&'s self, target: &mut impl Renderer<'s>) { let logo = if self.empty_lock { theme::ICON_LOGO_EMPTY diff --git a/core/embed/rust/src/ui/model_tt/constant.rs b/core/embed/rust/src/ui/model_tt/constant.rs index 914a6ac425..b2f6bf9508 100644 --- a/core/embed/rust/src/ui/model_tt/constant.rs +++ b/core/embed/rust/src/ui/model_tt/constant.rs @@ -7,9 +7,6 @@ pub const HEIGHT: i16 = DISPLAY_RESY as _; pub const LINE_SPACE: i16 = 4; pub const FONT_BPP: i16 = 4; -#[cfg(not(feature = "new_rendering"))] -pub const LOADER_OUTER: i16 = 60; -#[cfg(feature = "new_rendering")] pub const LOADER_OUTER: i16 = 59; pub const LOADER_INNER: i16 = 42; diff --git a/core/embed/rust/src/ui/shape/cache/jpeg_cache.rs b/core/embed/rust/src/ui/shape/cache/jpeg_cache.rs index 6f03cb2ce2..8adb672dd5 100644 --- a/core/embed/rust/src/ui/shape/cache/jpeg_cache.rs +++ b/core/embed/rust/src/ui/shape/cache/jpeg_cache.rs @@ -1,13 +1,13 @@ use crate::{ io::BinaryData, ui::{ - display::tjpgd, geometry::{Offset, Point, Rect}, shape::{BasicCanvas, Bitmap, BitmapFormat, BitmapView, Canvas, Rgb565Canvas}, }, }; use core::cell::UnsafeCell; +use trezor_tjpgdec as tjpgd; use without_alloc::alloc::LocalAllocLeakExt; // JDEC work buffer size diff --git a/core/embed/rust/src/ui/shape/display/mod.rs b/core/embed/rust/src/ui/shape/display/mod.rs index 5fba9b1b57..d980afec80 100644 --- a/core/embed/rust/src/ui/shape/display/mod.rs +++ b/core/embed/rust/src/ui/shape/display/mod.rs @@ -13,12 +13,6 @@ pub mod fb_rgba8888; #[cfg(all(not(feature = "xframebuffer"), feature = "display_rgb565"))] pub mod nofb_rgb565; -#[cfg(not(feature = "new_rendering"))] -mod _new_rendering { - pub use super::fake_display::{render_on_display, ConcreteRenderer}; -} - -#[cfg(feature = "new_rendering")] mod _new_rendering { #[cfg(not(feature = "xframebuffer"))] mod _xframebuffer { diff --git a/core/embed/rust/src/ui/ui_features.rs b/core/embed/rust/src/ui/ui_features.rs index a7f6c68f1c..2aca8f45df 100644 --- a/core/embed/rust/src/ui/ui_features.rs +++ b/core/embed/rust/src/ui/ui_features.rs @@ -3,9 +3,6 @@ use crate::ui::geometry::Rect; #[cfg(feature = "bootloader")] use crate::trezorhal::secbool::secbool; -#[cfg(not(feature = "new_rendering"))] -use crate::ui::display::Color; - pub trait UIFeaturesCommon { fn fadein() {} fn fadeout() {} @@ -38,9 +35,6 @@ pub trait UIFeaturesCommon { pub trait UIFeaturesBootloader { fn screen_welcome(); - #[cfg(not(feature = "new_rendering"))] - fn bld_continue_label(bg_color: Color); - fn screen_install_success(restart_seconds: u8, initial_setup: bool, complete_draw: bool); fn screen_install_fail(); @@ -77,7 +71,6 @@ pub trait UIFeaturesBootloader { fn screen_wipe_fail(); - #[cfg(feature = "new_rendering")] fn screen_boot( warning: bool, vendor_str: Option<&str>, diff --git a/core/embed/rust/src/ui/util.rs b/core/embed/rust/src/ui/util.rs index 99707d6a98..fe6a5e203f 100644 --- a/core/embed/rust/src/ui/util.rs +++ b/core/embed/rust/src/ui/util.rs @@ -1,12 +1,4 @@ -use crate::{ - strutil::{ShortString, TString}, - ui::{ - component::text::TextStyle, - display, - display::toif::Icon, - geometry::{Alignment2D, Offset, Point}, - }, -}; +use crate::strutil::ShortString; use super::display::Font; @@ -92,38 +84,6 @@ pub fn animation_disabled() -> bool { #[cfg(not(feature = "ui_debug"))] pub fn set_animation_disabled(_disabled: bool) {} -/// Display an icon and a text centered relative to given `Point`. -pub fn icon_text_center( - baseline: Point, - icon: Icon, - space: i16, - text: TString<'_>, - style: TextStyle, - text_offset: Offset, -) { - text.map(|t| { - let icon_width = icon.toif.width(); - let text_width = style.text_font.text_width(t); - let text_height = style.text_font.text_height(); - let text_center = baseline + Offset::new((icon_width + space) / 2, text_height / 2); - let icon_center = baseline - Offset::x((text_width + space) / 2); - - display::text_center( - text_center + text_offset, - t, - style.text_font, - style.text_color, - style.background_color, - ); - icon.draw( - icon_center, - Alignment2D::CENTER, - style.text_color, - style.background_color, - ); - }); -} - /// Convert char to a ShortString. pub fn char_to_string(ch: char) -> ShortString { let mut s = ShortString::new(); diff --git a/core/embed/rust/trezorhal.h b/core/embed/rust/trezorhal.h index 014be2bd4a..1048d6da7c 100644 --- a/core/embed/rust/trezorhal.h +++ b/core/embed/rust/trezorhal.h @@ -1,10 +1,7 @@ #include -#include "buffers.h" #include "button.h" #include "display.h" -#include "display_draw.h" -#include "dma2d.h" #include "dma2d_bitblt.h" #include "entropy.h" #include "flash.h"