Implement Canvas support for iced_tiny_skia
This commit is contained in:
parent
3f6e28fa9b
commit
5fd5d1cdf8
65 changed files with 1354 additions and 570 deletions
177
renderer/src/widget/canvas.rs
Normal file
177
renderer/src/widget/canvas.rs
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
mod cache;
|
||||
|
||||
pub use cache::Cache;
|
||||
|
||||
pub use iced_native::widget::canvas::event::{self, Event};
|
||||
pub use iced_native::widget::canvas::fill::{self, Fill};
|
||||
pub use iced_native::widget::canvas::gradient::{self, Gradient};
|
||||
pub use iced_native::widget::canvas::path::{self, Path};
|
||||
pub use iced_native::widget::canvas::stroke::{self, Stroke};
|
||||
pub use iced_native::widget::canvas::{
|
||||
Canvas, Cursor, LineCap, LineDash, LineJoin, Program, Renderer, Style, Text,
|
||||
};
|
||||
|
||||
use crate::{Backend, Point, Rectangle, Size, Vector};
|
||||
|
||||
pub use crate::Geometry;
|
||||
|
||||
pub enum Frame {
|
||||
Wgpu(iced_wgpu::widget::canvas::Frame),
|
||||
TinySkia(iced_tiny_skia::canvas::Frame),
|
||||
}
|
||||
|
||||
macro_rules! delegate {
|
||||
($frame:expr, $name:ident => $body:expr) => {
|
||||
match $frame {
|
||||
Self::Wgpu($name) => $body,
|
||||
Self::TinySkia($name) => $body,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn new<Theme>(renderer: &crate::Renderer<Theme>, size: Size) -> Self {
|
||||
match renderer.backend() {
|
||||
Backend::Wgpu(_) => {
|
||||
Frame::Wgpu(iced_wgpu::widget::canvas::Frame::new(size))
|
||||
}
|
||||
Backend::TinySkia(_) => {
|
||||
Frame::TinySkia(iced_tiny_skia::canvas::Frame::new(size))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the width of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn width(&self) -> f32 {
|
||||
delegate!(self, frame => frame.width())
|
||||
}
|
||||
|
||||
/// Returns the height of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn height(&self) -> f32 {
|
||||
delegate!(self, frame => frame.height())
|
||||
}
|
||||
|
||||
/// Returns the dimensions of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn size(&self) -> Size {
|
||||
delegate!(self, frame => frame.size())
|
||||
}
|
||||
|
||||
/// Returns the coordinate of the center of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn center(&self) -> Point {
|
||||
delegate!(self, frame => frame.center())
|
||||
}
|
||||
|
||||
/// Draws the given [`Path`] on the [`Frame`] by filling it with the
|
||||
/// provided style.
|
||||
pub fn fill(&mut self, path: &Path, fill: impl Into<Fill>) {
|
||||
delegate!(self, frame => frame.fill(path, fill));
|
||||
}
|
||||
|
||||
/// Draws an axis-aligned rectangle given its top-left corner coordinate and
|
||||
/// its `Size` on the [`Frame`] by filling it with the provided style.
|
||||
pub fn fill_rectangle(
|
||||
&mut self,
|
||||
top_left: Point,
|
||||
size: Size,
|
||||
fill: impl Into<Fill>,
|
||||
) {
|
||||
delegate!(self, frame => frame.fill_rectangle(top_left, size, fill));
|
||||
}
|
||||
|
||||
/// Draws the stroke of the given [`Path`] on the [`Frame`] with the
|
||||
/// provided style.
|
||||
pub fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>) {
|
||||
delegate!(self, frame => frame.stroke(path, stroke));
|
||||
}
|
||||
|
||||
/// Draws the characters of the given [`Text`] on the [`Frame`], filling
|
||||
/// them with the given color.
|
||||
///
|
||||
/// __Warning:__ Text currently does not work well with rotations and scale
|
||||
/// transforms! The position will be correctly transformed, but the
|
||||
/// resulting glyphs will not be rotated or scaled properly.
|
||||
///
|
||||
/// Additionally, all text will be rendered on top of all the layers of
|
||||
/// a [`Canvas`]. Therefore, it is currently only meant to be used for
|
||||
/// overlays, which is the most common use case.
|
||||
///
|
||||
/// Support for vectorial text is planned, and should address all these
|
||||
/// limitations.
|
||||
///
|
||||
/// [`Canvas`]: crate::widget::Canvas
|
||||
pub fn fill_text(&mut self, text: impl Into<Text>) {
|
||||
delegate!(self, frame => frame.fill_text(text));
|
||||
}
|
||||
|
||||
/// Stores the current transform of the [`Frame`] and executes the given
|
||||
/// drawing operations, restoring the transform afterwards.
|
||||
///
|
||||
/// This method is useful to compose transforms and perform drawing
|
||||
/// operations in different coordinate systems.
|
||||
#[inline]
|
||||
pub fn with_save(&mut self, f: impl FnOnce(&mut Frame)) {
|
||||
delegate!(self, frame => frame.push_transform());
|
||||
|
||||
f(self);
|
||||
|
||||
delegate!(self, frame => frame.pop_transform());
|
||||
}
|
||||
|
||||
/// Executes the given drawing operations within a [`Rectangle`] region,
|
||||
/// clipping any geometry that overflows its bounds. Any transformations
|
||||
/// performed are local to the provided closure.
|
||||
///
|
||||
/// This method is useful to perform drawing operations that need to be
|
||||
/// clipped.
|
||||
#[inline]
|
||||
pub fn with_clip(&mut self, region: Rectangle, f: impl FnOnce(&mut Frame)) {
|
||||
let mut frame = match self {
|
||||
Self::Wgpu(_) => {
|
||||
Self::Wgpu(iced_wgpu::widget::canvas::Frame::new(region.size()))
|
||||
}
|
||||
Self::TinySkia(_) => Self::TinySkia(
|
||||
iced_tiny_skia::canvas::Frame::new(region.size()),
|
||||
),
|
||||
};
|
||||
|
||||
f(&mut frame);
|
||||
|
||||
let translation = Vector::new(region.x, region.y);
|
||||
|
||||
match (self, frame) {
|
||||
(Self::Wgpu(target), Self::Wgpu(frame)) => {
|
||||
target.clip(frame, translation);
|
||||
}
|
||||
(Self::TinySkia(target), Self::TinySkia(frame)) => {
|
||||
target.clip(frame, translation);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Applies a translation to the current transform of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn translate(&mut self, translation: Vector) {
|
||||
delegate!(self, frame => frame.translate(translation));
|
||||
}
|
||||
|
||||
/// Applies a rotation in radians to the current transform of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn rotate(&mut self, angle: f32) {
|
||||
delegate!(self, frame => frame.rotate(angle));
|
||||
}
|
||||
|
||||
/// Applies a scaling to the current transform of the [`Frame`].
|
||||
#[inline]
|
||||
pub fn scale(&mut self, scale: f32) {
|
||||
delegate!(self, frame => frame.scale(scale));
|
||||
}
|
||||
|
||||
pub fn into_geometry(self) -> Geometry {
|
||||
Geometry(delegate!(self, frame => frame.into_primitive()))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue