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