mirror of
https://github.com/penpot/penpot.git
synced 2026-09-01 01:28:41 +00:00
Merge pull request #5920 from penpot/alotor-test-apply-modifiers
✨ Modify shapes geometry instead of transformation matrix
This commit is contained in:
commit
7470fb709f
@ -221,8 +221,7 @@
|
|||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
(aget buffer 1)
|
(aget buffer 1)
|
||||||
(aget buffer 2)
|
(aget buffer 2)
|
||||||
(aget buffer 3)
|
(aget buffer 3))
|
||||||
image-size)
|
|
||||||
true))))))
|
true))))))
|
||||||
|
|
||||||
(defn set-shape-fills
|
(defn set-shape-fills
|
||||||
|
|||||||
@ -332,21 +332,19 @@ pub extern "C" fn store_font(family_name_size: u32, font_size: u32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn store_image(a: u32, b: u32, c: u32, d: u32, size: u32) {
|
pub extern "C" fn store_image(a: u32, b: u32, c: u32, d: u32) {
|
||||||
let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer");
|
let state = unsafe { STATE.as_mut() }.expect("Got an invalid state pointer");
|
||||||
let id = uuid_from_u32_quartet(a, b, c, d);
|
let id = uuid_from_u32_quartet(a, b, c, d);
|
||||||
|
let image_bytes = mem::bytes();
|
||||||
|
|
||||||
unsafe {
|
match state.render_state().add_image(id, &image_bytes) {
|
||||||
let image_bytes =
|
Err(msg) => {
|
||||||
Vec::<u8>::from_raw_parts(mem::buffer_ptr(), size as usize, size as usize);
|
eprintln!("{}", msg);
|
||||||
match state.render_state().add_image(id, &image_bytes) {
|
|
||||||
Err(msg) => {
|
|
||||||
eprintln!("{}", msg);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
mem::free_bytes();
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mem::free_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@ -297,24 +297,28 @@ impl RenderState {
|
|||||||
|
|
||||||
self.drawing_surface
|
self.drawing_surface
|
||||||
.canvas()
|
.canvas()
|
||||||
.concat(&transform.invert().unwrap());
|
.concat(&transform.invert().unwrap_or(Matrix::default()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone so we don't change the value in the global state
|
||||||
|
let mut shape = shape.clone();
|
||||||
|
|
||||||
|
if let Some(modifiers) = modifiers {
|
||||||
|
shape.apply_transform(&modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
let center = shape.center();
|
let center = shape.center();
|
||||||
|
|
||||||
// Transform the shape in the center
|
let mut matrix = shape.transform;
|
||||||
let mut matrix = shape.transform.clone();
|
|
||||||
matrix.post_translate(center);
|
matrix.post_translate(center);
|
||||||
matrix.pre_translate(-center);
|
matrix.pre_translate(-center);
|
||||||
|
|
||||||
if let Some(modifiers) = modifiers {
|
|
||||||
matrix.post_concat(&modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.drawing_surface.canvas().concat(&matrix);
|
|
||||||
|
|
||||||
match &shape.kind {
|
match &shape.kind {
|
||||||
Kind::SVGRaw(sr) => {
|
Kind::SVGRaw(sr) => {
|
||||||
|
if let Some(modifiers) = modifiers {
|
||||||
|
self.drawing_surface.canvas().concat(&modifiers);
|
||||||
|
}
|
||||||
|
self.drawing_surface.canvas().concat(&matrix);
|
||||||
if let Some(svg) = shape.svg.as_ref() {
|
if let Some(svg) = shape.svg.as_ref() {
|
||||||
svg.render(self.drawing_surface.canvas())
|
svg.render(self.drawing_surface.canvas())
|
||||||
} else {
|
} else {
|
||||||
@ -332,12 +336,14 @@ impl RenderState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
self.drawing_surface.canvas().concat(&matrix);
|
||||||
|
|
||||||
for fill in shape.fills().rev() {
|
for fill in shape.fills().rev() {
|
||||||
fills::render(self, shape, fill);
|
fills::render(self, &shape, fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
for stroke in shape.strokes().rev() {
|
for stroke in shape.strokes().rev() {
|
||||||
strokes::render(self, shape, stroke);
|
strokes::render(self, &shape, stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
for shadow in shape.inner_shadows().rev().filter(|s| !s.hidden()) {
|
for shadow in shape.inner_shadows().rev().filter(|s| !s.hidden()) {
|
||||||
|
|||||||
@ -348,24 +348,29 @@ impl Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_corners(&mut self, raw_corners: (f32, f32, f32, f32)) {
|
pub fn set_corners(&mut self, raw_corners: (f32, f32, f32, f32)) {
|
||||||
let (r1, r2, r3, r4) = raw_corners;
|
match self.kind {
|
||||||
let are_straight_corners = r1.abs() <= f32::EPSILON
|
Kind::Rect(_, _) => {
|
||||||
&& r2.abs() <= f32::EPSILON
|
let (r1, r2, r3, r4) = raw_corners;
|
||||||
&& r3.abs() <= f32::EPSILON
|
let are_straight_corners = r1.abs() <= f32::EPSILON
|
||||||
&& r4.abs() <= f32::EPSILON;
|
&& r2.abs() <= f32::EPSILON
|
||||||
|
&& r3.abs() <= f32::EPSILON
|
||||||
|
&& r4.abs() <= f32::EPSILON;
|
||||||
|
|
||||||
let corners = if are_straight_corners {
|
let corners = if are_straight_corners {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some([
|
Some([
|
||||||
(r1, r1).into(),
|
(r1, r1).into(),
|
||||||
(r2, r2).into(),
|
(r2, r2).into(),
|
||||||
(r3, r3).into(),
|
(r3, r3).into(),
|
||||||
(r4, r4).into(),
|
(r4, r4).into(),
|
||||||
])
|
])
|
||||||
};
|
};
|
||||||
|
|
||||||
self.kind = Kind::Rect(self.selrect, corners);
|
self.kind = Kind::Rect(self.selrect, corners);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_svg(&mut self, svg: skia::svg::Dom) {
|
pub fn set_svg(&mut self, svg: skia::svg::Dom) {
|
||||||
@ -494,6 +499,52 @@ impl Shape {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transform_selrect(&mut self, transform: &Matrix) {
|
||||||
|
let mut center = self.selrect.center();
|
||||||
|
center = transform.map_point(center);
|
||||||
|
|
||||||
|
let bounds = self.bounds().transform(&transform);
|
||||||
|
self.transform = bounds.transform_matrix().unwrap_or(Matrix::default());
|
||||||
|
|
||||||
|
let width = bounds.width();
|
||||||
|
let height = bounds.height();
|
||||||
|
|
||||||
|
self.selrect = Rect::from_xywh(
|
||||||
|
center.x - width / 2.0,
|
||||||
|
center.y - height / 2.0,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_transform(&mut self, transform: &Matrix) {
|
||||||
|
match &self.kind {
|
||||||
|
Kind::Rect(_, c) => {
|
||||||
|
let c = c.clone();
|
||||||
|
self.transform_selrect(&transform);
|
||||||
|
self.kind = Kind::Rect(self.selrect, c);
|
||||||
|
}
|
||||||
|
Kind::Circle(_) => {
|
||||||
|
self.transform_selrect(&transform);
|
||||||
|
self.kind = Kind::Circle(self.selrect);
|
||||||
|
}
|
||||||
|
Kind::Path(path) => {
|
||||||
|
let mut path = path.clone();
|
||||||
|
self.transform_selrect(&transform);
|
||||||
|
path.transform(&transform);
|
||||||
|
self.kind = Kind::Path(path);
|
||||||
|
}
|
||||||
|
Kind::Bool(bool_type, path) => {
|
||||||
|
let bool_type = *bool_type;
|
||||||
|
let mut path = path.clone();
|
||||||
|
self.transform_selrect(&transform);
|
||||||
|
path.transform(&transform);
|
||||||
|
self.kind = Kind::Bool(bool_type, path);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -512,4 +563,21 @@ mod tests {
|
|||||||
shape.add_fill(Fill::Solid(Color::TRANSPARENT));
|
shape.add_fill(Fill::Solid(Color::TRANSPARENT));
|
||||||
assert_eq!(shape.fills.get(0), Some(&Fill::Solid(Color::TRANSPARENT)))
|
assert_eq!(shape.fills.get(0), Some(&Fill::Solid(Color::TRANSPARENT)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_apply_transform() {
|
||||||
|
let mut shape = Shape::new(Uuid::new_v4());
|
||||||
|
shape.set_shape_type(Type::Rect);
|
||||||
|
shape.set_selrect(0.0, 10.0, 10.0, 0.0);
|
||||||
|
shape.apply_transform(Matrix::scale((2.0, 2.0)));
|
||||||
|
|
||||||
|
match shape.kind {
|
||||||
|
Kind::Rect(r, _) => {
|
||||||
|
//println!(">>>{r:?}");
|
||||||
|
assert_eq!(r.width(), 20.0);
|
||||||
|
assert_eq!(r.height(), 20.0);
|
||||||
|
}
|
||||||
|
_ => assert!(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use skia_safe as skia;
|
use skia_safe::{self as skia, Matrix};
|
||||||
use std::array::TryFromSliceError;
|
use std::array::TryFromSliceError;
|
||||||
|
|
||||||
type Point = (f32, f32);
|
type Point = (f32, f32);
|
||||||
@ -144,4 +144,8 @@ impl Path {
|
|||||||
pub fn is_open(&self) -> bool {
|
pub fn is_open(&self) -> bool {
|
||||||
self.open
|
self.open
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn transform(&mut self, mtx: &Matrix) {
|
||||||
|
self.skia_path.transform(mtx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user