From 92a02c34628343153b33602eae00cef46e28d191 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Thu, 22 Dec 2022 12:19:59 +0100 Subject: WIP --- cairo-renderer/src/drawing/cairo/mod.rs | 35 ++++++++++ cairo-renderer/src/drawing/mod.rs | 8 +++ cairo-renderer/src/lib.rs | 111 ++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 cairo-renderer/src/drawing/cairo/mod.rs create mode 100644 cairo-renderer/src/drawing/mod.rs create mode 100644 cairo-renderer/src/lib.rs (limited to 'cairo-renderer/src') diff --git a/cairo-renderer/src/drawing/cairo/mod.rs b/cairo-renderer/src/drawing/cairo/mod.rs new file mode 100644 index 0000000..09baa9c --- /dev/null +++ b/cairo-renderer/src/drawing/cairo/mod.rs @@ -0,0 +1,35 @@ +use super::Engine; +use crate::core::{shapes::Shape as CoreShape, types::DefinitelyBounded}; + +use cairo::Context; + +pub struct CairoEngine { + ctx: Context, +} + +impl Engine for CairoEngine { + fn new() -> Self { + let surface = cairo::SvgSurface::for_stream(200., 100., std::io::stdout()).unwrap(); + let ctx = cairo::Context::new(&surface); + + CairoEngine { ctx } + } + + fn draw(&mut self, shape: &DefinitelyBounded) { + let bounds = &shape.bounds; + + self.ctx.move_to(bounds.left, bounds.top); + + match &shape.shape { + CoreShape::Rectangle(_rectangle) => { + self.ctx + .rectangle(bounds.left, bounds.top, bounds.width, bounds.height); + self.ctx.stroke(); + } + CoreShape::Text(text) => { + // TODO: properly shape it, with font, etc. + self.ctx.show_text(&text.content); + } + } + } +} diff --git a/cairo-renderer/src/drawing/mod.rs b/cairo-renderer/src/drawing/mod.rs new file mode 100644 index 0000000..1c32fb1 --- /dev/null +++ b/cairo-renderer/src/drawing/mod.rs @@ -0,0 +1,8 @@ +pub mod cairo; + +use crate::core::{shapes::Shape as CoreShape, types::DefinitelyBounded}; + +pub trait Engine { + fn new() -> Self; + fn draw(&mut self, shape: &DefinitelyBounded); +} diff --git a/cairo-renderer/src/lib.rs b/cairo-renderer/src/lib.rs new file mode 100644 index 0000000..26ca089 --- /dev/null +++ b/cairo-renderer/src/lib.rs @@ -0,0 +1,111 @@ +use diaphragm_core::{ + styles::{Pattern, DefinedDashStyle}, + text::{DefinedFontDescription, FontDescription}, + Renderer, +}; + +pub struct CairoRenderer { + ctx: cairo::Context, +} + +impl CairoRenderer { + pub fn new() -> Self { + // TODO: properly + let surface = cairo::SvgSurface::for_stream(1920., 1080., std::io::stdout()).unwrap(); + let ctx = cairo::Context::new(&surface); + + Self { ctx } + } +} + +impl Renderer for CairoRenderer { + fn move_to(&mut self, x: f64, y: f64) { + self.ctx.move_to(x, y) + } + + fn stroke(&mut self) { + self.ctx.stroke(); + } + + fn fill(&mut self) { + self.ctx.fill(); + } + + fn fill_preserve(&mut self) { + self.ctx.fill_preserve(); + } + + fn set_pattern(&mut self, pattern: &Pattern) { + match pattern { + Pattern::Solid(color) => { + let (red, green, blue, alpha) = color.rgba(); + self.ctx.set_source_rgba(red, green, blue, alpha) + } + Pattern::None => {} + _ => panic!("Unhandled pattern"), + } + } + + fn set_dash(&mut self, dash: &DefinedDashStyle) { + self.ctx.set_dash(&dash.dashes(), dash.offset()); + } + + fn clear_dash(&mut self) { + self.ctx.set_dash(&[], 0.); + } + + fn set_line_width(&mut self, width: f64) { + self.ctx.set_line_width(width); + } + + fn line_to(&mut self, x: f64, y: f64) { + self.ctx.line_to(x, y) + } + + fn rectangle(&mut self, x: f64, y: f64, width: f64, height: f64) { + self.ctx.rectangle(x, y, width, height); + } + + fn text_extents(&self, text: &str, font: &FontDescription) -> (f64, f64) { + let layout = pangocairo::create_layout(&self.ctx).expect("Couldn't create layout"); + let font_desc = pango::FontDescription::from_string(&font.family); + layout.set_font_description(Some(&font_desc)); + layout.set_markup(text); + + //let (extents, _) = layout.get_pixel_extents(); + //(extents.width as f64, extents.height as f64) + + // TODO: get height from the baseline + let mut layout_iter = layout.get_iter().unwrap(); + let _height = loop { + if layout_iter.at_last_line() { + break layout_iter.get_baseline(); + } + + layout_iter.next_line(); + }; + + // TODO: Probably should use the logical extents, but it has weird width + let (_, extents) = layout.get_pixel_extents(); + //let (extents, _) = layout.get_pixel_extents(); + (extents.width as f64, extents.height as f64) + + //let (width, height) = layout.get_pixel_size(); + //(width as f64, height as f64) + } + + fn show_text(&mut self, text: &str, font: &DefinedFontDescription) { + let layout = pangocairo::create_layout(&self.ctx).expect("Couldn't create layout"); + let mut font_desc = pango::FontDescription::from_string(&font.family); + + // TODO: I have no fucking idea why + font_desc.set_size((font.size * 600.) as _); + //font_desc.set_size((font.size * 700.) as _); + //font_desc.set_absolute_size(font.size * 800.); + layout.set_font_description(Some(&font_desc)); + layout.set_markup(text); + + //self.ctx.set_font_size(dbg!(font.size)); + pangocairo::show_layout(&self.ctx, &layout); + } +} -- cgit v1.2.3