use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Color {
pub r: f64,
pub g: f64,
pub b: f64,
}
impl Color {
pub const RED: Self = Self {
r: 1.0,
g: 0.0,
b: 0.0,
};
pub const GREEN: Self = Self {
r: 0.0,
g: 1.0,
b: 0.0,
};
pub const BLUE: Self = Self {
r: 0.0,
g: 0.0,
b: 1.0,
};
pub const BLACK: Self = Self {
r: 0.0,
g: 0.0,
b: 0.0,
};
pub const WHITE: Self = Self {
r: 1.0,
g: 1.0,
b: 1.0,
};
pub const fn rgb(r: f64, g: f64, b: f64) -> Self {
Self { r, g, b }
}
}
impl From<(f64, f64, f64)> for Color {
fn from((r, g, b): (f64, f64, f64)) -> Self {
Self { r, g, b }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LineCap {
Butt,
Round,
Square,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LineJoin {
Miter,
Round,
Bevel,
}
#[derive(Debug, Clone)]
pub struct Canvas {
buffer: Vec<u8>,
}
impl Canvas {
pub fn new() -> Self {
Self { buffer: Vec::new() }
}
pub fn move_to(mut self, x: f64, y: f64) -> Self {
self.buffer.extend(format!("{} {} m\n", x, y).as_bytes());
self
}
pub fn line_to(mut self, x: f64, y: f64) -> Self {
self.buffer.extend(format!("{} {} l\n", x, y).as_bytes());
self
}
pub fn curve_to(mut self, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) -> Self {
self.buffer
.extend(format!("{} {} {} {} {} {} c\n", x1, y1, x2, y2, x3, y3).as_bytes());
self
}
pub fn rect(mut self, x: f64, y: f64, width: f64, height: f64) -> Self {
self.buffer
.extend(format!("{} {} {} {} re\n", x, y, width, height).as_bytes());
self
}
pub fn stroke_color(mut self, color: Color) -> Self {
self.buffer
.extend(format!("{} {} {} RG\n", color.r, color.g, color.b).as_bytes());
self
}
pub fn fill_color(mut self, color: Color) -> Self {
self.buffer
.extend(format!("{} {} {} rg\n", color.r, color.g, color.b).as_bytes());
self
}
pub fn line_width(mut self, width: f64) -> Self {
self.buffer.extend(format!("{} w\n", width).as_bytes());
self
}
pub fn close_path(mut self) -> Self {
self.buffer.extend(b"h\n");
self
}
pub fn fill(mut self) -> Self {
self.buffer.extend(b"f\n");
self
}
pub fn stroke(mut self) -> Self {
self.buffer.extend(b"S\n");
self
}
pub fn fill_stroke(mut self) -> Self {
self.buffer.extend(b"B\n");
self
}
pub fn finish(self) -> Vec<u8> {
self.buffer
}
}
impl Default for Canvas {
fn default() -> Self {
Self::new()
}
}
impl AsRef<[u8]> for Canvas {
fn as_ref(&self) -> &[u8] {
&self.buffer
}
}
impl fmt::Write for Canvas {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.buffer.extend(s.as_bytes());
Ok(())
}
}