Introduce Svg struct in core::svg
This commit is contained in:
parent
8708101c89
commit
d4b08462e5
18 changed files with 146 additions and 257 deletions
|
|
@ -16,7 +16,7 @@ pub struct Image<H = Handle> {
|
||||||
/// The filter method of the image.
|
/// The filter method of the image.
|
||||||
pub filter_method: FilterMethod,
|
pub filter_method: FilterMethod,
|
||||||
|
|
||||||
/// The rotation to be applied to the image, from its center.
|
/// The rotation to be applied to the image; on its center.
|
||||||
pub rotation: Radians,
|
pub rotation: Radians,
|
||||||
|
|
||||||
/// The opacity of the image.
|
/// The opacity of the image.
|
||||||
|
|
@ -26,7 +26,7 @@ pub struct Image<H = Handle> {
|
||||||
|
|
||||||
/// If set to `true`, the image will be snapped to the pixel grid.
|
/// If set to `true`, the image will be snapped to the pixel grid.
|
||||||
///
|
///
|
||||||
/// This can avoid graphical glitches, specially when using a
|
/// This can avoid graphical glitches, specially when using
|
||||||
/// [`FilterMethod::Nearest`].
|
/// [`FilterMethod::Nearest`].
|
||||||
pub snap: bool,
|
pub snap: bool,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ pub use rotation::Rotation;
|
||||||
pub use shadow::Shadow;
|
pub use shadow::Shadow;
|
||||||
pub use shell::Shell;
|
pub use shell::Shell;
|
||||||
pub use size::Size;
|
pub use size::Size;
|
||||||
|
pub use svg::Svg;
|
||||||
pub use text::Text;
|
pub use text::Text;
|
||||||
pub use theme::Theme;
|
pub use theme::Theme;
|
||||||
pub use transformation::Transformation;
|
pub use transformation::Transformation;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ use crate::renderer::{self, Renderer};
|
||||||
use crate::svg;
|
use crate::svg;
|
||||||
use crate::text::{self, Text};
|
use crate::text::{self, Text};
|
||||||
use crate::{
|
use crate::{
|
||||||
Background, Color, Font, Pixels, Point, Radians, Rectangle, Size,
|
Background, Color, Font, Pixels, Point, Rectangle, Size, Transformation,
|
||||||
Transformation,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Renderer for () {
|
impl Renderer for () {
|
||||||
|
|
@ -192,13 +191,5 @@ impl svg::Renderer for () {
|
||||||
Size::default()
|
Size::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, _svg: svg::Svg, _bounds: Rectangle) {}
|
||||||
&mut self,
|
|
||||||
_handle: svg::Handle,
|
|
||||||
_color: Option<Color>,
|
|
||||||
_bounds: Rectangle,
|
|
||||||
_rotation: Radians,
|
|
||||||
_opacity: f32,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,66 @@ use std::hash::{Hash, Hasher as _};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// A raster image that can be drawn.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct Svg<H = Handle> {
|
||||||
|
/// The handle of the [`Svg`].
|
||||||
|
pub handle: H,
|
||||||
|
|
||||||
|
/// The [`Color`] filter to be applied to the [`Svg`].
|
||||||
|
///
|
||||||
|
/// If some [`Color`] is set, the whole [`Svg`] will be
|
||||||
|
/// painted with it—ignoring any intrinsic colors.
|
||||||
|
///
|
||||||
|
/// This can be useful for coloring icons programmatically
|
||||||
|
/// (e.g. with a theme).
|
||||||
|
pub color: Option<Color>,
|
||||||
|
|
||||||
|
/// The rotation to be applied to the image; on its center.
|
||||||
|
pub rotation: Radians,
|
||||||
|
|
||||||
|
/// The opacity of the [`Svg`].
|
||||||
|
///
|
||||||
|
/// 0 means transparent. 1 means opaque.
|
||||||
|
pub opacity: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Svg<Handle> {
|
||||||
|
/// Creates a new [`Svg`] with the given handle.
|
||||||
|
pub fn new(handle: impl Into<Handle>) -> Self {
|
||||||
|
Self {
|
||||||
|
handle: handle.into(),
|
||||||
|
color: None,
|
||||||
|
rotation: Radians(0.0),
|
||||||
|
opacity: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the [`Color`] filter of the [`Svg`].
|
||||||
|
pub fn color(mut self, color: impl Into<Color>) -> Self {
|
||||||
|
self.color = Some(color.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the rotation of the [`Svg`].
|
||||||
|
pub fn rotation(mut self, rotation: impl Into<Radians>) -> Self {
|
||||||
|
self.rotation = rotation.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the opacity of the [`Svg`].
|
||||||
|
pub fn opacity(mut self, opacity: impl Into<f32>) -> Self {
|
||||||
|
self.opacity = opacity.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Handle> for Svg {
|
||||||
|
fn from(handle: &Handle) -> Self {
|
||||||
|
Svg::new(handle.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A handle of Svg data.
|
/// A handle of Svg data.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Handle {
|
pub struct Handle {
|
||||||
|
|
@ -95,12 +155,5 @@ pub trait Renderer: crate::Renderer {
|
||||||
fn measure_svg(&self, handle: &Handle) -> Size<u32>;
|
fn measure_svg(&self, handle: &Handle) -> Size<u32>;
|
||||||
|
|
||||||
/// Draws an SVG with the given [`Handle`], an optional [`Color`] filter, and inside the provided `bounds`.
|
/// Draws an SVG with the given [`Handle`], an optional [`Color`] filter, and inside the provided `bounds`.
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, svg: Svg, bounds: Rectangle);
|
||||||
&mut self,
|
|
||||||
handle: Handle,
|
|
||||||
color: Option<Color>,
|
|
||||||
bounds: Rectangle,
|
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub use stroke::{LineCap, LineDash, LineJoin, Stroke};
|
||||||
pub use style::Style;
|
pub use style::Style;
|
||||||
pub use text::Text;
|
pub use text::Text;
|
||||||
|
|
||||||
pub use crate::core::Image;
|
pub use crate::core::{Image, Svg};
|
||||||
pub use crate::gradient::{self, Gradient};
|
pub use crate::gradient::{self, Gradient};
|
||||||
|
|
||||||
use crate::cache::Cached;
|
use crate::cache::Cached;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
//! Draw and generate geometry.
|
//! Draw and generate geometry.
|
||||||
use crate::core::svg;
|
use crate::core::{Point, Radians, Rectangle, Size, Vector};
|
||||||
use crate::core::{Color, Point, Radians, Rectangle, Size, Vector};
|
use crate::geometry::{self, Fill, Image, Path, Stroke, Svg, Text};
|
||||||
use crate::geometry::{self, Fill, Image, Path, Stroke, Text};
|
|
||||||
|
|
||||||
/// The region of a surface that can be used to draw geometry.
|
/// The region of a surface that can be used to draw geometry.
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
|
|
@ -206,15 +205,7 @@ pub trait Backend: Sized {
|
||||||
);
|
);
|
||||||
|
|
||||||
fn draw_image(&mut self, bounds: Rectangle, image: impl Into<Image>);
|
fn draw_image(&mut self, bounds: Rectangle, image: impl Into<Image>);
|
||||||
|
fn draw_svg(&mut self, bounds: Rectangle, svg: impl Into<Svg>);
|
||||||
fn draw_svg(
|
|
||||||
&mut self,
|
|
||||||
handle: &svg::Handle,
|
|
||||||
bounds: Rectangle,
|
|
||||||
color: Option<Color>,
|
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
);
|
|
||||||
|
|
||||||
fn into_geometry(self) -> Self::Geometry;
|
fn into_geometry(self) -> Self::Geometry;
|
||||||
}
|
}
|
||||||
|
|
@ -262,17 +253,8 @@ impl Backend for () {
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_geometry(self) -> Self::Geometry {}
|
|
||||||
|
|
||||||
fn draw_image(&mut self, _bounds: Rectangle, _image: impl Into<Image>) {}
|
fn draw_image(&mut self, _bounds: Rectangle, _image: impl Into<Image>) {}
|
||||||
|
fn draw_svg(&mut self, _bounds: Rectangle, _svg: impl Into<Svg>) {}
|
||||||
|
|
||||||
fn draw_svg(
|
fn into_geometry(self) -> Self::Geometry {}
|
||||||
&mut self,
|
|
||||||
_handle: &svg::Handle,
|
|
||||||
_bounds: Rectangle,
|
|
||||||
_color: Option<Color>,
|
|
||||||
_rotation: Radians,
|
|
||||||
_opacity: f32,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
#[cfg(feature = "image")]
|
#[cfg(feature = "image")]
|
||||||
pub use ::image as image_rs;
|
pub use ::image as image_rs;
|
||||||
|
|
||||||
use crate::core::{image, svg, Color, Radians, Rectangle};
|
use crate::core::image;
|
||||||
|
use crate::core::svg;
|
||||||
|
use crate::core::Rectangle;
|
||||||
|
|
||||||
/// A raster or vector image.
|
/// A raster or vector image.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
@ -11,22 +13,7 @@ pub enum Image {
|
||||||
Raster(image::Image, Rectangle),
|
Raster(image::Image, Rectangle),
|
||||||
|
|
||||||
/// A vector image.
|
/// A vector image.
|
||||||
Vector {
|
Vector(svg::Svg, Rectangle),
|
||||||
/// The handle of a vector image.
|
|
||||||
handle: svg::Handle,
|
|
||||||
|
|
||||||
/// The [`Color`] filter
|
|
||||||
color: Option<Color>,
|
|
||||||
|
|
||||||
/// The bounds of the image.
|
|
||||||
bounds: Rectangle,
|
|
||||||
|
|
||||||
/// The rotation of the image.
|
|
||||||
rotation: Radians,
|
|
||||||
|
|
||||||
/// The opacity of the image.
|
|
||||||
opacity: f32,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
|
|
@ -34,9 +21,7 @@ impl Image {
|
||||||
pub fn bounds(&self) -> Rectangle {
|
pub fn bounds(&self) -> Rectangle {
|
||||||
match self {
|
match self {
|
||||||
Image::Raster(image, bounds) => bounds.rotate(image.rotation),
|
Image::Raster(image, bounds) => bounds.rotate(image.rotation),
|
||||||
Image::Vector {
|
Image::Vector(svg, bounds) => bounds.rotate(svg.rotation),
|
||||||
bounds, rotation, ..
|
|
||||||
} => bounds.rotate(*rotation),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ use crate::core::image;
|
||||||
use crate::core::renderer;
|
use crate::core::renderer;
|
||||||
use crate::core::svg;
|
use crate::core::svg;
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, Background, Color, Image, Point, Radians, Rectangle, Size,
|
self, Background, Color, Image, Point, Rectangle, Size, Svg, Transformation,
|
||||||
Transformation,
|
|
||||||
};
|
};
|
||||||
use crate::graphics;
|
use crate::graphics;
|
||||||
use crate::graphics::compositor;
|
use crate::graphics::compositor;
|
||||||
|
|
@ -164,19 +163,8 @@ where
|
||||||
delegate!(self, renderer, renderer.measure_svg(handle))
|
delegate!(self, renderer, renderer.measure_svg(handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, svg: Svg, bounds: Rectangle) {
|
||||||
&mut self,
|
delegate!(self, renderer, renderer.draw_svg(svg, bounds));
|
||||||
handle: svg::Handle,
|
|
||||||
color: Option<Color>,
|
|
||||||
bounds: Rectangle,
|
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
|
||||||
delegate!(
|
|
||||||
self,
|
|
||||||
renderer,
|
|
||||||
renderer.draw_svg(handle, color, bounds, rotation, opacity)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,8 +413,7 @@ where
|
||||||
#[cfg(feature = "geometry")]
|
#[cfg(feature = "geometry")]
|
||||||
mod geometry {
|
mod geometry {
|
||||||
use super::Renderer;
|
use super::Renderer;
|
||||||
use crate::core::svg;
|
use crate::core::{Point, Radians, Rectangle, Size, Svg, Vector};
|
||||||
use crate::core::{Color, Point, Radians, Rectangle, Size, Vector};
|
|
||||||
use crate::graphics::cache::{self, Cached};
|
use crate::graphics::cache::{self, Cached};
|
||||||
use crate::graphics::geometry::{self, Fill, Image, Path, Stroke, Text};
|
use crate::graphics::geometry::{self, Fill, Image, Path, Stroke, Text};
|
||||||
|
|
||||||
|
|
@ -561,19 +548,8 @@ mod geometry {
|
||||||
delegate!(self, frame, frame.draw_image(bounds, image));
|
delegate!(self, frame, frame.draw_image(bounds, image));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, bounds: Rectangle, svg: impl Into<Svg>) {
|
||||||
&mut self,
|
delegate!(self, frame, frame.draw_svg(bounds, svg));
|
||||||
handle: &svg::Handle,
|
|
||||||
bounds: Rectangle,
|
|
||||||
color: Option<Color>,
|
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
|
||||||
delegate!(
|
|
||||||
self,
|
|
||||||
frame,
|
|
||||||
frame.draw_svg(handle, bounds, color, rotation, opacity)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_transform(&mut self) {
|
fn push_transform(&mut self) {
|
||||||
|
|
|
||||||
|
|
@ -580,13 +580,7 @@ impl Engine {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
Image::Vector {
|
Image::Vector(svg, bounds) => {
|
||||||
handle,
|
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
} => {
|
|
||||||
let physical_bounds = *bounds * _transformation;
|
let physical_bounds = *bounds * _transformation;
|
||||||
|
|
||||||
if !_clip_bounds.intersects(&physical_bounds) {
|
if !_clip_bounds.intersects(&physical_bounds) {
|
||||||
|
|
@ -597,7 +591,7 @@ impl Engine {
|
||||||
.then_some(_clip_mask as &_);
|
.then_some(_clip_mask as &_);
|
||||||
|
|
||||||
let center = physical_bounds.center();
|
let center = physical_bounds.center();
|
||||||
let radians = f32::from(*rotation);
|
let radians = f32::from(svg.rotation);
|
||||||
|
|
||||||
let transform = into_transform(_transformation).post_rotate_at(
|
let transform = into_transform(_transformation).post_rotate_at(
|
||||||
radians.to_degrees(),
|
radians.to_degrees(),
|
||||||
|
|
@ -606,10 +600,10 @@ impl Engine {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.vector_pipeline.draw(
|
self.vector_pipeline.draw(
|
||||||
handle,
|
&svg.handle,
|
||||||
*color,
|
svg.color,
|
||||||
physical_bounds,
|
physical_bounds,
|
||||||
*opacity,
|
svg.opacity,
|
||||||
_pixels,
|
_pixels,
|
||||||
transform,
|
transform,
|
||||||
clip_mask,
|
clip_mask,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::core::svg;
|
|
||||||
use crate::core::text::LineHeight;
|
use crate::core::text::LineHeight;
|
||||||
use crate::core::{Color, Pixels, Point, Radians, Rectangle, Size, Vector};
|
use crate::core::{self, Pixels, Point, Radians, Rectangle, Size, Svg, Vector};
|
||||||
use crate::graphics::cache::{self, Cached};
|
use crate::graphics::cache::{self, Cached};
|
||||||
use crate::graphics::geometry::fill::{self, Fill};
|
use crate::graphics::geometry::fill::{self, Fill};
|
||||||
use crate::graphics::geometry::stroke::{self, Stroke};
|
use crate::graphics::geometry::stroke::{self, Stroke};
|
||||||
use crate::graphics::geometry::{self, Image, Path, Style};
|
use crate::graphics::geometry::{self, Path, Style};
|
||||||
use crate::graphics::{self, Gradient, Text};
|
use crate::graphics::{self, Gradient, Image, Text};
|
||||||
use crate::Primitive;
|
use crate::Primitive;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -282,7 +281,7 @@ impl geometry::frame::Backend for Frame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_image(&mut self, bounds: Rectangle, image: impl Into<Image>) {
|
fn draw_image(&mut self, bounds: Rectangle, image: impl Into<core::Image>) {
|
||||||
let mut image = image.into();
|
let mut image = image.into();
|
||||||
|
|
||||||
let (bounds, external_rotation) =
|
let (bounds, external_rotation) =
|
||||||
|
|
@ -293,24 +292,15 @@ impl geometry::frame::Backend for Frame {
|
||||||
self.images.push(graphics::Image::Raster(image, bounds));
|
self.images.push(graphics::Image::Raster(image, bounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, bounds: Rectangle, svg: impl Into<Svg>) {
|
||||||
&mut self,
|
let mut svg = svg.into();
|
||||||
handle: &svg::Handle,
|
|
||||||
bounds: Rectangle,
|
|
||||||
color: Option<Color>,
|
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
|
||||||
let (bounds, external_rotation) =
|
let (bounds, external_rotation) =
|
||||||
transform_rectangle(bounds, self.transform);
|
transform_rectangle(bounds, self.transform);
|
||||||
|
|
||||||
self.images.push(graphics::Image::Vector {
|
svg.rotation += external_rotation;
|
||||||
handle: handle.clone(),
|
|
||||||
bounds,
|
self.images.push(Image::Vector(svg, bounds));
|
||||||
color,
|
|
||||||
rotation: rotation + external_rotation,
|
|
||||||
opacity,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::core::renderer::Quad;
|
use crate::core::renderer::Quad;
|
||||||
use crate::core::svg;
|
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, Background, Color, Point, Radians, Rectangle, Transformation,
|
self, Background, Color, Point, Rectangle, Svg, Transformation,
|
||||||
};
|
};
|
||||||
use crate::graphics::damage;
|
use crate::graphics::damage;
|
||||||
use crate::graphics::layer;
|
use crate::graphics::layer;
|
||||||
|
|
@ -119,23 +118,10 @@ impl Layer {
|
||||||
pub fn draw_image(&mut self, image: Image, transformation: Transformation) {
|
pub fn draw_image(&mut self, image: Image, transformation: Transformation) {
|
||||||
match image {
|
match image {
|
||||||
Image::Raster(raster, bounds) => {
|
Image::Raster(raster, bounds) => {
|
||||||
self.draw_raster(raster.clone(), bounds, transformation);
|
self.draw_raster(raster, bounds, transformation);
|
||||||
}
|
}
|
||||||
Image::Vector {
|
Image::Vector(svg, bounds) => {
|
||||||
handle,
|
self.draw_svg(svg, bounds, transformation);
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
} => {
|
|
||||||
self.draw_svg(
|
|
||||||
handle.clone(),
|
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
transformation,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,20 +139,11 @@ impl Layer {
|
||||||
|
|
||||||
pub fn draw_svg(
|
pub fn draw_svg(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: svg::Handle,
|
svg: Svg,
|
||||||
color: Option<Color>,
|
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
transformation: Transformation,
|
transformation: Transformation,
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
) {
|
||||||
let svg = Image::Vector {
|
let svg = Image::Vector(svg, bounds * transformation);
|
||||||
handle,
|
|
||||||
color,
|
|
||||||
bounds: bounds * transformation,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.images.push(svg);
|
self.images.push(svg);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -396,23 +396,9 @@ impl core::svg::Renderer for Renderer {
|
||||||
self.engine.vector_pipeline.viewport_dimensions(handle)
|
self.engine.vector_pipeline.viewport_dimensions(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, svg: core::Svg, bounds: Rectangle) {
|
||||||
&mut self,
|
|
||||||
handle: core::svg::Handle,
|
|
||||||
color: Option<Color>,
|
|
||||||
bounds: Rectangle,
|
|
||||||
rotation: core::Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
|
||||||
let (layer, transformation) = self.layers.current_mut();
|
let (layer, transformation) = self.layers.current_mut();
|
||||||
layer.draw_svg(
|
layer.draw_svg(svg, bounds, transformation);
|
||||||
handle,
|
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
transformation,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
//! Build and draw geometry.
|
//! Build and draw geometry.
|
||||||
use crate::core::svg;
|
|
||||||
use crate::core::text::LineHeight;
|
use crate::core::text::LineHeight;
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
Color, Pixels, Point, Radians, Rectangle, Size, Transformation, Vector,
|
self, Pixels, Point, Radians, Rectangle, Size, Svg, Transformation, Vector,
|
||||||
};
|
};
|
||||||
use crate::graphics::cache::{self, Cached};
|
use crate::graphics::cache::{self, Cached};
|
||||||
use crate::graphics::color;
|
use crate::graphics::color;
|
||||||
use crate::graphics::geometry::fill::{self, Fill};
|
use crate::graphics::geometry::fill::{self, Fill};
|
||||||
use crate::graphics::geometry::{
|
use crate::graphics::geometry::{
|
||||||
self, Image, LineCap, LineDash, LineJoin, Path, Stroke, Style,
|
self, LineCap, LineDash, LineJoin, Path, Stroke, Style,
|
||||||
};
|
};
|
||||||
use crate::graphics::gradient::{self, Gradient};
|
use crate::graphics::gradient::{self, Gradient};
|
||||||
use crate::graphics::mesh::{self, Mesh};
|
use crate::graphics::mesh::{self, Mesh};
|
||||||
use crate::graphics::{self, Text};
|
use crate::graphics::{Image, Text};
|
||||||
use crate::text;
|
use crate::text;
|
||||||
use crate::triangle;
|
use crate::triangle;
|
||||||
|
|
||||||
|
|
@ -26,7 +25,7 @@ use std::sync::Arc;
|
||||||
pub enum Geometry {
|
pub enum Geometry {
|
||||||
Live {
|
Live {
|
||||||
meshes: Vec<Mesh>,
|
meshes: Vec<Mesh>,
|
||||||
images: Vec<graphics::Image>,
|
images: Vec<Image>,
|
||||||
text: Vec<Text>,
|
text: Vec<Text>,
|
||||||
},
|
},
|
||||||
Cached(Cache),
|
Cached(Cache),
|
||||||
|
|
@ -35,7 +34,7 @@ pub enum Geometry {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
pub meshes: Option<triangle::Cache>,
|
pub meshes: Option<triangle::Cache>,
|
||||||
pub images: Option<Arc<[graphics::Image]>>,
|
pub images: Option<Arc<[Image]>>,
|
||||||
pub text: Option<text::Cache>,
|
pub text: Option<text::Cache>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +97,7 @@ pub struct Frame {
|
||||||
clip_bounds: Rectangle,
|
clip_bounds: Rectangle,
|
||||||
buffers: BufferStack,
|
buffers: BufferStack,
|
||||||
meshes: Vec<Mesh>,
|
meshes: Vec<Mesh>,
|
||||||
images: Vec<graphics::Image>,
|
images: Vec<Image>,
|
||||||
text: Vec<Text>,
|
text: Vec<Text>,
|
||||||
transforms: Transforms,
|
transforms: Transforms,
|
||||||
fill_tessellator: tessellation::FillTessellator,
|
fill_tessellator: tessellation::FillTessellator,
|
||||||
|
|
@ -292,7 +291,7 @@ impl geometry::frame::Backend for Frame {
|
||||||
height: f32::INFINITY,
|
height: f32::INFINITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.text.push(graphics::Text::Cached {
|
self.text.push(Text::Cached {
|
||||||
content: text.content,
|
content: text.content,
|
||||||
bounds,
|
bounds,
|
||||||
color: text.color,
|
color: text.color,
|
||||||
|
|
@ -376,7 +375,7 @@ impl geometry::frame::Backend for Frame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_image(&mut self, bounds: Rectangle, image: impl Into<Image>) {
|
fn draw_image(&mut self, bounds: Rectangle, image: impl Into<core::Image>) {
|
||||||
let mut image = image.into();
|
let mut image = image.into();
|
||||||
|
|
||||||
let (bounds, external_rotation) =
|
let (bounds, external_rotation) =
|
||||||
|
|
@ -384,27 +383,18 @@ impl geometry::frame::Backend for Frame {
|
||||||
|
|
||||||
image.rotation += external_rotation;
|
image.rotation += external_rotation;
|
||||||
|
|
||||||
self.images.push(graphics::Image::Raster(image, bounds));
|
self.images.push(Image::Raster(image, bounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, bounds: Rectangle, svg: impl Into<Svg>) {
|
||||||
&mut self,
|
let mut svg = svg.into();
|
||||||
handle: &svg::Handle,
|
|
||||||
bounds: Rectangle,
|
|
||||||
color: Option<Color>,
|
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
|
||||||
let (bounds, external_rotation) =
|
let (bounds, external_rotation) =
|
||||||
self.transforms.current.transform_rectangle(bounds);
|
self.transforms.current.transform_rectangle(bounds);
|
||||||
|
|
||||||
self.images.push(graphics::Image::Vector {
|
svg.rotation += external_rotation;
|
||||||
handle: handle.clone(),
|
|
||||||
color,
|
self.images.push(Image::Vector(svg, bounds));
|
||||||
bounds,
|
|
||||||
rotation: rotation + external_rotation,
|
|
||||||
opacity,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,23 +246,22 @@ impl Pipeline {
|
||||||
Image::Raster { .. } => {}
|
Image::Raster { .. } => {}
|
||||||
|
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
Image::Vector {
|
Image::Vector(svg, bounds) => {
|
||||||
handle,
|
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
} => {
|
|
||||||
let size = [bounds.width, bounds.height];
|
let size = [bounds.width, bounds.height];
|
||||||
|
|
||||||
if let Some(atlas_entry) = cache.upload_vector(
|
if let Some(atlas_entry) = cache.upload_vector(
|
||||||
device, encoder, handle, *color, size, scale,
|
device,
|
||||||
|
encoder,
|
||||||
|
&svg.handle,
|
||||||
|
svg.color,
|
||||||
|
size,
|
||||||
|
scale,
|
||||||
) {
|
) {
|
||||||
add_instances(
|
add_instances(
|
||||||
[bounds.x, bounds.y],
|
[bounds.x, bounds.y],
|
||||||
size,
|
size,
|
||||||
f32::from(*rotation),
|
f32::from(svg.rotation),
|
||||||
*opacity,
|
svg.opacity,
|
||||||
true,
|
true,
|
||||||
atlas_entry,
|
atlas_entry,
|
||||||
nearest_instances,
|
nearest_instances,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, renderer, Background, Color, Point, Radians, Rectangle,
|
self, renderer, Background, Color, Point, Rectangle, Svg, Transformation,
|
||||||
Transformation,
|
|
||||||
};
|
};
|
||||||
use crate::graphics;
|
use crate::graphics;
|
||||||
use crate::graphics::color;
|
use crate::graphics::color;
|
||||||
|
|
@ -118,21 +117,8 @@ impl Layer {
|
||||||
Image::Raster(image, bounds) => {
|
Image::Raster(image, bounds) => {
|
||||||
self.draw_raster(image, bounds, transformation);
|
self.draw_raster(image, bounds, transformation);
|
||||||
}
|
}
|
||||||
Image::Vector {
|
Image::Vector(svg, bounds) => {
|
||||||
handle,
|
self.draw_svg(svg, bounds, transformation);
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
} => {
|
|
||||||
self.draw_svg(
|
|
||||||
handle.clone(),
|
|
||||||
color,
|
|
||||||
bounds,
|
|
||||||
transformation,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -150,20 +136,11 @@ impl Layer {
|
||||||
|
|
||||||
pub fn draw_svg(
|
pub fn draw_svg(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: crate::core::svg::Handle,
|
svg: Svg,
|
||||||
color: Option<Color>,
|
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
transformation: Transformation,
|
transformation: Transformation,
|
||||||
rotation: Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
) {
|
||||||
let svg = Image::Vector {
|
let svg = Image::Vector(svg, bounds * transformation);
|
||||||
handle,
|
|
||||||
color,
|
|
||||||
bounds: bounds * transformation,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.images.push(svg);
|
self.images.push(svg);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -539,23 +539,9 @@ impl core::svg::Renderer for Renderer {
|
||||||
self.image_cache.borrow_mut().measure_svg(handle)
|
self.image_cache.borrow_mut().measure_svg(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_svg(
|
fn draw_svg(&mut self, svg: core::Svg, bounds: Rectangle) {
|
||||||
&mut self,
|
|
||||||
handle: core::svg::Handle,
|
|
||||||
color_filter: Option<Color>,
|
|
||||||
bounds: Rectangle,
|
|
||||||
rotation: core::Radians,
|
|
||||||
opacity: f32,
|
|
||||||
) {
|
|
||||||
let (layer, transformation) = self.layers.current_mut();
|
let (layer, transformation) = self.layers.current_mut();
|
||||||
layer.draw_svg(
|
layer.draw_svg(svg, bounds, transformation);
|
||||||
handle,
|
|
||||||
color_filter,
|
|
||||||
bounds,
|
|
||||||
transformation,
|
|
||||||
rotation,
|
|
||||||
opacity,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use crate::core::mouse;
|
||||||
use crate::core::renderer;
|
use crate::core::renderer;
|
||||||
use crate::core::widget::Tree;
|
use crate::core::widget::Tree;
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, ContentFit, Element, Layout, Length, Point, Rectangle, Rotation,
|
ContentFit, Element, Layout, Length, Point, Rectangle, Rotation, Size,
|
||||||
Size, Vector, Widget,
|
Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use image::{FilterMethod, Handle};
|
pub use image::{FilterMethod, Handle};
|
||||||
|
|
@ -181,7 +181,7 @@ pub fn draw<Renderer, Handle>(
|
||||||
|
|
||||||
let render = |renderer: &mut Renderer| {
|
let render = |renderer: &mut Renderer| {
|
||||||
renderer.draw_image(
|
renderer.draw_image(
|
||||||
core::Image {
|
image::Image {
|
||||||
handle: handle.clone(),
|
handle: handle.clone(),
|
||||||
filter_method,
|
filter_method,
|
||||||
rotation: rotation.radians(),
|
rotation: rotation.radians(),
|
||||||
|
|
|
||||||
|
|
@ -211,11 +211,13 @@ where
|
||||||
|
|
||||||
let render = |renderer: &mut Renderer| {
|
let render = |renderer: &mut Renderer| {
|
||||||
renderer.draw_svg(
|
renderer.draw_svg(
|
||||||
self.handle.clone(),
|
svg::Svg {
|
||||||
style.color,
|
handle: self.handle.clone(),
|
||||||
|
color: style.color,
|
||||||
|
rotation: self.rotation.radians(),
|
||||||
|
opacity: self.opacity,
|
||||||
|
},
|
||||||
drawing_bounds,
|
drawing_bounds,
|
||||||
self.rotation.radians(),
|
|
||||||
self.opacity,
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue