Implement composable, type-safe renderer fallback

This commit is contained in:
Héctor Ramón Jiménez 2024-03-21 22:27:17 +01:00
parent 7e4ae8450e
commit 3645d34d6a
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
35 changed files with 1474 additions and 1210 deletions

View file

@ -1018,3 +1018,12 @@ impl backend::Svg for Backend {
self.vector_pipeline.viewport_dimensions(handle)
}
}
#[cfg(feature = "geometry")]
impl crate::graphics::geometry::Backend for Backend {
type Frame = crate::geometry::Frame;
fn new_frame(&self, size: Size) -> Self::Frame {
crate::geometry::Frame::new(size)
}
}

View file

@ -4,7 +4,7 @@ use crate::core::{
};
use crate::graphics::geometry::fill::{self, Fill};
use crate::graphics::geometry::stroke::{self, Stroke};
use crate::graphics::geometry::{Path, Style, Text};
use crate::graphics::geometry::{self, Path, Style, Text};
use crate::graphics::Gradient;
use crate::primitive::{self, Primitive};
@ -25,23 +25,36 @@ impl Frame {
}
}
pub fn width(&self) -> f32 {
pub fn into_primitive(self) -> Primitive {
Primitive::Clip {
bounds: Rectangle::new(Point::ORIGIN, self.size),
content: Box::new(Primitive::Group {
primitives: self.primitives,
}),
}
}
}
impl geometry::Frame for Frame {
type Geometry = Primitive;
fn width(&self) -> f32 {
self.size.width
}
pub fn height(&self) -> f32 {
fn height(&self) -> f32 {
self.size.height
}
pub fn size(&self) -> Size {
fn size(&self) -> Size {
self.size
}
pub fn center(&self) -> Point {
fn center(&self) -> Point {
Point::new(self.size.width / 2.0, self.size.height / 2.0)
}
pub fn fill(&mut self, path: &Path, fill: impl Into<Fill>) {
fn fill(&mut self, path: &Path, fill: impl Into<Fill>) {
let Some(path) =
convert_path(path).and_then(|path| path.transform(self.transform))
else {
@ -61,7 +74,7 @@ impl Frame {
}));
}
pub fn fill_rectangle(
fn fill_rectangle(
&mut self,
top_left: Point,
size: Size,
@ -89,7 +102,7 @@ impl Frame {
}));
}
pub fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>) {
fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>) {
let Some(path) =
convert_path(path).and_then(|path| path.transform(self.transform))
else {
@ -110,7 +123,7 @@ impl Frame {
}));
}
pub fn fill_text(&mut self, text: impl Into<Text>) {
fn fill_text(&mut self, text: impl Into<Text>) {
let text = text.into();
let (scale_x, scale_y) = self.transform.get_scale();
@ -174,51 +187,52 @@ impl Frame {
}
}
pub fn push_transform(&mut self) {
fn push_transform(&mut self) {
self.stack.push(self.transform);
}
pub fn pop_transform(&mut self) {
fn pop_transform(&mut self) {
self.transform = self.stack.pop().expect("Pop transform");
}
pub fn clip(&mut self, frame: Self, at: Point) {
fn draft(&mut self, size: Size) -> Self {
Self::new(size)
}
fn paste(&mut self, frame: Self, at: Point) {
self.primitives.push(Primitive::Transform {
transformation: Transformation::translate(at.x, at.y),
content: Box::new(frame.into_primitive()),
});
}
pub fn translate(&mut self, translation: Vector) {
fn translate(&mut self, translation: Vector) {
self.transform =
self.transform.pre_translate(translation.x, translation.y);
}
pub fn rotate(&mut self, angle: impl Into<Radians>) {
fn rotate(&mut self, angle: impl Into<Radians>) {
self.transform = self.transform.pre_concat(
tiny_skia::Transform::from_rotate(angle.into().0.to_degrees()),
);
}
pub fn scale(&mut self, scale: impl Into<f32>) {
fn scale(&mut self, scale: impl Into<f32>) {
let scale = scale.into();
self.scale_nonuniform(Vector { x: scale, y: scale });
}
pub fn scale_nonuniform(&mut self, scale: impl Into<Vector>) {
fn scale_nonuniform(&mut self, scale: impl Into<Vector>) {
let scale = scale.into();
self.transform = self.transform.pre_scale(scale.x, scale.y);
}
}
pub fn into_primitive(self) -> Primitive {
Primitive::Clip {
bounds: Rectangle::new(Point::ORIGIN, self.size),
content: Box::new(Primitive::Group {
primitives: self.primitives,
}),
}
impl From<Frame> for Primitive {
fn from(frame: Frame) -> Self {
frame.into_primitive()
}
}

View file

@ -1,5 +1,5 @@
use crate::core::Rectangle;
use crate::graphics::Damage;
use crate::graphics::{Damage, Mesh};
pub type Primitive = crate::graphics::Primitive<Custom>;
@ -42,3 +42,11 @@ impl Damage for Custom {
}
}
}
impl TryFrom<Mesh> for Custom {
type Error = &'static str;
fn try_from(_mesh: Mesh) -> Result<Self, Self::Error> {
Err("unsupported")
}
}