1#![warn(missing_docs)]
3extern crate rusttype;
4extern crate walkdir;
5extern crate xdg;
6extern crate xml;
7
8#[macro_use]
9extern crate bitflags;
10
11pub mod line;
13pub mod shapes;
15pub mod text;
17
18pub trait Drawable {
20 fn draw(&self, canvas: &mut Canvas);
22}
23
24#[derive(Debug, PartialEq)]
26pub enum Endian {
27 Little,
29 Big,
31}
32
33impl Endian {
34 pub fn native() -> Endian {
36 if cfg!(target_endian = "little") {
37 Endian::Little
38 } else {
39 Endian::Big
40 }
41 }
42}
43
44pub struct Canvas<'a> {
47 pub buffer: &'a mut [u8],
49 pub width: usize,
51 pub height: usize,
53 pub stride: usize,
55 pub pixel_size: usize,
57 pub endianness: Endian,
59}
60
61impl<'a> Canvas<'a> {
62 pub fn new(
64 buffer: &'a mut [u8],
65 width: usize,
66 height: usize,
67 stride: usize,
68 endianness: Endian,
69 ) -> Canvas<'a> {
70 assert!(
71 stride % width == 0,
72 "Incorrect Dimensions - Stride is not a multiple of width"
73 );
74 assert!(buffer.len() == stride * height);
75 let pixel_size = stride / width;
76 Canvas {
77 buffer,
78 width,
79 height,
80 stride,
81 pixel_size,
82 endianness,
83 }
84 }
85
86 pub fn draw<D: Drawable>(&mut self, drawable: &D) {
88 drawable.draw(self);
89 }
90
91 pub fn draw_point(&mut self, x: usize, y: usize, color: [u8; 4]) {
93 let base = self.stride * y + self.pixel_size * x;
94 if self.endianness == Endian::Little {
95 if color[0] == 255 {
96 self.buffer[base + 3] = color[0];
97 self.buffer[base + 2] = color[1];
98 self.buffer[base + 1] = color[2];
99 self.buffer[base] = color[3];
100 } else {
101 for c in 0..3 {
102 let alpha = f32::from(color[0]) / 255.0;
103 let color_diff =
104 (color[3 - c] as isize - self.buffer[base + c] as isize) as f32 * alpha;
105 let new_color = (f32::from(self.buffer[base + c]) + color_diff) as u8;
106 self.buffer[base + c] = new_color as u8;
107 }
108 self.buffer[base + 3] = 255 as u8;
109 }
110 } else if color[0] == 255 {
111 self.buffer[base] = color[0];
112 self.buffer[base + 1] = color[1];
113 self.buffer[base + 2] = color[2];
114 self.buffer[base + 3] = color[3];
115 } else {
116 for c in 1..4 {
117 let alpha = f32::from(color[0]) / 255.0;
118 let color_diff =
119 (color[c] as isize - self.buffer[base + c] as isize) as f32 * alpha;
120 let new_color = (f32::from(self.buffer[base + c]) + color_diff) as u8;
121 self.buffer[base + c] = new_color as u8;
122 }
123 self.buffer[base] = 255 as u8;
124 }
125 }
126
127 pub fn clear(&mut self) {
129 for i in 0..self.width * self.height * 4 {
130 self.buffer[i] = 0x00;
131 }
132 }
133}