Introduce custom backend-specific primitives

This commit is contained in:
Héctor Ramón Jiménez 2023-06-22 00:38:36 +02:00
parent 8d65e40a11
commit 0ae1baa37b
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
28 changed files with 618 additions and 263 deletions

View file

@ -20,7 +20,6 @@ log = "0.4"
[dependencies.iced_graphics]
version = "0.8"
path = "../graphics"
features = ["tiny-skia"]
[dependencies.cosmic-text]
git = "https://github.com/hecrj/cosmic-text.git"

View file

@ -2,7 +2,8 @@ use crate::core::text;
use crate::core::Gradient;
use crate::core::{Background, Color, Font, Point, Rectangle, Size, Vector};
use crate::graphics::backend;
use crate::graphics::{Primitive, Viewport};
use crate::graphics::{Damage, Viewport};
use crate::primitive::{self, Primitive};
use crate::Settings;
use std::borrow::Cow;
@ -419,6 +420,13 @@ impl Backend {
self.raster_pipeline
.draw(handle, *bounds, pixels, transform, clip_mask);
}
#[cfg(not(feature = "image"))]
Primitive::Image { .. } => {
log::warn!(
"Unsupported primitive in `iced_tiny_skia`: {:?}",
primitive
);
}
#[cfg(feature = "svg")]
Primitive::Svg {
handle,
@ -442,12 +450,19 @@ impl Backend {
clip_mask,
);
}
Primitive::Fill {
#[cfg(not(feature = "svg"))]
Primitive::Svg { .. } => {
log::warn!(
"Unsupported primitive in `iced_tiny_skia`: {:?}",
primitive
);
}
Primitive::Custom(primitive::Custom::Fill {
path,
paint,
rule,
transform,
} => {
}) => {
let bounds = path.bounds();
let physical_bounds = (Rectangle {
@ -475,12 +490,12 @@ impl Backend {
clip_mask,
);
}
Primitive::Stroke {
Primitive::Custom(primitive::Custom::Stroke {
path,
paint,
stroke,
transform,
} => {
}) => {
let bounds = path.bounds();
let physical_bounds = (Rectangle {
@ -588,13 +603,6 @@ impl Backend {
primitive
);
}
_ => {
// Not supported!
log::warn!(
"Unsupported primitive in `iced_tiny_skia`: {:?}",
primitive
);
}
}
}
}
@ -766,6 +774,10 @@ fn adjust_clip_mask(clip_mask: &mut tiny_skia::Mask, bounds: Rectangle) {
);
}
impl iced_graphics::Backend for Backend {
type Primitive = primitive::Custom;
}
impl backend::Text for Backend {
const ICON_FONT: Font = Font::with_name("Iced-Icons");
const CHECKMARK_ICON: char = '\u{f00c}';

View file

@ -3,7 +3,7 @@ use crate::graphics::geometry::fill::{self, Fill};
use crate::graphics::geometry::stroke::{self, Stroke};
use crate::graphics::geometry::{Path, Style, Text};
use crate::graphics::Gradient;
use crate::graphics::Primitive;
use crate::primitive::{self, Primitive};
pub struct Frame {
size: Size,
@ -42,12 +42,13 @@ impl Frame {
let Some(path) = convert_path(path) else { return };
let fill = fill.into();
self.primitives.push(Primitive::Fill {
path,
paint: into_paint(fill.style),
rule: into_fill_rule(fill.rule),
transform: self.transform,
});
self.primitives
.push(Primitive::Custom(primitive::Custom::Fill {
path,
paint: into_paint(fill.style),
rule: into_fill_rule(fill.rule),
transform: self.transform,
}));
}
pub fn fill_rectangle(
@ -59,15 +60,16 @@ impl Frame {
let Some(path) = convert_path(&Path::rectangle(top_left, size)) else { return };
let fill = fill.into();
self.primitives.push(Primitive::Fill {
path,
paint: tiny_skia::Paint {
anti_alias: false,
..into_paint(fill.style)
},
rule: into_fill_rule(fill.rule),
transform: self.transform,
});
self.primitives
.push(Primitive::Custom(primitive::Custom::Fill {
path,
paint: tiny_skia::Paint {
anti_alias: false,
..into_paint(fill.style)
},
rule: into_fill_rule(fill.rule),
transform: self.transform,
}));
}
pub fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>) {
@ -76,12 +78,13 @@ impl Frame {
let stroke = stroke.into();
let skia_stroke = into_stroke(&stroke);
self.primitives.push(Primitive::Stroke {
path,
paint: into_paint(stroke.style),
stroke: skia_stroke,
transform: self.transform,
});
self.primitives
.push(Primitive::Custom(primitive::Custom::Stroke {
path,
paint: into_paint(stroke.style),
stroke: skia_stroke,
transform: self.transform,
}));
}
pub fn fill_text(&mut self, text: impl Into<Text>) {

View file

@ -1,6 +1,7 @@
pub mod window;
mod backend;
mod primitive;
mod settings;
mod text;
@ -17,6 +18,7 @@ pub use iced_graphics as graphics;
pub use iced_graphics::core;
pub use backend::Backend;
pub use primitive::Primitive;
pub use settings::Settings;
/// A [`tiny-skia`] graphics renderer for [`iced`].

View file

@ -0,0 +1,48 @@
use crate::core::Rectangle;
use crate::graphics::Damage;
pub type Primitive = crate::graphics::Primitive<Custom>;
#[derive(Debug, Clone, PartialEq)]
pub enum Custom {
/// A path filled with some paint.
Fill {
/// The path to fill.
path: tiny_skia::Path,
/// The paint to use.
paint: tiny_skia::Paint<'static>,
/// The fill rule to follow.
rule: tiny_skia::FillRule,
/// The transform to apply to the path.
transform: tiny_skia::Transform,
},
/// A path stroked with some paint.
Stroke {
/// The path to stroke.
path: tiny_skia::Path,
/// The paint to use.
paint: tiny_skia::Paint<'static>,
/// The stroke settings.
stroke: tiny_skia::Stroke,
/// The transform to apply to the path.
transform: tiny_skia::Transform,
},
}
impl Damage for Custom {
fn bounds(&self) -> Rectangle {
match self {
Self::Fill { path, .. } | Self::Stroke { path, .. } => {
let bounds = path.bounds();
Rectangle {
x: bounds.x(),
y: bounds.y(),
width: bounds.width(),
height: bounds.height(),
}
.expand(1.0)
}
}
}
}

View file

@ -1,8 +1,8 @@
use crate::core::{Color, Rectangle, Size};
use crate::graphics::compositor::{self, Information};
use crate::graphics::damage;
use crate::graphics::{Error, Primitive, Viewport};
use crate::{Backend, Renderer, Settings};
use crate::graphics::{Error, Viewport};
use crate::{Backend, Primitive, Renderer, Settings};
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
use std::marker::PhantomData;