159 lines
4.3 KiB
Rust
159 lines
4.3 KiB
Rust
use crate::context::palette::Palette;
|
|
use cairo::Context;
|
|
use cairo::{ImageSurface, Surface, SvgSurface};
|
|
use std::fs::File;
|
|
|
|
/// container that holds everything to render surface
|
|
pub(crate) trait RenderContainer {
|
|
/// render command
|
|
fn render(&self);
|
|
/// get render context just in case
|
|
fn context(&self) -> &Context;
|
|
/// surface to create cairo context
|
|
fn surface(&self) -> &Surface;
|
|
|
|
/// initialize RenderContainer
|
|
fn init(&self, width: f64, height: f64, line_size: f64);
|
|
|
|
/// plot a path
|
|
fn plot_path(&self, path: &Vec<[f64; 2]>, fill: bool);
|
|
|
|
fn put_path_on_stack(&self, path: &Vec<[f64; 2]>) {
|
|
let context = self.context();
|
|
let mut init = true;
|
|
for &[x, y] in path.iter() {
|
|
if init {
|
|
context.move_to(x, y);
|
|
init = false;
|
|
} else {
|
|
context.line_to(x, y);
|
|
}
|
|
}
|
|
context.close_path();
|
|
}
|
|
}
|
|
|
|
/// container to render svg images
|
|
pub struct SvgRenderContainer {
|
|
surface: SvgSurface,
|
|
context: Context,
|
|
}
|
|
|
|
impl SvgRenderContainer {
|
|
pub fn new(surface: SvgSurface, _: Palette) -> Self {
|
|
let context = Context::new(&surface);
|
|
SvgRenderContainer { surface, context }
|
|
}
|
|
}
|
|
|
|
impl RenderContainer for SvgRenderContainer {
|
|
fn render(&self) {
|
|
// nothing to do
|
|
}
|
|
|
|
fn context(&self) -> &Context {
|
|
&self.context
|
|
}
|
|
|
|
fn surface(&self) -> &Surface {
|
|
&self.surface as &Surface
|
|
}
|
|
|
|
fn init(&self, _width: f64, _height: f64, line_size: f64) {
|
|
self.context.set_line_width(line_size);
|
|
}
|
|
|
|
/// plot a path
|
|
fn plot_path(&self, path: &Vec<[f64; 2]>, fill: bool) {
|
|
self.put_path_on_stack(path);
|
|
let context = self.context();
|
|
if fill {
|
|
context.fill()
|
|
} else {
|
|
context.stroke();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// container to render png images
|
|
pub struct PngRenderContainer {
|
|
/// output path of the png
|
|
path: String,
|
|
surface: ImageSurface,
|
|
context: Context,
|
|
palette: Palette,
|
|
}
|
|
|
|
impl PngRenderContainer {
|
|
pub fn new(path: String, surface: ImageSurface, palette: Palette) -> Self {
|
|
let context = Context::new(&surface);
|
|
PngRenderContainer {
|
|
path,
|
|
surface,
|
|
context,
|
|
palette,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl RenderContainer for PngRenderContainer {
|
|
fn render(&self) {
|
|
let mut file = File::create(&self.path).expect("Couldn't create 'file.png'");
|
|
match self.surface.write_to_png(&mut file) {
|
|
Ok(_) => println!("{}, created", self.path),
|
|
Err(_) => println!("Error create file.png"),
|
|
}
|
|
}
|
|
|
|
fn context(&self) -> &Context {
|
|
&self.context
|
|
}
|
|
|
|
fn surface(&self) -> &Surface {
|
|
&self.surface as &Surface
|
|
}
|
|
|
|
fn init(&self, width: f64, height: f64, line_size: f64) {
|
|
// set background color
|
|
self.context.set_source_rgb(
|
|
self.palette.background_color.red as f64,
|
|
self.palette.background_color.green as f64,
|
|
self.palette.background_color.blue as f64,
|
|
);
|
|
self.context.rectangle(0., 0., width, height);
|
|
self.context.fill();
|
|
|
|
// configure line
|
|
self.context.set_source_rgb(
|
|
self.palette.fill_color.red as f64,
|
|
self.palette.fill_color.green as f64,
|
|
self.palette.fill_color.blue as f64,
|
|
);
|
|
self.context.set_line_width(line_size);
|
|
}
|
|
|
|
/// plot a path
|
|
fn plot_path(&self, path: &Vec<[f64; 2]>, fill: bool) {
|
|
if fill {
|
|
self.put_path_on_stack(path);
|
|
self.context.fill()
|
|
} else {
|
|
// fill with background
|
|
self.context.set_source_rgb(
|
|
self.palette.background_color.red as f64,
|
|
self.palette.background_color.green as f64,
|
|
self.palette.background_color.blue as f64,
|
|
);
|
|
self.put_path_on_stack(path);
|
|
self.context.fill();
|
|
// set drawing color back to normal
|
|
self.context.set_source_rgb(
|
|
self.palette.fill_color.red as f64,
|
|
self.palette.fill_color.green as f64,
|
|
self.palette.fill_color.blue as f64,
|
|
);
|
|
self.put_path_on_stack(path);
|
|
self.context.stroke();
|
|
}
|
|
}
|
|
}
|