1use crate::color::*;
4use crate::PixelData;
5use crate::PixelDraw;
6use crate::Color;
7use std::cmp::min;
8use std::cmp::max;
9
10
11#[derive(Debug,Default)]
14pub struct RenderingBase<T> {
15 pub pixf: T,
17}
18
19impl<T> RenderingBase<T> where T: PixelDraw {
20 pub fn new(pixf: T) -> RenderingBase<T> {
22 RenderingBase { pixf }
23 }
24 pub fn clear(&mut self, color: Rgba8) {
26 self.pixf.fill(color);
27 }
28 pub fn limits(&self) -> (i64,i64,i64,i64) {
30 let w = self.pixf.width() as i64;
31 let h = self.pixf.height() as i64;
32 (0, w-1, 0, h-1)
33 }
34 pub fn blend_hline<C: Color>(&mut self, x1: i64, y: i64, x2: i64, c: C, cover: u64) {
36 let (xmin,xmax,ymin,ymax) = self.limits();
37 let (x1,x2) = if x2 > x1 { (x1,x2) } else { (x2,x1) };
38 if y > ymax || y < ymin || x1 > xmax || x2 < xmin {
39 return;
40 }
41 let x1 = max(x1, xmin);
42 let x2 = min(x2, xmax);
43 self.pixf.blend_hline(x1, y, x2 - x1 + 1, c, cover);
44 }
45 pub fn blend_solid_hspan<C: Color>(&mut self, x: i64, y: i64, len: i64, c: C, covers: &[u64]) {
47 let (xmin,xmax,ymin,ymax) = self.limits();
51 if y > ymax || y < ymin {
52 return;
53 }
54 let (mut x, mut len, mut off) = (x,len, 0);
55 if x < xmin {
56 len -= xmin - x;
57 if len <= 0 {
58 return;
59 }
60 off = off + xmin - x; x = xmin;
62 }
63 if x + len > xmax {
64 len = xmax - x + 1;
66 if len <= 0 {
67 return;
68 }
69 }
70 let covers_win = &covers[off as usize .. (off+len) as usize];
71 assert!(len as usize <= covers[off as usize ..].len());
73 self.pixf.blend_solid_hspan(x, y, len, c, covers_win);
74 }
76 pub fn blend_solid_vspan<C: Color>(&mut self, x: i64, y: i64, len: i64, c: C, covers: &[u64]) {
78 let (xmin,xmax,ymin,ymax) = self.limits();
81 if x > xmax || x < xmin {
82 return;
83 }
84 let (mut y, mut len, mut off) = (y,len, 0);
85 if y < ymin {
86 len -= ymin - y;
87 if len <= 0 {
88 return;
89 }
90 off = off + ymin - y; y = ymin;
92 }
93 if y + len > ymax {
94 len = ymax - y + 1;
96 if len <= 0 {
97 return;
98 }
99 }
100 let covers_win = &covers[off as usize .. (off+len) as usize];
101 assert!(len as usize <= covers[off as usize ..].len());
103 self.pixf.blend_solid_vspan(x, y, len, c, covers_win);
104 }
106
107 pub fn blend_color_vspan<C: Color>(&mut self, x: i64, y: i64, len: i64, colors: &[C], covers: &[u64], cover: u64) {
108 let (xmin,xmax,ymin,ymax) = self.limits();
109 if x > xmax || x < xmin {
110 return;
111 }
112 let (mut y, mut len, mut off) = (y,len, 0);
113 if y < ymin {
114 len -= ymin - y;
115 if len <= 0 {
116 return;
117 }
118 off = off + ymin - y; y = ymin;
120 }
121 if y + len > ymax {
122 len = ymax - y + 1;
124 if len <= 0 {
125 return;
126 }
127 }
128 let covers_win = if covers.is_empty() {
129 &[]
130 } else {
131 &covers[off as usize .. (off+len) as usize]
132 };
133 let colors_win = &colors[off as usize .. (off+len) as usize];
134 self.pixf.blend_color_vspan(x, y, len, colors_win, covers_win, cover);
135 }
136 pub fn blend_color_hspan<C: Color>(&mut self, x: i64, y: i64, len: i64, colors: &[C], covers: &[u64], cover: u64) {
137 let (xmin,xmax,ymin,ymax) = self.limits();
138 if y > ymax || y < ymin {
139 return;
140 }
141 let (mut x, mut len, mut off) = (x,len, 0);
142 if x < xmin {
143 len -= xmin - x;
144 if len <= 0 {
145 return;
146 }
147 off = off + xmin - x; x = xmin;
149 }
150 if x + len > xmax {
151 len = xmax - x + 1;
153 if len <= 0 {
154 return;
155 }
156 }
157 let covers_win = if covers.is_empty() {
158 &[]
159 } else {
160 &covers[off as usize .. (off+len) as usize]
161 };
162 let colors_win = &colors[off as usize .. (off+len) as usize];
163 self.pixf.blend_color_hspan(x, y, len, colors_win, covers_win, cover);
164 }
165}
166
167impl<T> PixelData for RenderingBase<T> where T: PixelData {
168 fn pixeldata(&self) -> &[u8] {
169 & self.pixf.pixeldata()
170 }
171}