refactor(print): define blit rectangles

This commit is contained in:
Dylan M. Taylor
2026-10-28 03:24:18 +00:00
parent 33252920e3
commit e8f52cc07e
2 changed files with 17 additions and 6 deletions
+15 -4
View File
@@ -255,6 +255,15 @@ pub struct Image16 {
pub rgb: Vec<u16>,
}
/// A rectangular image region used as a source or destination for `Image16::blit`.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BlitRect {
pub x: usize,
pub y: usize,
pub w: usize,
pub h: usize,
}
impl Image16 {
pub fn filled(w: usize, h: usize, c: [u16; 3]) -> Result<Self, String> {
let n = w.checked_mul(h).and_then(|n| n.checked_mul(3)).ok_or("image too large")?;
@@ -284,9 +293,11 @@ impl Image16 {
}
/// Copies the `w` x `h` block of `src` at (`sx`, `sy`) to (`dx`, `dy`), clipped to both images.
pub fn blit(&mut self, src: &Image16, sx: usize, sy: usize, dx: usize, dy: usize, w: usize, h: usize) {
let w = w.min(src.w.saturating_sub(sx)).min(self.w.saturating_sub(dx));
let h = h.min(src.h.saturating_sub(sy)).min(self.h.saturating_sub(dy));
pub fn blit(&mut self, src: &Image16, source: BlitRect, destination: BlitRect) {
let BlitRect { x: sx, y: sy, .. } = source;
let BlitRect { x: dx, y: dy, .. } = destination;
let w = source.w.min(destination.w).min(src.w.saturating_sub(sx)).min(self.w.saturating_sub(dx));
let h = source.h.min(destination.h).min(src.h.saturating_sub(sy)).min(self.h.saturating_sub(dy));
for row in 0..h {
let from = src.rgb.get(((sy + row) * src.w + sx) * 3..((sy + row) * src.w + sx + w) * 3);
let to = self.rgb.get_mut(((dy + row) * self.w + dx) * 3..((dy + row) * self.w + dx + w) * 3);
@@ -424,7 +435,7 @@ pub fn draw_cell(page: &mut Image16, photo: &Image16, cell: PxRect, style: &Cell
if border > 0 {
page.fill_rect(dx - border, dy - border, w + 2 * border, h + 2 * border, style.border);
}
page.blit(&img, sx, sy, dx, dy, w, h);
page.blit(&img, BlitRect { x: sx, y: sy, w, h }, BlitRect { x: dx, y: dy, w, h });
let s = style.stroke_px.min(w.min(h) / 2);
if s > 0 {
page.fill_rect(dx, dy, w, s, style.stroke);
+2 -2
View File
@@ -182,9 +182,9 @@ fn rotate_and_blit_are_clipped() {
let r = img.rotated_cw().unwrap();
assert_eq!((r.w, r.h), (2, 3));
let mut p = page();
p.blit(&img, 0, 0, 99, 99, 10, 10);
p.blit(&img, BlitRect { x: 0, y: 0, w: 10, h: 10 }, BlitRect { x: 99, y: 99, w: 10, h: 10 });
assert_eq!(at(&p, 99, 99), at(&img, 0, 0));
p.blit(&img, 5, 5, 0, 0, 3, 3);
p.blit(&img, BlitRect { x: 5, y: 5, w: 3, h: 3 }, BlitRect { x: 0, y: 0, w: 3, h: 3 });
p.fill_rect(95, 95, 50, 50, RED);
assert_eq!(at(&p, 99, 99), RED);
p.fill_rect(usize::MAX, usize::MAX, usize::MAX, usize::MAX, RED);