From 9c15b76c5a6355902b2a105a7c6ee93f6b5016dc Mon Sep 17 00:00:00 2001 From: Minijackson Date: Thu, 29 Dec 2022 01:40:08 +0100 Subject: WIP v2: text works, primitives works in Lua --- core/src/core_shapes.rs | 73 ++++++++++++++++++----- core/src/lib.rs | 8 +-- core/src/rendering.rs | 53 ++++++++++------- core/src/runtime.rs | 154 ++++++++++++++++++++++++++++-------------------- core/src/solving.rs | 55 ++++++++++++----- core/src/types.rs | 110 +++++++++++++++++----------------- 6 files changed, 277 insertions(+), 176 deletions(-) (limited to 'core/src') diff --git a/core/src/core_shapes.rs b/core/src/core_shapes.rs index 805d82e..d8017ab 100644 --- a/core/src/core_shapes.rs +++ b/core/src/core_shapes.rs @@ -1,8 +1,44 @@ -use super::complex_shapes::{ComplexShape, DrawResult}; -use super::rendering::{Render, Renderer}; -use super::solving::{Constrainable, SolverContext, SolverModel}; -use super::types::*; +pub struct CoreDrawable { + pub(crate) shape: CoreShape, + pub(crate) context: CoreShapeContext, +} + +impl CoreDrawable { + pub fn new(shape: CoreShape, context: CoreShapeContext) -> Self { + Self { shape, context } + } +} + +pub enum CoreShape { + Rectangle(Rectangle), + Text(Text), + // StraightPath(StraightPath), +} +impl From for CoreShape { + fn from(rectangle: Rectangle) -> Self { + CoreShape::Rectangle(rectangle) + } +} + +impl From for CoreShape { + fn from(text: Text) -> Self { + CoreShape::Text(text) + } +} + +pub struct DefinedCoreDrawable { + pub(crate) shape: DefinedCoreShape, + pub(crate) context: DefinedCoreShapeContext, +} + +pub enum DefinedCoreShape { + Rectangle(Rectangle), + Text(DefinedText), + // StraightPath(StraightPath), +} + +/* pub trait CoreShape { fn constrain( &self, @@ -23,19 +59,25 @@ impl ComplexShape for T { panic!("Tried to decompose core shape") } } +*/ // TODO: add default #[derive(Copy, Clone, Debug, Default)] pub struct Rectangle {} +/* impl CoreShape for Rectangle { fn to_render(&self, _model: &dyn SolverModel) -> Option> { Some(Box::new(*self)) } } +*/ + +use crate::types::{CoreShapeContext, DefinedCoreShapeContext}; pub use super::text::{DefinedText, Text}; +/* impl CoreShape for Text { fn constrain( &self, @@ -62,18 +104,20 @@ impl CoreShape for Text { .map(|path| -> Box { Box::new(path) }) } } +*/ -#[derive(Clone, Debug, Default)] -pub struct StraightPath { - pub(crate) points: Vec, -} - -impl StraightPath { - pub fn new(points: Vec) -> Self { - Self { points } - } -} +// #[derive(Clone, Debug, Default)] +// pub struct StraightPath { +// pub(crate) points: Vec, +// } +// +// impl StraightPath { +// pub fn new(points: Vec) -> Self { +// Self { points } +// } +// } +/* pub struct DefinedStraightPath { pub(crate) points: Vec, } @@ -84,3 +128,4 @@ impl CoreShape for StraightPath { .map(|path| -> Box { Box::new(path) }) } } +*/ diff --git a/core/src/lib.rs b/core/src/lib.rs index 57e45df..f949cd9 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -2,7 +2,7 @@ #![deny(unsafe_code)] pub mod colors; -mod complex_shapes; +// mod complex_shapes; pub mod core_shapes; mod rendering; mod runtime; @@ -11,9 +11,9 @@ pub mod styles; pub mod text; pub mod types; -pub use complex_shapes::{ - ComplexShape, DrawResult, Drawable, DrawableBuilder, DynClone, DynDrawable, -}; +// pub use complex_shapes::{ +// ComplexShape, DrawResult, Drawable, DrawableBuilder, DynClone, DynDrawable, +// }; pub use rendering::Renderer; pub use runtime::Runtime; pub use solving::{SolverContext, SolverModel}; diff --git a/core/src/rendering.rs b/core/src/rendering.rs index f7a0189..9c9f9e4 100644 --- a/core/src/rendering.rs +++ b/core/src/rendering.rs @@ -1,7 +1,7 @@ use super::core_shapes::*; use super::styles::{DefinedDashStyle, DefinedStrokeStyle, FillStyle, Pattern}; use super::text::{DefinedFontDescription, FontDescription}; -use super::types::DefinedShapeContext; +use super::types::DefinedCoreShapeContext; pub trait Renderer { fn move_to(&mut self, x: f64, y: f64); @@ -20,7 +20,16 @@ pub trait Renderer { } pub trait Render { - fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer); + fn render(&self, context: DefinedCoreShapeContext, renderer: &mut dyn Renderer); +} + +impl Render for DefinedCoreShape { + fn render(&self, context: DefinedCoreShapeContext, renderer: &mut dyn Renderer) { + match self { + Self::Rectangle(r) => r.render(context, renderer), + Self::Text(t) => t.render(context, renderer), + } + } } fn draw(fill: &FillStyle, stroke: &DefinedStrokeStyle, renderer: &mut dyn Renderer) { @@ -47,7 +56,7 @@ fn draw(fill: &FillStyle, stroke: &DefinedStrokeStyle, renderer: &mut dyn Render } impl Render for Rectangle { - fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) { + fn render(&self, context: DefinedCoreShapeContext, renderer: &mut dyn Renderer) { let bounds = &context.bounds; renderer.rectangle(bounds.left, bounds.top, bounds.width, bounds.height); draw(&context.fill, &context.stroke, renderer); @@ -55,7 +64,7 @@ impl Render for Rectangle { } impl Render for DefinedText { - fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) { + fn render(&self, context: DefinedCoreShapeContext, renderer: &mut dyn Renderer) { // TODO: select font, style, text shaping (renderer specific), etc. let bounds = &context.bounds; //renderer.move_to(bounds.left, bounds.top + self.font.size); @@ -66,21 +75,21 @@ impl Render for DefinedText { } } -impl Render for DefinedStraightPath { - fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) { - let mut iter = self.points.iter(); - - let first_point = match iter.next() { - Some(point) => point, - None => return, - }; - - renderer.move_to(first_point.x, first_point.y); - - for point in iter { - renderer.line_to(point.x, point.y); - } - - draw(&context.fill, &context.stroke, renderer); - } -} +// impl Render for DefinedStraightPath { +// fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) { +// let mut iter = self.points.iter(); +// +// let first_point = match iter.next() { +// Some(point) => point, +// None => return, +// }; +// +// renderer.move_to(first_point.x, first_point.y); +// +// for point in iter { +// renderer.line_to(point.x, point.y); +// } +// +// draw(&context.fill, &context.stroke, renderer); +// } +// } diff --git a/core/src/runtime.rs b/core/src/runtime.rs index bfb31fa..d70e4d0 100644 --- a/core/src/runtime.rs +++ b/core/src/runtime.rs @@ -1,13 +1,17 @@ -use super::complex_shapes::{ComplexShape, Drawable, DynDrawable}; +use crate::core_shapes::CoreDrawable; +use crate::rendering::Render; + +// use super::complex_shapes::{ComplexShape, Drawable}; use super::rendering::Renderer; use super::solving::{Constrainable, SolverContext}; -const RECURSION_LIMIT: u64 = 10_000; +// const RECURSION_LIMIT: u64 = 10_000; pub struct Runtime<'a> { solver_ctx: Box, renderer: Box, - drawables: Vec, + // drawables: Vec, + drawables: Vec, } impl<'a> Runtime<'a> { @@ -15,81 +19,101 @@ impl<'a> Runtime<'a> { Self { solver_ctx, renderer, + // drawables: Vec::new(), drawables: Vec::new(), } } - pub fn add_drawable(&mut self, drawable: Drawable) { - self.drawables.push(drawable.into()) + // pub fn add_drawable(&mut self, drawable: Drawable) { + // self.drawables.push(drawable.into()) + // } + + pub fn add_drawable(&mut self, drawable: CoreDrawable) { + self.drawables.push(drawable) } pub fn solver_ctx(&mut self) -> &mut (dyn SolverContext + 'a) { &mut *self.solver_ctx } - // TODO: preserve ordering of shapes - pub fn render(mut self) { - let mut drawables = self.drawables; - let mut waited_on_variables = Vec::new(); - let mut core_shapes = Vec::new(); - - /* - for drawable in &self.shapes { - let bounds = &drawable.bounds; - let shape = &drawable.shape; - - if let Some(core_shape) = shape.to_render() { - drawables.push((*drawable).clone()); - continue; - } - - let mut result = shape.draw(bounds); - drawables.append(&mut result.subshapes); - waited_on_variables.append(&mut result.waiting_on); - } - */ - - let mut recursion_count = 0; - - while !drawables.is_empty() { - recursion_count += 1; - - if recursion_count > RECURSION_LIMIT { - panic!("Recursion limit reached"); - } - - let mut tmp_drawables = Vec::new(); - - for drawable in drawables.drain(..) { - let shape_ctx = &drawable.context; - let shape = &drawable.shape; - - if let Some(core_shape) = shape.as_core_shape() { - core_shape.constrain(shape_ctx, &mut *self.solver_ctx, &*self.renderer); - core_shapes.push((shape.dyn_clone(), shape_ctx.clone())); // Better to Arc? Cow? - continue; - } - - let mut result = shape.draw(shape_ctx, &mut *self.solver_ctx); - tmp_drawables.append(&mut result.subshapes); - waited_on_variables.append(&mut result.waiting_on); - } - - drawables = tmp_drawables; - } + pub fn renderer(&mut self) -> &mut dyn Renderer { + &mut *self.renderer + } + pub fn render(mut self) { let model = self.solver_ctx.solve(); - // Delay rendering core shapes until later to have all the constraints - for (core_shape, shape_ctx) in core_shapes { - let core_shape = core_shape.as_core_shape().unwrap(); - - match (core_shape.to_render(&*model), shape_ctx.fixate(&*model)) { - (Some(defined_shape), Some(shape_ctx)) => { - defined_shape.render(shape_ctx, &mut *self.renderer) - } - _ => panic!("Failed to fixate core shape"), - } + for drawable in &self.drawables { + let defined_drawable = drawable + .fixate(&*model) + .expect("Could not fixate core shape"); + defined_drawable.shape.render(defined_drawable.context, &mut *self.renderer); } } + + // TODO: preserve ordering of shapes + // pub fn render(mut self) { + // let mut drawables = self.drawables; + // let mut waited_on_variables = Vec::new(); + // let mut core_shapes = Vec::new(); + // + // /* + // for drawable in &self.shapes { + // let bounds = &drawable.bounds; + // let shape = &drawable.shape; + // + // if let Some(core_shape) = shape.to_render() { + // drawables.push((*drawable).clone()); + // continue; + // } + // + // let mut result = shape.draw(bounds); + // drawables.append(&mut result.subshapes); + // waited_on_variables.append(&mut result.waiting_on); + // } + // */ + // + // let mut recursion_count = 0; + // + // while !drawables.is_empty() { + // recursion_count += 1; + // + // if recursion_count > RECURSION_LIMIT { + // panic!("Recursion limit reached"); + // } + // + // let mut tmp_drawables = Vec::new(); + // + // for drawable in drawables.drain(..) { + // let shape_ctx = &drawable.context; + // let shape = &drawable.shape; + // + // if let Some(core_shape) = shape.as_core_shape() { + // core_shape.constrain(shape_ctx, &mut *self.solver_ctx, &*self.renderer); + // core_shapes.push((shape.dyn_clone(), shape_ctx.clone())); // Better to Arc? Cow? + // continue; + // } + // + // let mut result = shape.draw(shape_ctx, &mut *self.solver_ctx); + // tmp_drawables.append(&mut result.subshapes); + // waited_on_variables.append(&mut result.waiting_on); + // } + // + // drawables = tmp_drawables; + // } + // + // let model = self.solver_ctx.solve(); + // + // // Delay rendering core shapes until later to have all the constraints + // for (core_shape, shape_ctx) in core_shapes { + // let core_shape = core_shape.as_core_shape().unwrap(); + // + // match (core_shape.to_render(&*model), shape_ctx.fixate(&*model)) { + // (Some(defined_shape), Some(shape_ctx)) => { + // defined_shape.render(shape_ctx, &mut *self.renderer) + // } + // _ => panic!("Failed to fixate core shape"), + // } + // } + // } } diff --git a/core/src/solving.rs b/core/src/solving.rs index 4760611..261b4d4 100644 --- a/core/src/solving.rs +++ b/core/src/solving.rs @@ -1,4 +1,5 @@ -use super::core_shapes::*; +use crate::core_shapes::{CoreDrawable, CoreShape, DefinedCoreDrawable, DefinedCoreShape}; + use super::styles::*; use super::text::*; use super::types::{Bool, Float}; @@ -147,6 +148,17 @@ pub trait Constrainable { fn fixate(&self, model: &dyn SolverModel) -> Option; } +impl Constrainable for CoreShape { + type Fixated = DefinedCoreShape; + + fn fixate(&self, model: &dyn SolverModel) -> Option { + match self { + CoreShape::Rectangle(r) => Some(DefinedCoreShape::Rectangle(*r)), + CoreShape::Text(t) => t.fixate(model).map(DefinedCoreShape::Text), + } + } +} + impl Constrainable for Float { type Fixated = f64; @@ -218,11 +230,22 @@ impl Constrainable for DashStyle { } } -impl Constrainable for ShapeContext { - type Fixated = DefinedShapeContext; +impl Constrainable for CoreDrawable { + type Fixated = DefinedCoreDrawable; + + fn fixate(&self, model: &dyn SolverModel) -> Option { + Some(DefinedCoreDrawable { + shape: self.shape.fixate(model)?, + context: self.context.fixate(model)?, + }) + } +} + +impl Constrainable for CoreShapeContext { + type Fixated = DefinedCoreShapeContext; fn fixate(&self, model: &dyn SolverModel) -> Option { - Some(DefinedShapeContext { + Some(DefinedCoreShapeContext { bounds: self.bounds.fixate(model)?, fill: self.fill.clone(), stroke: self.stroke.fixate(model)?, @@ -265,15 +288,15 @@ impl Constrainable for Text { } } -impl Constrainable for StraightPath { - type Fixated = DefinedStraightPath; - - fn fixate(&self, model: &dyn SolverModel) -> Option { - let points: Option<_> = self - .points - .iter() - .map(|point| point.fixate(model)) - .collect(); - Some(DefinedStraightPath { points: points? }) - } -} +// impl Constrainable for StraightPath { +// type Fixated = DefinedStraightPath; +// +// fn fixate(&self, model: &dyn SolverModel) -> Option { +// let points: Option<_> = self +// .points +// .iter() +// .map(|point| point.fixate(model)) +// .collect(); +// Some(DefinedStraightPath { points: points? }) +// } +// } diff --git a/core/src/types.rs b/core/src/types.rs index 1b7623a..96e059a 100644 --- a/core/src/types.rs +++ b/core/src/types.rs @@ -99,19 +99,19 @@ impl Bounds { BoundsBuilder::default() } - pub fn top(&self, _ctx: &mut dyn SolverContext) -> Float { + pub fn top(&self, _solver: &mut dyn SolverContext) -> Float { self.top } - pub fn left(&self, _ctx: &mut dyn SolverContext) -> Float { + pub fn left(&self, _solver: &mut dyn SolverContext) -> Float { self.left } - pub fn width(&self, _ctx: &mut dyn SolverContext) -> Float { + pub fn width(&self, _solver: &mut dyn SolverContext) -> Float { self.width } - pub fn height(&self, _ctx: &mut dyn SolverContext) -> Float { + pub fn height(&self, _solver: &mut dyn SolverContext) -> Float { self.height } @@ -133,7 +133,7 @@ impl Bounds { solver.float_add(&[self.left, half_width]) } - pub fn top_left(&self, _ctx: &mut dyn SolverContext) -> Point2D { + pub fn top_left(&self, _solver: &mut dyn SolverContext) -> Point2D { Point2D::new(self.left, self.top) } @@ -206,11 +206,11 @@ impl BoundsBuilder { } } -#[derive(Clone, Debug)] -pub struct Bounded { - pub bounds: Bounds, - pub shape: Shape, -} +// #[derive(Clone, Debug)] +// pub struct Bounded { +// pub bounds: Bounds, +// pub shape: Shape, +// } #[derive(Clone, PartialEq, PartialOrd, Debug)] pub struct DefinedBounds { @@ -220,20 +220,20 @@ pub struct DefinedBounds { pub height: f64, } -#[derive(Clone, PartialEq, PartialOrd, Debug)] -pub struct DefinitelyBounded { - pub bounds: DefinedBounds, - pub shape: Shape, -} +// #[derive(Clone, PartialEq, PartialOrd, Debug)] +// pub struct DefinitelyBounded { +// pub bounds: DefinedBounds, +// pub shape: Shape, +// } #[derive(Clone, Debug)] -pub struct ShapeContext { +pub struct CoreShapeContext { pub(crate) bounds: Bounds, pub(crate) fill: FillStyle, pub(crate) stroke: StrokeStyle, } -impl ShapeContext { +impl CoreShapeContext { pub fn new(solver: &mut dyn SolverContext) -> Self { Self { bounds: Bounds { @@ -247,9 +247,9 @@ impl ShapeContext { } } - pub(crate) fn builder() -> ShapeContextBuilder { - ShapeContextBuilder::default() - } + // pub(crate) fn builder() -> ShapeContextBuilder { + // ShapeContextBuilder::default() + // } pub fn bounds(&self) -> &Bounds { &self.bounds @@ -276,41 +276,41 @@ impl ShapeContext { } } -#[derive(Clone, Default)] -pub(crate) struct ShapeContextBuilder { - bounds: Option, - fill: Option, - stroke: Option, -} - -impl ShapeContextBuilder { - pub fn bounds(&mut self, bounds: Bounds) -> &mut Self { - self.bounds = Some(bounds); - self - } - - pub fn fill(&mut self, fill: FillStyle) -> &mut Self { - self.fill = Some(fill); - self - } - - pub fn stroke(&mut self, stroke: StrokeStyle) -> &mut Self { - self.stroke = Some(stroke); - self - } - - pub fn build(&self, solver: &mut dyn SolverContext) -> ShapeContext { - ShapeContext { - bounds: self.bounds.clone().unwrap_or_else(|| Bounds::builder().build(solver)), - fill: self.fill.clone().unwrap_or_default(), - stroke: self.stroke.clone().unwrap_or_default(), - } - } -} +// #[derive(Clone, Default)] +// pub(crate) struct ShapeContextBuilder { +// bounds: Option, +// fill: Option, +// stroke: Option, +// } +// +// impl ShapeContextBuilder { +// pub fn bounds(&mut self, bounds: Bounds) -> &mut Self { +// self.bounds = Some(bounds); +// self +// } +// +// pub fn fill(&mut self, fill: FillStyle) -> &mut Self { +// self.fill = Some(fill); +// self +// } +// +// pub fn stroke(&mut self, stroke: StrokeStyle) -> &mut Self { +// self.stroke = Some(stroke); +// self +// } +// +// pub fn build(&self, solver: &mut dyn SolverContext) -> ShapeContext { +// ShapeContext { +// bounds: self.bounds.clone().unwrap_or_else(|| Bounds::builder().build(solver)), +// fill: self.fill.clone().unwrap_or_default(), +// stroke: self.stroke.clone().unwrap_or_default(), +// } +// } +// } #[derive(Clone, Debug)] -pub struct DefinedShapeContext { - pub bounds: DefinedBounds, - pub fill: FillStyle, - pub stroke: DefinedStrokeStyle, +pub struct DefinedCoreShapeContext { + pub(crate) bounds: DefinedBounds, + pub(crate) fill: FillStyle, + pub(crate) stroke: DefinedStrokeStyle, } -- cgit v1.2.3