Draft support for Quad and Clip primitives in iced_tiny_skia
This commit is contained in:
parent
445b31c6c5
commit
df5d66423d
1 changed files with 150 additions and 3 deletions
|
|
@ -2,7 +2,7 @@ use crate::{Color, Font, Settings, Size, Viewport};
|
||||||
|
|
||||||
use iced_graphics::backend;
|
use iced_graphics::backend;
|
||||||
use iced_graphics::text;
|
use iced_graphics::text;
|
||||||
use iced_graphics::Primitive;
|
use iced_graphics::{Background, Primitive, Rectangle, Vector};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
|
@ -22,12 +22,133 @@ impl Backend {
|
||||||
pub fn draw<T: AsRef<str>>(
|
pub fn draw<T: AsRef<str>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pixels: &mut tiny_skia::Pixmap,
|
pixels: &mut tiny_skia::Pixmap,
|
||||||
_primitives: &[Primitive],
|
primitives: &[Primitive],
|
||||||
_viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
_overlay: &[T],
|
_overlay: &[T],
|
||||||
) {
|
) {
|
||||||
pixels.fill(into_color(background_color));
|
pixels.fill(into_color(background_color));
|
||||||
|
|
||||||
|
let scale_factor = viewport.scale_factor() as f32;
|
||||||
|
|
||||||
|
for primitive in primitives {
|
||||||
|
draw_primitive(primitive, pixels, None, scale_factor, Vector::ZERO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_primitive(
|
||||||
|
primitive: &Primitive,
|
||||||
|
pixels: &mut tiny_skia::Pixmap,
|
||||||
|
clip_mask: Option<&tiny_skia::ClipMask>,
|
||||||
|
scale_factor: f32,
|
||||||
|
translation: Vector,
|
||||||
|
) {
|
||||||
|
match primitive {
|
||||||
|
Primitive::None => {}
|
||||||
|
Primitive::Quad {
|
||||||
|
bounds,
|
||||||
|
background,
|
||||||
|
border_radius: _, // TODO
|
||||||
|
border_width,
|
||||||
|
border_color,
|
||||||
|
} => {
|
||||||
|
let transform = tiny_skia::Transform::from_translate(
|
||||||
|
translation.x,
|
||||||
|
translation.y,
|
||||||
|
)
|
||||||
|
.post_scale(scale_factor, scale_factor);
|
||||||
|
|
||||||
|
let path = tiny_skia::PathBuilder::from_rect(
|
||||||
|
tiny_skia::Rect::from_xywh(
|
||||||
|
bounds.x,
|
||||||
|
bounds.y,
|
||||||
|
bounds.width,
|
||||||
|
bounds.height,
|
||||||
|
)
|
||||||
|
.expect("Create quad rectangle"),
|
||||||
|
);
|
||||||
|
|
||||||
|
pixels.fill_path(
|
||||||
|
&path,
|
||||||
|
&tiny_skia::Paint {
|
||||||
|
shader: match background {
|
||||||
|
Background::Color(color) => {
|
||||||
|
tiny_skia::Shader::SolidColor(into_color(*color))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
anti_alias: true,
|
||||||
|
..tiny_skia::Paint::default()
|
||||||
|
},
|
||||||
|
tiny_skia::FillRule::EvenOdd,
|
||||||
|
transform,
|
||||||
|
clip_mask,
|
||||||
|
);
|
||||||
|
|
||||||
|
if *border_width > 0.0 {
|
||||||
|
pixels.stroke_path(
|
||||||
|
&path,
|
||||||
|
&tiny_skia::Paint {
|
||||||
|
shader: tiny_skia::Shader::SolidColor(into_color(
|
||||||
|
*border_color,
|
||||||
|
)),
|
||||||
|
anti_alias: true,
|
||||||
|
..tiny_skia::Paint::default()
|
||||||
|
},
|
||||||
|
&tiny_skia::Stroke {
|
||||||
|
width: *border_width,
|
||||||
|
..tiny_skia::Stroke::default()
|
||||||
|
},
|
||||||
|
transform,
|
||||||
|
clip_mask,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Primitive::Text { .. } => {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
Primitive::Image { .. } => {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
Primitive::Svg { .. } => {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
Primitive::Group { primitives } => {
|
||||||
|
for primitive in primitives {
|
||||||
|
draw_primitive(
|
||||||
|
primitive,
|
||||||
|
pixels,
|
||||||
|
clip_mask,
|
||||||
|
scale_factor,
|
||||||
|
translation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Primitive::Translate {
|
||||||
|
translation: offset,
|
||||||
|
content,
|
||||||
|
} => {
|
||||||
|
draw_primitive(
|
||||||
|
content,
|
||||||
|
pixels,
|
||||||
|
clip_mask,
|
||||||
|
scale_factor,
|
||||||
|
translation + *offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Primitive::Clip { bounds, content } => {
|
||||||
|
draw_primitive(
|
||||||
|
content,
|
||||||
|
pixels,
|
||||||
|
Some(&rectangular_clip_mask(pixels, *bounds * scale_factor)),
|
||||||
|
scale_factor,
|
||||||
|
translation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Primitive::Cached { cache } => {
|
||||||
|
draw_primitive(cache, pixels, clip_mask, scale_factor, translation);
|
||||||
|
}
|
||||||
|
Primitive::SolidMesh { .. } | Primitive::GradientMesh { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,6 +157,32 @@ fn into_color(color: Color) -> tiny_skia::Color {
|
||||||
.expect("Convert color from iced to tiny_skia")
|
.expect("Convert color from iced to tiny_skia")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rectangular_clip_mask(
|
||||||
|
pixels: &tiny_skia::Pixmap,
|
||||||
|
bounds: Rectangle,
|
||||||
|
) -> tiny_skia::ClipMask {
|
||||||
|
let mut clip_mask = tiny_skia::ClipMask::new();
|
||||||
|
|
||||||
|
let path = {
|
||||||
|
let mut builder = tiny_skia::PathBuilder::new();
|
||||||
|
builder.push_rect(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||||
|
|
||||||
|
builder.finish().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
clip_mask
|
||||||
|
.set_path(
|
||||||
|
pixels.width(),
|
||||||
|
pixels.height(),
|
||||||
|
&path,
|
||||||
|
tiny_skia::FillRule::EvenOdd,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.expect("Set path of clipping area");
|
||||||
|
|
||||||
|
clip_mask
|
||||||
|
}
|
||||||
|
|
||||||
impl iced_graphics::Backend for Backend {
|
impl iced_graphics::Backend for Backend {
|
||||||
fn trim_measurements(&mut self) {
|
fn trim_measurements(&mut self) {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue