agg/
base.rs

1//! Rendering Base
2
3use crate::color::*;
4use crate::PixelData;
5use crate::PixelDraw;
6use crate::Color;
7use std::cmp::min;
8use std::cmp::max;
9
10
11/// Rendering Base
12///
13#[derive(Debug,Default)]
14pub struct RenderingBase<T> {
15    /// Pixel Format
16    pub pixf: T,
17}
18
19impl<T> RenderingBase<T> where T: PixelDraw {
20    /// Create new Rendering Base from Pixel Format
21    pub fn new(pixf: T) -> RenderingBase<T> {
22        RenderingBase { pixf }
23    }
24    /// Set Image to a single color 
25    pub fn clear(&mut self, color: Rgba8) {
26        self.pixf.fill(color);
27    }
28    /// Get Image size
29    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    /// Blend a color along y-row from x1 to x2
35    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    /// Blend a color from (x,y) with variable covers
46    pub fn blend_solid_hspan<C: Color>(&mut self, x: i64, y: i64, len: i64, c: C, covers: &[u64]) {
47        //eprintln!("blend_color_hspan, cover_full {:?}", covers);
48        //eprintln!("RENBASE BLEND_SOLID_HSPAN x,y {:4} {:4} len {:4}", x, y, len );
49        //eprintln!("DRAW: blend_solid_hspan() x,y {} {} len {} RENBASE", x, y, len );
50        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; // Woah!!!!
61            x = xmin;
62        }
63        if x + len > xmax {
64            //eprintln!("X+LEN > XMAX");
65            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        //eprintln!("RENBASE BLEND_SOLID_HSPAN x,y {:4} {:4} OFF {:4} LEN {:4} {:4} ", x, y, off, len, covers.len());
72        assert!(len as usize <= covers[off as usize ..].len());
73        self.pixf.blend_solid_hspan(x, y, len, c, covers_win);
74        //eprintln!("RENBASE BLEND SOLID HSPAN DONE");
75    }
76    /// Blend a color from (x,y) with variable covers
77    pub fn blend_solid_vspan<C: Color>(&mut self, x: i64, y: i64, len: i64, c: C, covers: &[u64]) {
78        //eprintln!("RENBASE BLEND_SOLID_VSPAN x,y {:4} {:4} len {:4}", x, y, len );
79        //eprintln!("DRAW: blend_solid_vspan() x,y {} {} len {} RENBASE", x, y, len );
80        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; // Woah!!!!
91            y = ymin;
92        }
93        if y + len > ymax {
94            //eprintln!("X+LEN > XMAX");
95            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        //eprintln!("RENBASE BLEND_SOLID_VSPAN x,y {:4} {:4} OFF {:4} LEN {:4} {:4}", x, y, off, len, covers.len());
102        assert!(len as usize <= covers[off as usize ..].len());
103        self.pixf.blend_solid_vspan(x, y, len, c, covers_win);
104        //eprintln!("RENBASE BLEND SOLID HSPAN DONE");
105    }
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; // Woah!!!!
119            y = ymin;
120        }
121        if y + len > ymax {
122            //eprintln!("X+LEN > XMAX");
123            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; // Woah!!!!
148            x = xmin;
149        }
150        if x + len > xmax {
151            //eprintln!("X+LEN > XMAX");
152            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}