1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
use super::{Coord, Size}; use rgb24::Rgb24; pub trait ViewTransformRgb24: Copy { fn transform(&self, rgb24: Rgb24) -> Rgb24; } impl<F: Fn(Rgb24) -> Rgb24 + Copy> ViewTransformRgb24 for F { fn transform(&self, rgb24: Rgb24) -> Rgb24 { (self)(rgb24) } } #[derive(Clone, Copy)] pub struct ViewTransformRgb24Identity; impl ViewTransformRgb24 for ViewTransformRgb24Identity { fn transform(&self, rgb24: Rgb24) -> Rgb24 { rgb24 } } #[derive(Clone, Copy)] pub struct ViewTransformRgb24Compose<Inner: ViewTransformRgb24, Outer: ViewTransformRgb24> { inner: Inner, outer: Outer, } impl<Inner, Outer> ViewTransformRgb24 for ViewTransformRgb24Compose<Inner, Outer> where Inner: ViewTransformRgb24, Outer: ViewTransformRgb24, { fn transform(&self, rgb24: Rgb24) -> Rgb24 { self.outer.transform(self.inner.transform(rgb24)) } } #[derive(Clone, Copy)] pub struct ViewContext<R: ViewTransformRgb24 = ViewTransformRgb24Identity> { pub inner_offset: Coord, pub outer_offset: Coord, pub depth: i32, pub transform_rgb24: R, pub size: Size, } impl ViewContext<ViewTransformRgb24Identity> { pub fn default_with_size(size: Size) -> Self { Self { inner_offset: Coord::new(0, 0), outer_offset: Coord::new(0, 0), depth: 0, transform_rgb24: ViewTransformRgb24Identity, size, } } } impl<R: ViewTransformRgb24> ViewContext<R> { pub fn new( inner_offset: Coord, outer_offset: Coord, depth: i32, transform_rgb24: R, size: Size, ) -> Self { Self { inner_offset, outer_offset, depth, transform_rgb24, size, } } pub fn add_inner_offset(self, offset_delta: Coord) -> Self { Self { inner_offset: self.inner_offset + offset_delta, ..self } } pub fn add_offset(self, offset_delta: Coord) -> Self { Self { outer_offset: self.outer_offset + offset_delta, size: (self.size.to_coord().unwrap() - offset_delta) .to_size() .unwrap_or(Size::new_u16(0, 0)), ..self } } pub fn add_depth(self, depth_delta: i32) -> Self { Self { depth: self.depth + depth_delta, ..self } } pub fn constrain_size_to(self, size: Size) -> Self { Self { size: Size::new(self.size.x().min(size.x()), self.size.y().min(size.y())), ..self } } pub fn constrain_size_by(self, size: Size) -> Self { Self { size: self.size.saturating_sub(size), ..self } } pub fn compose_transform_rgb24<Inner: ViewTransformRgb24>( self, inner: Inner, ) -> ViewContext<ViewTransformRgb24Compose<Inner, R>> { ViewContext { transform_rgb24: ViewTransformRgb24Compose { inner, outer: self.transform_rgb24, }, inner_offset: self.inner_offset, outer_offset: self.outer_offset, depth: self.depth, size: self.size, } } }