st7305_lcd/framebuffer/
window.rs1use embedded_graphics_core::{
2 geometry::{Point, Size},
3 primitives::Rectangle,
4};
5
6use super::PixelMap;
7use crate::cmd::base::{ColumnAddressSet, RowAddressSet};
8
9const BAND: u32 = 12;
11const PAIR: u32 = 2;
13const BAND_BYTES: usize = 3;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct Window {
27 area: Rectangle,
29 caset_first: u8,
30 raset_first: u8,
31}
32
33impl Window {
34 pub fn covering<M: PixelMap>(area: Rectangle) -> Option<Self> {
40 let panel = Rectangle::new(Point::zero(), Size::new(M::WIDTH, M::HEIGHT));
41 let bottom_right = area.intersection(&panel).bottom_right()?; let top_left = area.intersection(&panel).top_left;
43
44 let x0 = top_left.x as u32 / PAIR * PAIR;
46 let y0 = top_left.y as u32 / BAND * BAND;
47 let x1 = (bottom_right.x as u32 / PAIR + 1) * PAIR; let y1 = (bottom_right.y as u32 / BAND + 1) * BAND;
49
50 Some(Self {
51 area: Rectangle::new(
52 Point::new(x0 as i32, y0 as i32),
53 Size::new(x1 - x0, y1 - y0),
54 ),
55 caset_first: M::CASET_FIRST,
56 raset_first: M::RASET_FIRST,
57 })
58 }
59
60 pub fn full<M: PixelMap>() -> Self {
62 let panel = Rectangle::new(Point::zero(), Size::new(M::WIDTH, M::HEIGHT));
63 Self::covering::<M>(panel).expect("a panel has pixels")
64 }
65
66 pub const fn bounds(&self) -> Rectangle {
68 self.area
69 }
70
71 pub const fn byte_len(&self) -> usize {
73 (self.pairs() * self.bands()) as usize * BAND_BYTES
74 }
75
76 pub fn column_address_set(&self) -> ColumnAddressSet {
78 let xs = u32::from(self.caset_first) + self.band0();
79 ColumnAddressSet::new(xs as u8, (xs + self.bands() - 1) as u8)
80 }
81
82 pub fn row_address_set(&self) -> RowAddressSet {
84 let ys = u32::from(self.raset_first) + self.pair0();
85 RowAddressSet::new(ys as u8, (ys + self.pairs() - 1) as u8)
86 }
87
88 const fn pair0(&self) -> u32 {
89 self.area.top_left.x as u32 / PAIR
90 }
91
92 const fn pairs(&self) -> u32 {
93 self.area.size.width / PAIR
94 }
95
96 const fn band0(&self) -> u32 {
97 self.area.top_left.y as u32 / BAND
98 }
99
100 const fn bands(&self) -> u32 {
101 self.area.size.height / BAND
102 }
103
104 pub(super) fn copy_from<'a>(&self, buf: &[u8], height: u32, out: &'a mut [u8]) -> &'a [u8] {
111 let out = &mut out[..self.byte_len()];
112 let column = (height / 4) as usize; let width = self.bands() as usize * BAND_BYTES;
114 let offset = column - (self.band0() + self.bands()) as usize * BAND_BYTES;
116 let pair0 = self.pair0() as usize;
117
118 for (i, chunk) in out.chunks_exact_mut(width).enumerate() {
119 let start = (pair0 + i) * column + offset;
120 chunk.copy_from_slice(&buf[start..start + width]);
121 }
122 out
123 }
124}