1use crate::color::Color;
12use glium::texture::{ClientFormat, RawImage2d, Texture2dDataSource};
13use std::{
14 borrow::Cow,
15 ops::{Deref, DerefMut, Index, IndexMut},
16};
17
18pub struct Image {
26 width: usize,
27 height: usize,
28 pixels: Vec<Color>,
29}
30
31pub struct RC(pub usize, pub usize);
34
35pub struct XY(pub usize, pub usize);
38
39impl Image {
40 pub fn width(&self) -> usize {
42 self.width
43 }
44
45 pub fn height(&self) -> usize {
47 self.height
48 }
49
50 pub fn new(width: usize, height: usize) -> Image {
52 Image {
53 width,
54 height,
55 pixels: vec![Color { r: 0, g: 0, b: 0 }; (width * height) as usize],
56 }
57 }
58
59 pub fn fill(&mut self, color: Color) {
61 for pix in &mut self.pixels {
62 *pix = color;
63 }
64 }
65}
66
67impl Index<RC> for Image {
68 type Output = Color;
69 fn index(&self, RC(row, col): RC) -> &Self::Output {
70 &self.pixels[(row * self.width + col) as usize]
71 }
72}
73
74impl IndexMut<RC> for Image {
75 fn index_mut(&mut self, RC(row, col): RC) -> &mut Self::Output {
76 &mut self.pixels[(row * self.width + col) as usize]
77 }
78}
79
80impl Index<XY> for Image {
81 type Output = Color;
82 fn index(&self, XY(x, y): XY) -> &Self::Output {
83 &self.pixels[(y * self.width + x) as usize]
84 }
85}
86
87impl IndexMut<XY> for Image {
88 fn index_mut(&mut self, XY(x, y): XY) -> &mut Self::Output {
89 &mut self.pixels[(y * self.width + x) as usize]
90 }
91}
92
93impl Deref for Image {
94 type Target = [Color];
95 fn deref(&self) -> &Self::Target {
96 &self.pixels
97 }
98}
99
100impl DerefMut for Image {
101 fn deref_mut(&mut self) -> &mut Self::Target {
102 &mut self.pixels
103 }
104}
105
106impl<'a> Texture2dDataSource<'a> for &'a Image {
107 type Data = u8;
108 fn into_raw(self) -> RawImage2d<'a, Self::Data> {
109 RawImage2d {
110 data: Cow::Borrowed(unsafe {
111 std::slice::from_raw_parts(self.pixels.as_ptr() as *const u8, self.pixels.len() * 3)
112 }),
113 width: self.width as u32,
114 height: self.height as u32,
115 format: ClientFormat::U8U8U8,
116 }
117 }
118}