mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-22 22:48:20 +00:00
fixup! feat(core): introduce new drawing library
This commit is contained in:
parent
5cb2abd3c8
commit
434b272f44
@ -1,41 +0,0 @@
|
||||
use crate::ui::{display::Color, geometry::Offset};
|
||||
|
||||
use super::{BasicCanvas, Canvas, Mono8Canvas};
|
||||
|
||||
use crate::trezorhal::display;
|
||||
|
||||
pub struct MonoDisplay<'a> {
|
||||
canvas: Mono8Canvas<'a>,
|
||||
}
|
||||
|
||||
impl<'a> MonoDisplay<'a> {
|
||||
pub fn new(size: Offset, buff: &'a mut [u8]) -> Option<Self> {
|
||||
Some(Self {
|
||||
canvas: Mono8Canvas::new(size, None, buff)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn canvas(&mut self) -> &mut Mono8Canvas<'a> {
|
||||
&mut self.canvas
|
||||
}
|
||||
|
||||
pub fn refresh(&self) {
|
||||
// TODO:
|
||||
|
||||
let w = self.canvas.width() as u16 - 1;
|
||||
let h = self.canvas.height() as u16 - 1;
|
||||
display::set_window(0, 0, w, h);
|
||||
|
||||
let view = self.canvas.view();
|
||||
|
||||
for y in 0..self.canvas.size().y {
|
||||
let row = unwrap!(view.row(y));
|
||||
for value in row.iter() {
|
||||
let c = Color::rgb(*value, *value, *value);
|
||||
display::pixeldata(c.into());
|
||||
}
|
||||
}
|
||||
|
||||
display::refresh();
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
use crate::ui::{
|
||||
display::Color,
|
||||
geometry::{Offset, Rect},
|
||||
};
|
||||
|
||||
use super::{BasicCanvas, BitmapView, Viewport};
|
||||
|
||||
use crate::trezorhal::bitmap::Dma2d;
|
||||
|
||||
// ==========================================================================
|
||||
// Display canvas
|
||||
// ==========================================================================
|
||||
|
||||
pub struct Wnd565Display {
|
||||
size: Offset,
|
||||
viewport: Viewport,
|
||||
}
|
||||
|
||||
impl Wnd565Display {
|
||||
pub fn acquire() -> Option<Self> {
|
||||
let size = Offset::new(240, 240); // TODO
|
||||
let viewport = Viewport::from_size(size);
|
||||
Some(Self { size, viewport })
|
||||
}
|
||||
}
|
||||
|
||||
impl BasicCanvas for Wnd565Display {
|
||||
fn viewport(&self) -> Viewport {
|
||||
self.viewport
|
||||
}
|
||||
|
||||
fn set_viewport(&mut self, viewport: Viewport) {
|
||||
self.viewport = viewport.absolute_clip(self.bounds());
|
||||
}
|
||||
|
||||
fn size(&self) -> Offset {
|
||||
self.size
|
||||
}
|
||||
|
||||
fn fill_rect(&mut self, r: Rect, color: Color) {
|
||||
let r = r.translate(self.viewport.origin);
|
||||
Dma2d::wnd565_fill(r, self.viewport.clip, color);
|
||||
}
|
||||
|
||||
fn draw_bitmap(&mut self, r: Rect, bitmap: BitmapView) {
|
||||
let r = r.translate(self.viewport.origin);
|
||||
Dma2d::wnd565_copy(r, self.viewport.clip, &bitmap);
|
||||
}
|
||||
}
|
@ -51,12 +51,12 @@ impl Bar {
|
||||
Self { thickness, ..self }
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render<'s>(self, renderer: &mut impl Renderer<'s>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl Shape for Bar {
|
||||
impl Shape<'_> for Bar {
|
||||
fn bounds(&self, _cache: &DrawingCache) -> Rect {
|
||||
self.area
|
||||
}
|
||||
@ -110,8 +110,8 @@ impl Shape for Bar {
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeClone for Bar {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'s> ShapeClone<'s> for Bar {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'s>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
@ -16,23 +16,23 @@ use without_alloc::alloc::LocalAllocLeakExt;
|
||||
///
|
||||
/// `Shape` objects may use `DrawingCache` as a scratch-pad memory or for
|
||||
/// caching expensive calculations results.
|
||||
pub trait Shape {
|
||||
pub trait Shape<'s> {
|
||||
/// Returns the smallest bounding rectangle containing whole parts of the
|
||||
/// shape.
|
||||
///
|
||||
/// The function is used by renderer for optimization if the shape
|
||||
/// must be renderer or not.
|
||||
fn bounds(&self, cache: &DrawingCache) -> Rect;
|
||||
fn bounds(&self, cache: &DrawingCache<'s>) -> Rect;
|
||||
|
||||
/// Draws shape on the canvas.
|
||||
fn draw(&mut self, canvas: &mut dyn Canvas, cache: &DrawingCache);
|
||||
fn draw(&mut self, canvas: &mut dyn Canvas, cache: &DrawingCache<'s>);
|
||||
|
||||
/// The function should release all allocated resources needed
|
||||
/// for shape drawing.
|
||||
///
|
||||
/// It's called by renderer if the shape's draw() function won't be called
|
||||
/// anymore.
|
||||
fn cleanup(&mut self, cache: &DrawingCache);
|
||||
fn cleanup(&mut self, cache: &DrawingCache<'s>);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
@ -41,12 +41,13 @@ pub trait Shape {
|
||||
|
||||
/// All shapes (like `Bar`, `Text`, `Circle`, ...) that can be rendered
|
||||
/// by `ProgressiveRender` must implement `ShapeClone`.
|
||||
pub trait ShapeClone {
|
||||
pub trait ShapeClone<'s> {
|
||||
/// Clones a shape object at the specified memory bump.
|
||||
///
|
||||
/// The method is used by `ProgressiveRenderer` to store shape objects for
|
||||
/// deferred drawing.
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'s>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>;
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
'alloc: 's;
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ impl Blurring {
|
||||
Self { area, radius }
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render<'s>(self, renderer: &mut impl Renderer<'s>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl Shape for Blurring {
|
||||
impl Shape<'_> for Blurring {
|
||||
fn bounds(&self, _cache: &DrawingCache) -> Rect {
|
||||
self.area
|
||||
}
|
||||
@ -34,8 +34,8 @@ impl Shape for Blurring {
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeClone for Blurring {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'s> ShapeClone<'s> for Blurring {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'s>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
@ -160,7 +160,7 @@ impl<'a> JpegCacheSlot<'a> {
|
||||
}
|
||||
|
||||
let decoder = unwrap!(self.decoder.as_mut()); // should never fail
|
||||
let input = unwrap!(self.input.as_mut()); // shoud never fail
|
||||
let input = unwrap!(self.input.as_mut()); // should never fail
|
||||
let mut output = JpegFnOutput::new(output);
|
||||
|
||||
match decoder.decomp2(input, &mut output) {
|
||||
|
@ -36,7 +36,7 @@ impl<'a> ZlibCacheSlot<'a> {
|
||||
}
|
||||
|
||||
/// May be called with zdata == &[] to make the slot free
|
||||
fn reset(&mut self, zdata: &'static [u8]) {
|
||||
fn reset(&mut self, zdata: &'a [u8]) {
|
||||
// Drop the existing decompression context holding
|
||||
// a mutable reference to window buffer
|
||||
self.dc = None;
|
||||
@ -133,7 +133,7 @@ impl<'a> ZlibCache<'a> {
|
||||
|
||||
pub fn uncompress(
|
||||
&mut self,
|
||||
zdata: &'static [u8],
|
||||
zdata: &'a [u8],
|
||||
offset: usize,
|
||||
dest_buf: &mut [u8],
|
||||
) -> Result<bool, ()> {
|
||||
@ -155,7 +155,7 @@ impl<'a> ZlibCache<'a> {
|
||||
|
||||
pub fn uncompress_toif(
|
||||
&mut self,
|
||||
toif: Toif<'static>,
|
||||
toif: Toif<'a>,
|
||||
from_row: i16,
|
||||
dest_buf: &mut [u8],
|
||||
) -> Result<(), ()> {
|
||||
|
@ -64,12 +64,12 @@ impl Circle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render<'s>(self, renderer: &mut impl Renderer<'s>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl Shape for Circle {
|
||||
impl Shape<'_> for Circle {
|
||||
fn bounds(&self, _cache: &DrawingCache) -> Rect {
|
||||
let c = self.center;
|
||||
let r = self.radius;
|
||||
@ -129,8 +129,8 @@ impl Shape for Circle {
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeClone for Circle {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'s> ShapeClone<'s> for Circle {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'s>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
@ -8,13 +8,13 @@ use super::{DrawingCache, Renderer, Shape, ShapeClone};
|
||||
use without_alloc::alloc::LocalAllocLeakExt;
|
||||
|
||||
/// A shape for rendering compressed JPEG images.
|
||||
pub struct JpegImage {
|
||||
pub struct JpegImage<'a> {
|
||||
/// Image position
|
||||
pos: Point,
|
||||
// Image position alignment
|
||||
align: Alignment2D,
|
||||
/// JPEG data
|
||||
jpeg: &'static [u8],
|
||||
jpeg: &'a [u8],
|
||||
/// Scale factor (default 0)
|
||||
scale: u8,
|
||||
/// Blurring radius or 0 if no blurring required (default 0)
|
||||
@ -26,8 +26,8 @@ pub struct JpegImage {
|
||||
blur_tag: Option<u32>,
|
||||
}
|
||||
|
||||
impl JpegImage {
|
||||
pub fn new(pos: Point, jpeg: &'static [u8]) -> Self {
|
||||
impl<'a> JpegImage<'a> {
|
||||
pub fn new(pos: Point, jpeg: &'a [u8]) -> Self {
|
||||
JpegImage {
|
||||
pos,
|
||||
align: Alignment2D::TOP_LEFT,
|
||||
@ -59,18 +59,18 @@ impl JpegImage {
|
||||
Self { dim, ..self }
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render(self, renderer: &mut impl Renderer<'a>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl Shape for JpegImage {
|
||||
fn bounds(&self, cache: &DrawingCache) -> Rect {
|
||||
impl<'a> Shape<'a> for JpegImage<'a> {
|
||||
fn bounds(&self, cache: &DrawingCache<'a>) -> Rect {
|
||||
let size = unwrap!(cache.jpeg().get_size(self.jpeg, self.scale), "Invalid JPEG");
|
||||
Rect::from_top_left_and_size(size.snap(self.pos, self.align), size)
|
||||
}
|
||||
|
||||
fn cleanup(&mut self, _cache: &DrawingCache) {
|
||||
fn cleanup(&mut self, _cache: &DrawingCache<'a>) {
|
||||
self.blur_tag = None;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ impl Shape for JpegImage {
|
||||
// Faster implementation suitable for DirectRenderer without blurring support
|
||||
// (but is terribly slow on ProgressiveRenderer if slices are not aligned
|
||||
// to JPEG MCUs )
|
||||
fn draw(&mut self, canvas: &mut dyn RgbCanvasEx, cache: &DrawingCache) {
|
||||
fn draw(&mut self, canvas: &mut dyn RgbCanvasEx, cache: &DrawingCache<'a>) {
|
||||
let bounds = self.bounds(cache);
|
||||
let clip = canvas.viewport().relative_clip(bounds).clip;
|
||||
|
||||
@ -103,7 +103,7 @@ impl Shape for JpegImage {
|
||||
}*/
|
||||
|
||||
// This is a little bit slower implementation suitable for ProgressiveRenderer
|
||||
fn draw(&mut self, canvas: &mut dyn Canvas, cache: &DrawingCache) {
|
||||
fn draw(&mut self, canvas: &mut dyn Canvas, cache: &DrawingCache<'a>) {
|
||||
let bounds = self.bounds(cache);
|
||||
let clip = canvas.viewport().relative_clip(bounds).clip;
|
||||
|
||||
@ -188,8 +188,8 @@ impl Shape for JpegImage {
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeClone for JpegImage {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'a> ShapeClone<'a> for JpegImage<'a> {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'a>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
@ -8,9 +8,9 @@ use crate::ui::{
|
||||
|
||||
use static_alloc::Bump;
|
||||
|
||||
pub fn render_on_display<F>(clip: Option<Rect>, bg_color: Option<Color>, mut func: F)
|
||||
pub fn render_on_display<'a, F>(clip: Option<Rect>, bg_color: Option<Color>, func: F)
|
||||
where
|
||||
F: FnMut(&mut DirectRenderer<Mono8Canvas>),
|
||||
F: FnOnce(&mut DirectRenderer<'_, 'a, Mono8Canvas<'a>>),
|
||||
{
|
||||
// TODO: do not use constants 128 & 64 directly
|
||||
|
||||
@ -22,6 +22,8 @@ where
|
||||
|
||||
let bump = unsafe { &mut *core::ptr::addr_of_mut!(BUMP) };
|
||||
{
|
||||
bump.reset();
|
||||
|
||||
let cache = DrawingCache::new(bump, bump);
|
||||
let mut canvas = unwrap!(Mono8Canvas::new(Offset::new(128, 64), None, fb));
|
||||
|
||||
@ -35,7 +37,6 @@ where
|
||||
|
||||
refresh_display(&canvas);
|
||||
}
|
||||
bump.reset();
|
||||
}
|
||||
|
||||
fn refresh_display(canvas: &Mono8Canvas) {
|
||||
|
@ -9,9 +9,9 @@ use crate::trezorhal::bitmap::{BitmapView, Dma2d};
|
||||
|
||||
use static_alloc::Bump;
|
||||
|
||||
pub fn render_on_display<F>(clip: Option<Rect>, bg_color: Option<Color>, mut func: F)
|
||||
pub fn render_on_display<'a, F>(clip: Option<Rect>, bg_color: Option<Color>, func: F)
|
||||
where
|
||||
F: FnMut(&mut ProgressiveRenderer<Bump<[u8; 40 * 1024]>, DisplayModelT>),
|
||||
F: FnOnce(&mut ProgressiveRenderer<'_, 'a, Bump<[u8; 40 * 1024]>, DisplayModelT>),
|
||||
{
|
||||
#[link_section = ".no_dma_buffers"]
|
||||
static mut BUMP_A: Bump<[u8; 40 * 1024]> = Bump::uninit();
|
||||
@ -22,6 +22,9 @@ where
|
||||
let bump_a = unsafe { &mut *core::ptr::addr_of_mut!(BUMP_A) };
|
||||
let bump_b = unsafe { &mut *core::ptr::addr_of_mut!(BUMP_B) };
|
||||
{
|
||||
bump_a.reset();
|
||||
bump_b.reset();
|
||||
|
||||
let cache = DrawingCache::new(bump_a, bump_b);
|
||||
let mut canvas = DisplayModelT::acquire().unwrap();
|
||||
|
||||
@ -35,8 +38,6 @@ where
|
||||
|
||||
target.render(16);
|
||||
}
|
||||
bump_a.reset();
|
||||
bump_b.reset();
|
||||
}
|
||||
|
||||
pub struct DisplayModelT {
|
||||
|
@ -83,7 +83,7 @@ impl QrImage {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render<'s>(self, renderer: &mut impl Renderer<'s>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ impl QrImage {
|
||||
}
|
||||
}
|
||||
|
||||
impl Shape for QrImage {
|
||||
impl Shape<'_> for QrImage {
|
||||
fn bounds(&self, _cache: &DrawingCache) -> Rect {
|
||||
self.area
|
||||
}
|
||||
@ -157,8 +157,8 @@ impl Shape for QrImage {
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeClone for QrImage {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'s> ShapeClone<'s> for QrImage {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'s>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ use without_alloc::{alloc::LocalAllocLeakExt, FixedVec};
|
||||
/// All renders must implement Renderer trait
|
||||
/// Renderers can immediately use the draw() method of the passed shape or
|
||||
/// may store it (using the boxed() method) and draw it later
|
||||
pub trait Renderer {
|
||||
pub trait Renderer<'a> {
|
||||
fn viewport(&self) -> Viewport;
|
||||
|
||||
fn set_viewport(&mut self, viewport: Viewport);
|
||||
@ -33,7 +33,7 @@ pub trait Renderer {
|
||||
|
||||
fn render_shape<S>(&mut self, shape: S)
|
||||
where
|
||||
S: Shape + ShapeClone;
|
||||
S: Shape<'a> + ShapeClone<'a>;
|
||||
|
||||
fn in_window(&mut self, r: Rect, inner: &dyn Fn(&mut Self)) {
|
||||
let original = self.set_window(r);
|
||||
@ -60,13 +60,13 @@ pub trait Renderer {
|
||||
// ==========================================================================
|
||||
|
||||
/// A simple implementation of a Renderer that draws directly onto the CanvasEx
|
||||
pub struct DirectRenderer<'a, 'alloc: 'a, C>
|
||||
pub struct DirectRenderer<'a, 'alloc, C>
|
||||
where
|
||||
C: Canvas,
|
||||
{
|
||||
/// Target canvas
|
||||
canvas: &'a mut C,
|
||||
/// Drawing che (decompression cache, scratch-pad memory)
|
||||
/// Drawing cache (decompression context, scratch-pad memory)
|
||||
cache: &'a DrawingCache<'alloc>,
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'alloc, C> Renderer for DirectRenderer<'a, 'alloc, C>
|
||||
impl<'a, 'alloc, C> Renderer<'alloc> for DirectRenderer<'a, 'alloc, C>
|
||||
where
|
||||
C: Canvas,
|
||||
{
|
||||
@ -105,7 +105,7 @@ where
|
||||
|
||||
fn render_shape<S>(&mut self, mut shape: S)
|
||||
where
|
||||
S: Shape + ShapeClone,
|
||||
S: Shape<'alloc> + ShapeClone<'alloc>,
|
||||
{
|
||||
if self.canvas.viewport().contains(shape.bounds(self.cache)) {
|
||||
shape.draw(self.canvas, self.cache);
|
||||
@ -119,13 +119,14 @@ where
|
||||
// ==========================================================================
|
||||
|
||||
struct ShapeHolder<'a> {
|
||||
shape: &'a mut dyn Shape,
|
||||
shape: &'a mut dyn Shape<'a>,
|
||||
viewport: Viewport,
|
||||
}
|
||||
|
||||
/// A more advanced Renderer implementation that supports deferred rendering.
|
||||
pub struct ProgressiveRenderer<'a, 'alloc, T: LocalAllocLeakExt<'alloc>, C>
|
||||
pub struct ProgressiveRenderer<'a, 'alloc, T, C>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
C: BasicCanvas,
|
||||
{
|
||||
/// Target canvas
|
||||
@ -138,7 +139,7 @@ where
|
||||
viewport: Viewport,
|
||||
// Default background color
|
||||
bg_color: Option<Color>,
|
||||
/// Drawing cache (decompression cache, scratch-pad memory)
|
||||
/// Drawing cache (decompression context, scratch-pad memory)
|
||||
cache: &'a DrawingCache<'alloc>,
|
||||
}
|
||||
|
||||
@ -218,7 +219,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'alloc, T, C> Renderer for ProgressiveRenderer<'a, 'alloc, T, C>
|
||||
impl<'a, 'alloc, T, C> Renderer<'alloc> for ProgressiveRenderer<'a, 'alloc, T, C>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
C: BasicCanvas,
|
||||
@ -233,7 +234,7 @@ where
|
||||
|
||||
fn render_shape<S>(&mut self, shape: S)
|
||||
where
|
||||
S: Shape + ShapeClone,
|
||||
S: Shape<'alloc> + ShapeClone<'alloc>,
|
||||
{
|
||||
// Is the shape visible?
|
||||
if self.viewport.contains(shape.bounds(self.cache)) {
|
||||
|
@ -47,7 +47,7 @@ impl<'a> Text<'a> {
|
||||
Self { align, ..self }
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render<'r>(self, renderer: &mut impl Renderer<'r>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ impl<'a> Text<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Shape for Text<'a> {
|
||||
impl<'a> Shape<'_> for Text<'a> {
|
||||
fn bounds(&self, _cache: &DrawingCache) -> Rect {
|
||||
let pos = self.aligned_pos();
|
||||
let max_ascent = self.font.text_max_height() - self.font.text_baseline();
|
||||
@ -105,8 +105,8 @@ impl<'a> Shape for Text<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ShapeClone for Text<'a> {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'a, 's> ShapeClone<'s> for Text<'a> {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'s>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
@ -9,21 +9,21 @@ use super::{DrawingCache, Renderer, Shape, ShapeClone};
|
||||
use without_alloc::alloc::LocalAllocLeakExt;
|
||||
|
||||
/// A shape for rendering compressed TOIF images.
|
||||
pub struct ToifImage {
|
||||
pub struct ToifImage<'a> {
|
||||
/// Image position
|
||||
pos: Point,
|
||||
// Image position alignment
|
||||
align: Alignment2D,
|
||||
// Image data
|
||||
toif: Toif<'static>,
|
||||
toif: Toif<'a>,
|
||||
// Foreground color
|
||||
fg_color: Color,
|
||||
// Optional background color
|
||||
bg_color: Option<Color>,
|
||||
}
|
||||
|
||||
impl ToifImage {
|
||||
pub fn new(pos: Point, toif: Toif<'static>) -> Self {
|
||||
impl<'a> ToifImage<'a> {
|
||||
pub fn new(pos: Point, toif: Toif<'a>) -> Self {
|
||||
Self {
|
||||
pos,
|
||||
align: Alignment2D::TOP_LEFT,
|
||||
@ -48,11 +48,11 @@ impl ToifImage {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(self, renderer: &mut impl Renderer) {
|
||||
pub fn render(self, renderer: &mut impl Renderer<'a>) {
|
||||
renderer.render_shape(self);
|
||||
}
|
||||
|
||||
fn draw_grayscale(&self, canvas: &mut dyn Canvas, cache: &DrawingCache) {
|
||||
fn draw_grayscale(&self, canvas: &mut dyn Canvas, cache: &DrawingCache<'a>) {
|
||||
// TODO: introduce new viewport/shape function for this calculation
|
||||
let bounds = self.bounds(cache);
|
||||
let viewport = canvas.viewport();
|
||||
@ -100,7 +100,7 @@ impl ToifImage {
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_rgb(&self, canvas: &mut dyn Canvas, cache: &DrawingCache) {
|
||||
fn draw_rgb(&self, canvas: &mut dyn Canvas, cache: &DrawingCache<'a>) {
|
||||
// TODO: introduce new viewport/shape function for this calculation
|
||||
let bounds = self.bounds(cache);
|
||||
let viewport = canvas.viewport();
|
||||
@ -145,17 +145,17 @@ impl ToifImage {
|
||||
}
|
||||
}
|
||||
|
||||
impl Shape for ToifImage {
|
||||
fn bounds(&self, _cache: &DrawingCache) -> Rect {
|
||||
impl<'a> Shape<'a> for ToifImage<'a> {
|
||||
fn bounds(&self, _cache: &DrawingCache<'a>) -> Rect {
|
||||
let size = Offset::new(self.toif.width(), self.toif.height());
|
||||
Rect::from_top_left_and_size(size.snap(self.pos, self.align), size)
|
||||
}
|
||||
|
||||
fn cleanup(&mut self, _cache: &DrawingCache) {
|
||||
fn cleanup(&mut self, _cache: &DrawingCache<'a>) {
|
||||
// TODO: inform the cache that we won't use the zlib slot anymore
|
||||
}
|
||||
|
||||
fn draw(&mut self, canvas: &mut dyn Canvas, cache: &DrawingCache) {
|
||||
fn draw(&mut self, canvas: &mut dyn Canvas, cache: &DrawingCache<'a>) {
|
||||
if self.toif.is_grayscale() {
|
||||
self.draw_grayscale(canvas, cache);
|
||||
} else {
|
||||
@ -164,8 +164,8 @@ impl Shape for ToifImage {
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeClone for ToifImage {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape>
|
||||
impl<'a> ShapeClone<'a> for ToifImage<'a> {
|
||||
fn clone_at_bump<'alloc, T>(self, bump: &'alloc T) -> Option<&'alloc mut dyn Shape<'a>>
|
||||
where
|
||||
T: LocalAllocLeakExt<'alloc>,
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user