diff --git a/core/embed/rust/src/ui/shape/canvas/common.rs b/core/embed/rust/src/ui/shape/canvas/common.rs index ceaff693c1..796b74d2f8 100644 --- a/core/embed/rust/src/ui/shape/canvas/common.rs +++ b/core/embed/rust/src/ui/shape/canvas/common.rs @@ -81,7 +81,7 @@ pub trait Canvas: BasicCanvas { /// Draws a single pixel and blends its color with the background. /// /// - If alpha == 255, the (foreground) pixel color is used. - /// - If 0 < alpha << 255, pixel and backround colors are blended. + /// - If 0 < alpha << 255, pixel and background colors are blended. /// - If alpha == 0, the background color is used. fn blend_pixel(&mut self, pt: Point, color: Color, alpha: u8); @@ -364,7 +364,7 @@ pub trait Canvas: BasicCanvas { // Draws circle with the specified center and the radius. #[cfg(not(feature = "ui_antialiasing"))] - fn draw_circle(&mut self, center: Point, radius: i16, color: Color) { + fn draw_circle(&mut self, center: Point, radius: i16, color: Color, alpha: u8) { let split = unwrap!(circle_points(radius).last()).v; let r = Rect::new( @@ -376,8 +376,8 @@ pub trait Canvas: BasicCanvas { for p in circle_points(radius) { let pt_l = Point::new(center.x - p.u, center.y - p.v); let pt_r = Point::new(center.x + p.u, center.y - p.v); - self.draw_pixel(pt_l, color); - self.draw_pixel(pt_r, color); + self.blend_pixel(pt_l, color, alpha); + self.blend_pixel(pt_r, color, alpha); } } @@ -390,8 +390,8 @@ pub trait Canvas: BasicCanvas { for p in circle_points(radius).take_while(|p| p.u < p.v) { let pt_l = Point::new(center.x - p.v, center.y - p.u); let pt_r = Point::new(center.x + p.v, center.y - p.u); - self.draw_pixel(pt_l, color); - self.draw_pixel(pt_r, color); + self.blend_pixel(pt_l, color, alpha); + self.blend_pixel(pt_r, color, alpha); } } @@ -404,8 +404,8 @@ pub trait Canvas: BasicCanvas { for p in circle_points(radius).skip(1).take_while(|p| p.u < p.v) { let pt_l = Point::new(center.x - p.v, center.y + p.u); let pt_r = Point::new(center.x + p.v, center.y + p.u); - self.draw_pixel(pt_l, color); - self.draw_pixel(pt_r, color); + self.blend_pixel(pt_l, color, alpha); + self.blend_pixel(pt_r, color, alpha); } } @@ -418,17 +418,16 @@ pub trait Canvas: BasicCanvas { for p in circle_points(radius) { let pt_l = Point::new(center.x - p.u, center.y + p.v); let pt_r = Point::new(center.x + p.u, center.y + p.v); - self.draw_pixel(pt_l, color); - self.draw_pixel(pt_r, color); + self.blend_pixel(pt_l, color, alpha); + self.blend_pixel(pt_r, color, alpha); } } } /// Draws filled circle with the specified center and the radius. #[cfg(not(feature = "ui_antialiasing"))] - fn fill_circle(&mut self, center: Point, radius: i16, color: Color) { + fn fill_circle(&mut self, center: Point, radius: i16, color: Color, alpha: u8) { let split = unwrap!(circle_points(radius).last()).v; - let alpha = 255; let r = Rect::new( Point::new(center.x - radius, center.y - radius), @@ -490,10 +489,9 @@ pub trait Canvas: BasicCanvas { /// Draws antialiased filled circle with the specified center and the /// radius. #[cfg(feature = "ui_antialiasing")] - fn fill_circle(&mut self, center: Point, radius: i16, color: Color) { + fn fill_circle(&mut self, center: Point, radius: i16, color: Color, alpha: u8) { let split = unwrap!(circle_points(radius).last()).v; - let alpha = 255; let alpha_mul = |a: u8| -> u8 { ((a as u16 * alpha as u16) / 255) as u8 }; let r = Rect::new( diff --git a/core/embed/rust/src/ui/shape/circle.rs b/core/embed/rust/src/ui/shape/circle.rs index 95296e0cba..40778838c6 100644 --- a/core/embed/rust/src/ui/shape/circle.rs +++ b/core/embed/rust/src/ui/shape/circle.rs @@ -14,6 +14,7 @@ pub struct Circle { fg_color: Option, bg_color: Option, thickness: i16, + alpha: u8, start_angle: Option, end_angle: Option, } @@ -26,6 +27,7 @@ impl Circle { fg_color: None, bg_color: None, thickness: 1, + alpha: 255, start_angle: None, end_angle: None, } @@ -49,6 +51,10 @@ impl Circle { Self { thickness, ..self } } + pub fn with_alpha(self, alpha: u8) -> Self { + Self { alpha, ..self } + } + pub fn with_start_angle(self, from_angle: i16) -> Self { Self { start_angle: Some(from_angle), @@ -94,22 +100,22 @@ impl Shape<'_> for Circle { if self.start_angle.is_none() && self.end_angle.is_none() { if th == 1 { if let Some(color) = self.bg_color { - canvas.fill_circle(self.center, self.radius, color); + canvas.fill_circle(self.center, self.radius, color, self.alpha); } if let Some(color) = self.fg_color { #[cfg(not(feature = "ui_antialiasing"))] - canvas.draw_circle(self.center, self.radius, color); + canvas.draw_circle(self.center, self.radius, color, self.alpha); #[cfg(feature = "ui_antialiasing")] - canvas.fill_circle(self.center, self.radius, color); + canvas.fill_circle(self.center, self.radius, color, self.alpha); } } else { if let Some(color) = self.fg_color { if th > 0 { - canvas.fill_circle(self.center, self.radius, color); + canvas.fill_circle(self.center, self.radius, color, self.alpha); } } if let Some(color) = self.bg_color { - canvas.fill_circle(self.center, self.radius - th, color); + canvas.fill_circle(self.center, self.radius - th, color, self.alpha); } } } else { diff --git a/core/embed/rust/src/ui/shape/text.rs b/core/embed/rust/src/ui/shape/text.rs index f0d80f123f..adcc820779 100644 --- a/core/embed/rust/src/ui/shape/text.rs +++ b/core/embed/rust/src/ui/shape/text.rs @@ -15,6 +15,8 @@ pub struct Text<'a> { text: &'a str, // Text color color: Color, + // Text alpha + alpha: u8, // Text font font: Font, // Horizontal alignment @@ -31,6 +33,7 @@ impl<'a> Text<'a> { pos, text, color: Color::white(), + alpha: 255, font: Font::NORMAL, align: Alignment::Start, bounds: Rect::zero(), @@ -49,6 +52,10 @@ impl<'a> Text<'a> { Self { align, ..self } } + pub fn with_alpha(self, alpha: u8) -> Self { + Self { alpha, ..self } + } + pub fn render<'r>(mut self, renderer: &mut impl Renderer<'r>) { self.bounds = self.calc_bounds(); renderer.render_shape(self); @@ -98,6 +105,7 @@ impl<'a> Shape<'_> for Text<'a> { let glyph = self.font.get_glyph(ch); let glyph_bitmap = glyph.bitmap(); let glyph_view = BitmapView::new(&glyph_bitmap) + .with_alpha(self.alpha) .with_fg(self.color) .with_offset(Offset::new( -glyph.bearing_x, diff --git a/core/embed/rust/src/ui/shape/toif.rs b/core/embed/rust/src/ui/shape/toif.rs index a4be22c0f9..6d3b655d11 100644 --- a/core/embed/rust/src/ui/shape/toif.rs +++ b/core/embed/rust/src/ui/shape/toif.rs @@ -22,6 +22,8 @@ pub struct ToifImage<'a> { fg_color: Color, // Optional background color bg_color: Option, + // Alpha value + alpha: u8, /// Final size calculated from TOIF data size: Offset, } @@ -34,6 +36,7 @@ impl<'a> ToifImage<'a> { toif, fg_color: Color::white(), bg_color: None, + alpha: 255, size: Offset::zero(), } } @@ -45,6 +48,7 @@ impl<'a> ToifImage<'a> { toif: toif.original_data().into(), fg_color: Color::white(), bg_color: None, + alpha: 255, size: Offset::zero(), } } @@ -64,6 +68,10 @@ impl<'a> ToifImage<'a> { } } + pub fn with_alpha(self, alpha: u8) -> Self { + Self { alpha, ..self } + } + pub fn render(mut self, renderer: &mut impl Renderer<'a>) { self.size = self.calc_size(); renderer.render_shape(self); @@ -106,7 +114,8 @@ impl<'a> ToifImage<'a> { let slice_view = slice .view() .with_fg(self.fg_color) - .with_offset(Offset::new(r.x0 - bounds.top_left().x, 0)); + .with_offset(Offset::new(r.x0 - bounds.top_left().x, 0)) + .with_alpha(self.alpha); match self.bg_color { Some(bg_color) => canvas.draw_bitmap(r, slice_view.with_bg(bg_color)),