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}