Replace Primitive::Translate with Transform
This commit is contained in:
parent
759f0e9225
commit
5467c19c80
11 changed files with 205 additions and 133 deletions
|
|
@ -102,10 +102,10 @@ impl<T: Damage> Damage for Primitive<T> {
|
|||
.fold(Rectangle::with_size(Size::ZERO), |a, b| {
|
||||
Rectangle::union(&a, &b)
|
||||
}),
|
||||
Self::Translate {
|
||||
translation,
|
||||
Self::Transform {
|
||||
transformation,
|
||||
content,
|
||||
} => content.bounds() + *translation,
|
||||
} => content.bounds() * *transformation,
|
||||
Self::Cache { content } => content.bounds(),
|
||||
Self::Custom(custom) => custom.bounds(),
|
||||
}
|
||||
|
|
@ -144,19 +144,19 @@ fn regions<T: Damage>(a: &Primitive<T>, b: &Primitive<T>) -> Vec<Rectangle> {
|
|||
}
|
||||
}
|
||||
(
|
||||
Primitive::Translate {
|
||||
translation: translation_a,
|
||||
Primitive::Transform {
|
||||
transformation: transformation_a,
|
||||
content: content_a,
|
||||
},
|
||||
Primitive::Translate {
|
||||
translation: translation_b,
|
||||
Primitive::Transform {
|
||||
transformation: transformation_b,
|
||||
content: content_b,
|
||||
},
|
||||
) => {
|
||||
if translation_a == translation_b {
|
||||
if transformation_a == transformation_b {
|
||||
return regions(content_a, content_b)
|
||||
.into_iter()
|
||||
.map(|r| r + *translation_a)
|
||||
.map(|r| r * *transformation_a)
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::core::{
|
|||
};
|
||||
use crate::text::editor;
|
||||
use crate::text::paragraph;
|
||||
use crate::Transformation;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
@ -104,12 +105,12 @@ pub enum Primitive<T> {
|
|||
/// The content of the clip
|
||||
content: Box<Primitive<T>>,
|
||||
},
|
||||
/// A primitive that applies a translation
|
||||
Translate {
|
||||
/// The translation vector
|
||||
translation: Vector,
|
||||
/// A primitive that applies a [`Transformation`]
|
||||
Transform {
|
||||
/// The [`Transformation`]
|
||||
transformation: Transformation,
|
||||
|
||||
/// The primitive to translate
|
||||
/// The primitive to transform
|
||||
content: Box<Primitive<T>>,
|
||||
},
|
||||
/// A cached primitive.
|
||||
|
|
@ -125,12 +126,12 @@ pub enum Primitive<T> {
|
|||
}
|
||||
|
||||
impl<T> Primitive<T> {
|
||||
/// Creates a [`Primitive::Group`].
|
||||
/// Groups the current [`Primitive`].
|
||||
pub fn group(primitives: Vec<Self>) -> Self {
|
||||
Self::Group { primitives }
|
||||
}
|
||||
|
||||
/// Creates a [`Primitive::Clip`].
|
||||
/// Clips the current [`Primitive`].
|
||||
pub fn clip(self, bounds: Rectangle) -> Self {
|
||||
Self::Clip {
|
||||
bounds,
|
||||
|
|
@ -138,10 +139,21 @@ impl<T> Primitive<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a [`Primitive::Translate`].
|
||||
/// Translates the current [`Primitive`].
|
||||
pub fn translate(self, translation: Vector) -> Self {
|
||||
Self::Translate {
|
||||
translation,
|
||||
Self::Transform {
|
||||
transformation: Transformation::translate(
|
||||
translation.x,
|
||||
translation.y,
|
||||
),
|
||||
content: Box::new(self),
|
||||
}
|
||||
}
|
||||
|
||||
/// Transforms the current [`Primitive`].
|
||||
pub fn transform(self, transformation: Transformation) -> Self {
|
||||
Self::Transform {
|
||||
transformation,
|
||||
content: Box::new(self),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use glam::{Mat4, Vec3};
|
||||
use crate::core::{Point, Rectangle, Size, Vector};
|
||||
|
||||
use glam::{Mat4, Vec3, Vec4};
|
||||
use std::ops::Mul;
|
||||
|
||||
/// A 2D transformation matrix.
|
||||
|
|
@ -6,10 +8,8 @@ use std::ops::Mul;
|
|||
pub struct Transformation(Mat4);
|
||||
|
||||
impl Transformation {
|
||||
/// Get the identity transformation.
|
||||
pub fn identity() -> Transformation {
|
||||
Transformation(Mat4::IDENTITY)
|
||||
}
|
||||
/// A [`Transformation`] that preserves whatever is transformed.
|
||||
pub const IDENTITY: Self = Self(Mat4::IDENTITY);
|
||||
|
||||
/// Creates an orthographic projection.
|
||||
#[rustfmt::skip]
|
||||
|
|
@ -30,6 +30,26 @@ impl Transformation {
|
|||
pub fn scale(x: f32, y: f32) -> Transformation {
|
||||
Transformation(Mat4::from_scale(Vec3::new(x, y, 1.0)))
|
||||
}
|
||||
|
||||
/// The scale factor on the X axis.
|
||||
pub fn scale_x(&self) -> f32 {
|
||||
self.0.x_axis.x
|
||||
}
|
||||
|
||||
/// The scale factor on the Y axis.
|
||||
pub fn scale_y(&self) -> f32 {
|
||||
self.0.y_axis.y
|
||||
}
|
||||
|
||||
/// The translation on the X axis.
|
||||
pub fn translation_x(&self) -> f32 {
|
||||
self.0.w_axis.x
|
||||
}
|
||||
|
||||
/// The translation on the Y axis.
|
||||
pub fn translation_y(&self) -> f32 {
|
||||
self.0.w_axis.y
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for Transformation {
|
||||
|
|
@ -40,6 +60,56 @@ impl Mul for Transformation {
|
|||
}
|
||||
}
|
||||
|
||||
impl Mul<Transformation> for Point {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, transformation: Transformation) -> Self {
|
||||
let point = transformation
|
||||
.0
|
||||
.mul_vec4(Vec4::new(self.x, self.y, 1.0, 1.0));
|
||||
|
||||
Point::new(point.x, point.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Transformation> for Vector {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, transformation: Transformation) -> Self {
|
||||
let new_vector = transformation
|
||||
.0
|
||||
.mul_vec4(Vec4::new(self.x, self.y, 1.0, 0.0));
|
||||
|
||||
Vector::new(new_vector.x, new_vector.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Transformation> for Size {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, transformation: Transformation) -> Self {
|
||||
let new_size = transformation.0.mul_vec4(Vec4::new(
|
||||
self.width,
|
||||
self.height,
|
||||
1.0,
|
||||
0.0,
|
||||
));
|
||||
|
||||
Size::new(new_size.x, new_size.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Transformation> for Rectangle {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, transformation: Transformation) -> Self {
|
||||
let position = self.position();
|
||||
let size = self.size();
|
||||
|
||||
Self::new(position * transformation, size * transformation)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[f32; 16]> for Transformation {
|
||||
fn as_ref(&self) -> &[f32; 16] {
|
||||
self.0.as_ref()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use tiny_skia::Size;
|
|||
use crate::core::{Background, Color, Gradient, Rectangle, Vector};
|
||||
use crate::graphics::backend;
|
||||
use crate::graphics::text;
|
||||
use crate::graphics::Viewport;
|
||||
use crate::graphics::{Transformation, Viewport};
|
||||
use crate::primitive::{self, Primitive};
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
|
@ -106,7 +106,7 @@ impl Backend {
|
|||
clip_mask,
|
||||
region,
|
||||
scale_factor,
|
||||
Vector::ZERO,
|
||||
Transformation::IDENTITY,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ impl Backend {
|
|||
clip_mask: &mut tiny_skia::Mask,
|
||||
clip_bounds: Rectangle,
|
||||
scale_factor: f32,
|
||||
translation: Vector,
|
||||
transformation: Transformation,
|
||||
) {
|
||||
match primitive {
|
||||
Primitive::Quad {
|
||||
|
|
@ -164,7 +164,7 @@ impl Backend {
|
|||
"Quad with non-normal height!"
|
||||
);
|
||||
|
||||
let physical_bounds = (*bounds + translation) * scale_factor;
|
||||
let physical_bounds = (*bounds * transformation) * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -173,11 +173,8 @@ impl Backend {
|
|||
let clip_mask = (!physical_bounds.is_within(&clip_bounds))
|
||||
.then_some(clip_mask as &_);
|
||||
|
||||
let transform = tiny_skia::Transform::from_translate(
|
||||
translation.x,
|
||||
translation.y,
|
||||
)
|
||||
.post_scale(scale_factor, scale_factor);
|
||||
let transform = into_transform(transformation)
|
||||
.post_scale(scale_factor, scale_factor);
|
||||
|
||||
// Make sure the border radius is not larger than the bounds
|
||||
let border_width = border
|
||||
|
|
@ -199,7 +196,7 @@ impl Backend {
|
|||
y: bounds.y + shadow.offset.y - shadow.blur_radius,
|
||||
width: bounds.width + shadow.blur_radius * 2.0,
|
||||
height: bounds.height + shadow.blur_radius * 2.0,
|
||||
} + translation)
|
||||
} * transformation)
|
||||
* scale_factor;
|
||||
|
||||
let radii = fill_border_radius
|
||||
|
|
@ -451,7 +448,7 @@ impl Backend {
|
|||
clip_bounds: text_clip_bounds,
|
||||
} => {
|
||||
let physical_bounds =
|
||||
(*text_clip_bounds + translation) * scale_factor;
|
||||
*text_clip_bounds * transformation * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -462,7 +459,7 @@ impl Backend {
|
|||
|
||||
self.text_pipeline.draw_paragraph(
|
||||
paragraph,
|
||||
*position + translation,
|
||||
*position * transformation,
|
||||
*color,
|
||||
scale_factor,
|
||||
pixels,
|
||||
|
|
@ -476,7 +473,7 @@ impl Backend {
|
|||
clip_bounds: text_clip_bounds,
|
||||
} => {
|
||||
let physical_bounds =
|
||||
(*text_clip_bounds + translation) * scale_factor;
|
||||
(*text_clip_bounds * transformation) * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -487,7 +484,7 @@ impl Backend {
|
|||
|
||||
self.text_pipeline.draw_editor(
|
||||
editor,
|
||||
*position + translation,
|
||||
*position * transformation,
|
||||
*color,
|
||||
scale_factor,
|
||||
pixels,
|
||||
|
|
@ -507,7 +504,7 @@ impl Backend {
|
|||
clip_bounds: text_clip_bounds,
|
||||
} => {
|
||||
let physical_bounds =
|
||||
(*text_clip_bounds + translation) * scale_factor;
|
||||
*text_clip_bounds * transformation * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -518,7 +515,7 @@ impl Backend {
|
|||
|
||||
self.text_pipeline.draw_cached(
|
||||
content,
|
||||
*bounds + translation,
|
||||
*bounds * transformation,
|
||||
*color,
|
||||
*size,
|
||||
*line_height,
|
||||
|
|
@ -542,7 +539,7 @@ impl Backend {
|
|||
};
|
||||
|
||||
let physical_bounds =
|
||||
(*text_clip_bounds + translation) * scale_factor;
|
||||
*text_clip_bounds * transformation * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -553,7 +550,7 @@ impl Backend {
|
|||
|
||||
self.text_pipeline.draw_raw(
|
||||
&buffer,
|
||||
*position + translation,
|
||||
*position * transformation,
|
||||
*color,
|
||||
scale_factor,
|
||||
pixels,
|
||||
|
|
@ -566,7 +563,7 @@ impl Backend {
|
|||
filter_method,
|
||||
bounds,
|
||||
} => {
|
||||
let physical_bounds = (*bounds + translation) * scale_factor;
|
||||
let physical_bounds = (*bounds * transformation) * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -575,11 +572,8 @@ impl Backend {
|
|||
let clip_mask = (!physical_bounds.is_within(&clip_bounds))
|
||||
.then_some(clip_mask as &_);
|
||||
|
||||
let transform = tiny_skia::Transform::from_translate(
|
||||
translation.x,
|
||||
translation.y,
|
||||
)
|
||||
.post_scale(scale_factor, scale_factor);
|
||||
let transform = into_transform(transformation)
|
||||
.post_scale(scale_factor, scale_factor);
|
||||
|
||||
self.raster_pipeline.draw(
|
||||
handle,
|
||||
|
|
@ -602,7 +596,7 @@ impl Backend {
|
|||
bounds,
|
||||
color,
|
||||
} => {
|
||||
let physical_bounds = (*bounds + translation) * scale_factor;
|
||||
let physical_bounds = (*bounds * transformation) * scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
|
|
@ -614,7 +608,7 @@ impl Backend {
|
|||
self.vector_pipeline.draw(
|
||||
handle,
|
||||
*color,
|
||||
(*bounds + translation) * scale_factor,
|
||||
(*bounds * transformation) * scale_factor,
|
||||
pixels,
|
||||
clip_mask,
|
||||
);
|
||||
|
|
@ -637,7 +631,7 @@ impl Backend {
|
|||
y: bounds.y(),
|
||||
width: bounds.width(),
|
||||
height: bounds.height(),
|
||||
} + translation)
|
||||
} * transformation)
|
||||
* scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
|
|
@ -651,11 +645,8 @@ impl Backend {
|
|||
path,
|
||||
paint,
|
||||
*rule,
|
||||
tiny_skia::Transform::from_translate(
|
||||
translation.x,
|
||||
translation.y,
|
||||
)
|
||||
.post_scale(scale_factor, scale_factor),
|
||||
into_transform(transformation)
|
||||
.post_scale(scale_factor, scale_factor),
|
||||
clip_mask,
|
||||
);
|
||||
}
|
||||
|
|
@ -671,7 +662,7 @@ impl Backend {
|
|||
y: bounds.y(),
|
||||
width: bounds.width(),
|
||||
height: bounds.height(),
|
||||
} + translation)
|
||||
} * transformation)
|
||||
* scale_factor;
|
||||
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
|
|
@ -685,11 +676,8 @@ impl Backend {
|
|||
path,
|
||||
paint,
|
||||
stroke,
|
||||
tiny_skia::Transform::from_translate(
|
||||
translation.x,
|
||||
translation.y,
|
||||
)
|
||||
.post_scale(scale_factor, scale_factor),
|
||||
into_transform(transformation)
|
||||
.post_scale(scale_factor, scale_factor),
|
||||
clip_mask,
|
||||
);
|
||||
}
|
||||
|
|
@ -701,12 +689,12 @@ impl Backend {
|
|||
clip_mask,
|
||||
clip_bounds,
|
||||
scale_factor,
|
||||
translation,
|
||||
transformation,
|
||||
);
|
||||
}
|
||||
}
|
||||
Primitive::Translate {
|
||||
translation: offset,
|
||||
Primitive::Transform {
|
||||
transformation: new_transformation,
|
||||
content,
|
||||
} => {
|
||||
self.draw_primitive(
|
||||
|
|
@ -715,11 +703,11 @@ impl Backend {
|
|||
clip_mask,
|
||||
clip_bounds,
|
||||
scale_factor,
|
||||
translation + *offset,
|
||||
transformation * *new_transformation,
|
||||
);
|
||||
}
|
||||
Primitive::Clip { bounds, content } => {
|
||||
let bounds = (*bounds + translation) * scale_factor;
|
||||
let bounds = (*bounds * transformation) * scale_factor;
|
||||
|
||||
if bounds == clip_bounds {
|
||||
self.draw_primitive(
|
||||
|
|
@ -728,7 +716,7 @@ impl Backend {
|
|||
clip_mask,
|
||||
bounds,
|
||||
scale_factor,
|
||||
translation,
|
||||
transformation,
|
||||
);
|
||||
} else if let Some(bounds) = clip_bounds.intersection(&bounds) {
|
||||
if bounds.x + bounds.width <= 0.0
|
||||
|
|
@ -749,7 +737,7 @@ impl Backend {
|
|||
clip_mask,
|
||||
bounds,
|
||||
scale_factor,
|
||||
translation,
|
||||
transformation,
|
||||
);
|
||||
|
||||
adjust_clip_mask(clip_mask, clip_bounds);
|
||||
|
|
@ -762,7 +750,7 @@ impl Backend {
|
|||
clip_mask,
|
||||
clip_bounds,
|
||||
scale_factor,
|
||||
translation,
|
||||
transformation,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -780,6 +768,17 @@ fn into_color(color: Color) -> tiny_skia::Color {
|
|||
.expect("Convert color from iced to tiny_skia")
|
||||
}
|
||||
|
||||
fn into_transform(transformation: Transformation) -> tiny_skia::Transform {
|
||||
tiny_skia::Transform {
|
||||
sx: transformation.scale_x(),
|
||||
kx: 0.0,
|
||||
ky: 0.0,
|
||||
sy: transformation.scale_y(),
|
||||
tx: transformation.translation_x(),
|
||||
ty: transformation.translation_y(),
|
||||
}
|
||||
}
|
||||
|
||||
fn rounded_rectangle(
|
||||
bounds: Rectangle,
|
||||
border_radius: [f32; 4],
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::core::{Pixels, Point, Rectangle, Size, Vector};
|
|||
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::{Gradient, Transformation};
|
||||
use crate::primitive::{self, Primitive};
|
||||
|
||||
pub struct Frame {
|
||||
|
|
@ -181,8 +181,8 @@ impl Frame {
|
|||
}
|
||||
|
||||
pub fn clip(&mut self, frame: Self, at: Point) {
|
||||
self.primitives.push(Primitive::Translate {
|
||||
translation: Vector::new(at.x, at.y),
|
||||
self.primitives.push(Primitive::Transform {
|
||||
transformation: Transformation::translate(at.x, at.y),
|
||||
content: Box::new(frame.into_primitive()),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::graphics::geometry::{
|
|||
};
|
||||
use crate::graphics::gradient::{self, Gradient};
|
||||
use crate::graphics::mesh::{self, Mesh};
|
||||
use crate::graphics::Transformation;
|
||||
use crate::primitive::{self, Primitive};
|
||||
|
||||
use lyon::geom::euclid;
|
||||
|
|
@ -435,7 +436,7 @@ impl Frame {
|
|||
pub fn clip(&mut self, frame: Frame, at: Point) {
|
||||
let size = frame.size();
|
||||
let primitives = frame.into_primitives();
|
||||
let translation = Vector::new(at.x, at.y);
|
||||
let transformation = Transformation::translate(at.x, at.y);
|
||||
|
||||
let (text, meshes) = primitives
|
||||
.into_iter()
|
||||
|
|
@ -443,12 +444,12 @@ impl Frame {
|
|||
|
||||
self.primitives.push(Primitive::Group {
|
||||
primitives: vec![
|
||||
Primitive::Translate {
|
||||
translation,
|
||||
Primitive::Transform {
|
||||
transformation,
|
||||
content: Box::new(Primitive::Group { primitives: meshes }),
|
||||
},
|
||||
Primitive::Translate {
|
||||
translation,
|
||||
Primitive::Transform {
|
||||
transformation,
|
||||
content: Box::new(Primitive::Clip {
|
||||
bounds: Rectangle::with_size(size),
|
||||
content: Box::new(Primitive::Group {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::core::alignment;
|
|||
use crate::core::{Color, Font, Pixels, Point, Rectangle, Size, Vector};
|
||||
use crate::graphics;
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::Viewport;
|
||||
use crate::graphics::{Transformation, Viewport};
|
||||
use crate::primitive::{self, Primitive};
|
||||
use crate::quad::{self, Quad};
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ impl<'a> Layer<'a> {
|
|||
for primitive in primitives {
|
||||
Self::process_primitive(
|
||||
&mut layers,
|
||||
Vector::new(0.0, 0.0),
|
||||
Transformation::IDENTITY,
|
||||
primitive,
|
||||
0,
|
||||
);
|
||||
|
|
@ -115,7 +115,7 @@ impl<'a> Layer<'a> {
|
|||
|
||||
fn process_primitive(
|
||||
layers: &mut Vec<Self>,
|
||||
translation: Vector,
|
||||
transformation: Transformation,
|
||||
primitive: &'a Primitive,
|
||||
current_layer: usize,
|
||||
) {
|
||||
|
|
@ -130,9 +130,10 @@ impl<'a> Layer<'a> {
|
|||
|
||||
layer.text.push(Text::Paragraph {
|
||||
paragraph: paragraph.clone(),
|
||||
position: *position + translation,
|
||||
position: *position * transformation,
|
||||
color: *color,
|
||||
clip_bounds: *clip_bounds + translation,
|
||||
clip_bounds: *clip_bounds * transformation,
|
||||
scale: transformation.scale_y(),
|
||||
});
|
||||
}
|
||||
Primitive::Editor {
|
||||
|
|
@ -145,9 +146,10 @@ impl<'a> Layer<'a> {
|
|||
|
||||
layer.text.push(Text::Editor {
|
||||
editor: editor.clone(),
|
||||
position: *position + translation,
|
||||
position: *position * transformation,
|
||||
color: *color,
|
||||
clip_bounds: *clip_bounds + translation,
|
||||
clip_bounds: *clip_bounds * transformation,
|
||||
scale: transformation.scale_y(),
|
||||
});
|
||||
}
|
||||
Primitive::Text {
|
||||
|
|
@ -166,7 +168,7 @@ impl<'a> Layer<'a> {
|
|||
|
||||
layer.text.push(Text::Cached(text::Cached {
|
||||
content,
|
||||
bounds: *bounds + translation,
|
||||
bounds: *bounds * transformation,
|
||||
size: *size,
|
||||
line_height: *line_height,
|
||||
color: *color,
|
||||
|
|
@ -174,7 +176,7 @@ impl<'a> Layer<'a> {
|
|||
horizontal_alignment: *horizontal_alignment,
|
||||
vertical_alignment: *vertical_alignment,
|
||||
shaping: *shaping,
|
||||
clip_bounds: *clip_bounds + translation,
|
||||
clip_bounds: *clip_bounds * transformation,
|
||||
}));
|
||||
}
|
||||
graphics::Primitive::RawText(graphics::text::Raw {
|
||||
|
|
@ -187,9 +189,9 @@ impl<'a> Layer<'a> {
|
|||
|
||||
layer.text.push(Text::Raw(graphics::text::Raw {
|
||||
buffer: buffer.clone(),
|
||||
position: *position + translation,
|
||||
position: *position * transformation,
|
||||
color: *color,
|
||||
clip_bounds: *clip_bounds + translation,
|
||||
clip_bounds: *clip_bounds * transformation,
|
||||
}));
|
||||
}
|
||||
Primitive::Quad {
|
||||
|
|
@ -199,12 +201,10 @@ impl<'a> Layer<'a> {
|
|||
shadow,
|
||||
} => {
|
||||
let layer = &mut layers[current_layer];
|
||||
let bounds = *bounds * transformation;
|
||||
|
||||
let quad = Quad {
|
||||
position: [
|
||||
bounds.x + translation.x,
|
||||
bounds.y + translation.y,
|
||||
],
|
||||
position: [bounds.x, bounds.y],
|
||||
size: [bounds.width, bounds.height],
|
||||
border_color: color::pack(border.color),
|
||||
border_radius: border.radius.into(),
|
||||
|
|
@ -226,7 +226,7 @@ impl<'a> Layer<'a> {
|
|||
layer.images.push(Image::Raster {
|
||||
handle: handle.clone(),
|
||||
filter_method: *filter_method,
|
||||
bounds: *bounds + translation,
|
||||
bounds: *bounds * transformation,
|
||||
});
|
||||
}
|
||||
Primitive::Svg {
|
||||
|
|
@ -239,7 +239,7 @@ impl<'a> Layer<'a> {
|
|||
layer.images.push(Image::Vector {
|
||||
handle: handle.clone(),
|
||||
color: *color,
|
||||
bounds: *bounds + translation,
|
||||
bounds: *bounds * transformation,
|
||||
});
|
||||
}
|
||||
Primitive::Group { primitives } => {
|
||||
|
|
@ -247,7 +247,7 @@ impl<'a> Layer<'a> {
|
|||
for primitive in primitives {
|
||||
Self::process_primitive(
|
||||
layers,
|
||||
translation,
|
||||
transformation,
|
||||
primitive,
|
||||
current_layer,
|
||||
);
|
||||
|
|
@ -255,7 +255,7 @@ impl<'a> Layer<'a> {
|
|||
}
|
||||
Primitive::Clip { bounds, content } => {
|
||||
let layer = &mut layers[current_layer];
|
||||
let translated_bounds = *bounds + translation;
|
||||
let translated_bounds = *bounds * transformation;
|
||||
|
||||
// Only draw visible content
|
||||
if let Some(clip_bounds) =
|
||||
|
|
@ -266,19 +266,19 @@ impl<'a> Layer<'a> {
|
|||
|
||||
Self::process_primitive(
|
||||
layers,
|
||||
translation,
|
||||
transformation,
|
||||
content,
|
||||
layers.len() - 1,
|
||||
);
|
||||
}
|
||||
}
|
||||
Primitive::Translate {
|
||||
translation: new_translation,
|
||||
Primitive::Transform {
|
||||
transformation: new_transformation,
|
||||
content,
|
||||
} => {
|
||||
Self::process_primitive(
|
||||
layers,
|
||||
translation + *new_translation,
|
||||
transformation * *new_transformation,
|
||||
content,
|
||||
current_layer,
|
||||
);
|
||||
|
|
@ -286,7 +286,7 @@ impl<'a> Layer<'a> {
|
|||
Primitive::Cache { content } => {
|
||||
Self::process_primitive(
|
||||
layers,
|
||||
translation,
|
||||
transformation,
|
||||
content,
|
||||
current_layer,
|
||||
);
|
||||
|
|
@ -296,20 +296,15 @@ impl<'a> Layer<'a> {
|
|||
graphics::Mesh::Solid { buffers, size } => {
|
||||
let layer = &mut layers[current_layer];
|
||||
|
||||
let bounds = Rectangle::new(
|
||||
Point::new(translation.x, translation.y),
|
||||
*size,
|
||||
);
|
||||
let bounds =
|
||||
Rectangle::with_size(*size) * transformation;
|
||||
|
||||
// Only draw visible content
|
||||
if let Some(clip_bounds) =
|
||||
layer.bounds.intersection(&bounds)
|
||||
{
|
||||
layer.meshes.push(Mesh::Solid {
|
||||
origin: Point::new(
|
||||
translation.x,
|
||||
translation.y,
|
||||
),
|
||||
transformation,
|
||||
buffers,
|
||||
clip_bounds,
|
||||
});
|
||||
|
|
@ -318,20 +313,15 @@ impl<'a> Layer<'a> {
|
|||
graphics::Mesh::Gradient { buffers, size } => {
|
||||
let layer = &mut layers[current_layer];
|
||||
|
||||
let bounds = Rectangle::new(
|
||||
Point::new(translation.x, translation.y),
|
||||
*size,
|
||||
);
|
||||
let bounds =
|
||||
Rectangle::with_size(*size) * transformation;
|
||||
|
||||
// Only draw visible content
|
||||
if let Some(clip_bounds) =
|
||||
layer.bounds.intersection(&bounds)
|
||||
{
|
||||
layer.meshes.push(Mesh::Gradient {
|
||||
origin: Point::new(
|
||||
translation.x,
|
||||
translation.y,
|
||||
),
|
||||
transformation,
|
||||
buffers,
|
||||
clip_bounds,
|
||||
});
|
||||
|
|
@ -340,7 +330,7 @@ impl<'a> Layer<'a> {
|
|||
},
|
||||
primitive::Custom::Pipeline(pipeline) => {
|
||||
let layer = &mut layers[current_layer];
|
||||
let bounds = pipeline.bounds + translation;
|
||||
let bounds = pipeline.bounds * transformation;
|
||||
|
||||
if let Some(clip_bounds) =
|
||||
layer.bounds.intersection(&bounds)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
//! A collection of triangle primitives.
|
||||
use crate::core::{Point, Rectangle};
|
||||
use crate::core::Rectangle;
|
||||
use crate::graphics::mesh;
|
||||
use crate::graphics::Transformation;
|
||||
|
||||
/// A mesh of triangles.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Mesh<'a> {
|
||||
/// A mesh of triangles with a solid color.
|
||||
Solid {
|
||||
/// The origin of the vertices of the [`Mesh`].
|
||||
origin: Point,
|
||||
/// The [`Transformation`] for the vertices of the [`Mesh`].
|
||||
transformation: Transformation,
|
||||
|
||||
/// The vertex and index buffers of the [`Mesh`].
|
||||
buffers: &'a mesh::Indexed<mesh::SolidVertex2D>,
|
||||
|
|
@ -18,8 +19,8 @@ pub enum Mesh<'a> {
|
|||
},
|
||||
/// A mesh of triangles with a gradient color.
|
||||
Gradient {
|
||||
/// The origin of the vertices of the [`Mesh`].
|
||||
origin: Point,
|
||||
/// The [`Transformation`] for the vertices of the [`Mesh`].
|
||||
transformation: Transformation,
|
||||
|
||||
/// The vertex and index buffers of the [`Mesh`].
|
||||
buffers: &'a mesh::Indexed<mesh::GradientVertex2D>,
|
||||
|
|
@ -31,11 +32,10 @@ pub enum Mesh<'a> {
|
|||
|
||||
impl Mesh<'_> {
|
||||
/// Returns the origin of the [`Mesh`].
|
||||
pub fn origin(&self) -> Point {
|
||||
pub fn transformation(&self) -> Transformation {
|
||||
match self {
|
||||
Self::Solid { origin, .. } | Self::Gradient { origin, .. } => {
|
||||
*origin
|
||||
}
|
||||
Self::Solid { transformation, .. }
|
||||
| Self::Gradient { transformation, .. } => *transformation,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ pub enum Text<'a> {
|
|||
position: Point,
|
||||
color: Color,
|
||||
clip_bounds: Rectangle,
|
||||
scale: f32,
|
||||
},
|
||||
/// An editor.
|
||||
#[allow(missing_docs)]
|
||||
|
|
@ -23,6 +24,7 @@ pub enum Text<'a> {
|
|||
position: Point,
|
||||
color: Color,
|
||||
clip_bounds: Rectangle,
|
||||
scale: f32,
|
||||
},
|
||||
/// Some cached text.
|
||||
Cached(Cached<'a>),
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ impl Uniforms {
|
|||
impl Default for Uniforms {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
transform: *Transformation::identity().as_ref(),
|
||||
transform: *Transformation::IDENTITY.as_ref(),
|
||||
scale: 1.0,
|
||||
_padding: [0.0; 3],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,12 +98,10 @@ impl Layer {
|
|||
let mut index_offset = 0;
|
||||
|
||||
for mesh in meshes {
|
||||
let origin = mesh.origin();
|
||||
let indices = mesh.indices();
|
||||
|
||||
let uniforms = Uniforms::new(
|
||||
transformation * Transformation::translate(origin.x, origin.y),
|
||||
);
|
||||
let uniforms =
|
||||
Uniforms::new(transformation * mesh.transformation());
|
||||
|
||||
index_offset +=
|
||||
self.index_buffer.write(queue, index_offset, indices);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue