simple_canvas/
lib.rs

1// Copyright (c) 2024 Remi A. Godin
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! A simple canvas struct that act as a 2 dimensional array.
22
23/// A struct containing a single vector abstracted to a 2 dimensional array.
24///
25/// # Arguments
26///
27/// `data`          The actual data, stored as a `Vec<T>`
28/// `width`         The width of the canvas
29/// `height`        The height of the canvas
30///
31/// # Note
32/// The canvas is repesented by a single vector of type `<T>`. The canvas can be interpreted in any
33/// direction, but it was intended to start at the top left corner, and goes from left to right, up
34/// to down. 
35///
36/// The functions provided allow access to each elemeny by row and column, as well as access to
37/// iterators over the whole canvas. If you prefer the raw data, then you can access the `data`
38/// field directly.
39#[derive(Clone)]
40pub struct Canvas<T> {
41    pub data: Vec<T>,
42    pub width: usize,
43    pub height: usize,
44}
45
46impl<T: Clone> Canvas<T> {
47    /// Creates a new canvas of the specified size. The background data is the default data that
48    /// will fill the canvas at initialization.
49    ///
50    /// Background data type must implement the `Clone` trait.
51    pub fn new(width: usize, height: usize, background_data: T) -> Canvas<T> {
52        let mut canvas: Canvas<T> = Canvas {
53            width,
54            height,
55            data: Vec::with_capacity(width * height)
56        };
57        for _i in 0..(width * height) {
58            canvas.data.push(background_data.clone());
59        }
60        canvas
61    }
62
63
64    /// Return the pixel value at the specified row and column.
65    pub fn get(&self, row: usize, col: usize) -> Option<&T> {
66        self.data.get(row * self.width + col)
67    }
68
69    /// Return a mutable reference to the pixel at the specified row and column.
70    pub fn get_mut(&mut self, row: usize, col: usize) -> Option<&mut T> {
71        self.data.get_mut(row * self.width + col)
72    }
73
74    /// Returns an iterator over all the pixels in the canvas, starting from top left, scanning
75    /// left to right, top to bottom.
76    pub fn iter(&self) -> core::slice::Iter<T> {
77        self.data.iter()
78    }
79
80    /// Returns a mutable iterator over all the pixels in the canvas, starting from top left,
81    /// scanning left ot right, top to bottom.
82    pub fn iter_mut(&mut self) -> core::slice::IterMut<T> {
83        self.data.iter_mut()
84    }
85}