mirror of
https://github.com/penpot/penpot.git
synced 2025-05-13 14:26:40 +02:00
✨ Use skia matrix for internal data
This commit is contained in:
parent
4594c7bf0a
commit
3dcabc9502
13 changed files with 228 additions and 211 deletions
|
@ -19,6 +19,13 @@ impl RawStopData {
|
|||
pub fn offset(&self) -> f32 {
|
||||
self.offset as f32 / 100.0
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: [u8; 5]) -> Self {
|
||||
Self {
|
||||
color: [bytes[0], bytes[1], bytes[2], bytes[3]],
|
||||
offset: bytes[4],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
@ -37,7 +44,7 @@ impl Gradient {
|
|||
self.offsets.push(offset);
|
||||
}
|
||||
|
||||
fn to_linear_shader(&self, rect: &math::Rect) -> skia::Shader {
|
||||
fn to_linear_shader(&self, rect: &math::Rect) -> Option<skia::Shader> {
|
||||
let start = (
|
||||
rect.left + self.start.0 * rect.width(),
|
||||
rect.top + self.start.1 * rect.height(),
|
||||
|
@ -46,7 +53,7 @@ impl Gradient {
|
|||
rect.left + self.end.0 * rect.width(),
|
||||
rect.top + self.end.1 * rect.height(),
|
||||
);
|
||||
let shader = skia::shader::Shader::linear_gradient(
|
||||
skia::shader::Shader::linear_gradient(
|
||||
(start, end),
|
||||
self.colors.as_slice(),
|
||||
self.offsets.as_slice(),
|
||||
|
@ -54,11 +61,9 @@ impl Gradient {
|
|||
None,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
shader
|
||||
}
|
||||
|
||||
fn to_radial_shader(&self, rect: &math::Rect) -> skia::Shader {
|
||||
fn to_radial_shader(&self, rect: &math::Rect) -> Option<skia::Shader> {
|
||||
let center = skia::Point::new(
|
||||
rect.left + self.start.0 * rect.width(),
|
||||
rect.top + self.start.1 * rect.height(),
|
||||
|
@ -80,7 +85,7 @@ impl Gradient {
|
|||
transform.pre_scale((self.width * rect.width() / rect.height(), 1.), None);
|
||||
transform.pre_translate((-center.x, -center.y));
|
||||
|
||||
let shader = skia::shader::Shader::radial_gradient(
|
||||
skia::shader::Shader::radial_gradient(
|
||||
center,
|
||||
distance,
|
||||
self.colors.as_slice(),
|
||||
|
@ -89,8 +94,6 @@ impl Gradient {
|
|||
None,
|
||||
Some(&transform),
|
||||
)
|
||||
.unwrap();
|
||||
shader
|
||||
}
|
||||
}
|
||||
|
||||
|
|
40
render-wasm/src/shapes/modifiers.rs
Normal file
40
render-wasm/src/shapes/modifiers.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use skia_safe as skia;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::shapes::{Shape, TransformEntry};
|
||||
use crate::state::State;
|
||||
|
||||
fn propagate_shape(_state: &State, shape: &Shape, transform: skia::Matrix) -> Vec<TransformEntry> {
|
||||
let children: Vec<TransformEntry> = shape
|
||||
.children
|
||||
.iter()
|
||||
.map(|id| TransformEntry {
|
||||
id: id.clone(),
|
||||
transform,
|
||||
})
|
||||
.collect();
|
||||
|
||||
children
|
||||
}
|
||||
|
||||
pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec<TransformEntry> {
|
||||
let mut entries = modifiers.clone();
|
||||
let mut processed = HashSet::<Uuid>::new();
|
||||
let mut result = Vec::<TransformEntry>::new();
|
||||
|
||||
// Propagate the transform to children
|
||||
while let Some(entry) = entries.pop() {
|
||||
if !processed.contains(&entry.id) {
|
||||
if let Some(shape) = state.shapes.get(&entry.id) {
|
||||
let mut children = propagate_shape(state, shape, entry.transform);
|
||||
entries.append(&mut children);
|
||||
processed.insert(entry.id);
|
||||
result.push(entry.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
use skia_safe as skia;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::matrix::Matrix;
|
||||
use crate::mem::SerializableResult;
|
||||
use crate::utils::{uuid_from_u32_quartet, uuid_to_u32_quartet};
|
||||
use skia::Matrix;
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
#[repr(C)]
|
||||
|
@ -12,7 +13,7 @@ pub struct TransformEntry {
|
|||
}
|
||||
|
||||
impl SerializableResult for TransformEntry {
|
||||
type BytesType = [u8; size_of::<TransformEntry>()];
|
||||
type BytesType = [u8; 40];
|
||||
|
||||
fn from_bytes(bytes: Self::BytesType) -> Self {
|
||||
let id = uuid_from_u32_quartet(
|
||||
|
@ -22,26 +23,35 @@ impl SerializableResult for TransformEntry {
|
|||
u32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
|
||||
);
|
||||
|
||||
let transform = Matrix::new(
|
||||
let transform = Matrix::new_all(
|
||||
f32::from_le_bytes([bytes[16], bytes[17], bytes[18], bytes[19]]),
|
||||
f32::from_le_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]),
|
||||
f32::from_le_bytes([bytes[24], bytes[25], bytes[26], bytes[27]]),
|
||||
f32::from_le_bytes([bytes[28], bytes[29], bytes[30], bytes[31]]),
|
||||
f32::from_le_bytes([bytes[32], bytes[33], bytes[34], bytes[35]]),
|
||||
f32::from_le_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]),
|
||||
f32::from_le_bytes([bytes[28], bytes[29], bytes[30], bytes[31]]),
|
||||
f32::from_le_bytes([bytes[36], bytes[37], bytes[38], bytes[39]]),
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
);
|
||||
|
||||
TransformEntry { id, transform }
|
||||
}
|
||||
|
||||
fn as_bytes(&self) -> Self::BytesType {
|
||||
let mut result: [u8; 40] = [0; 40];
|
||||
let mut result: Self::BytesType = [0; 40];
|
||||
let (a, b, c, d) = uuid_to_u32_quartet(&self.id);
|
||||
result[0..4].clone_from_slice(&a.to_le_bytes());
|
||||
result[4..8].clone_from_slice(&b.to_le_bytes());
|
||||
result[8..12].clone_from_slice(&c.to_le_bytes());
|
||||
result[12..16].clone_from_slice(&d.to_le_bytes());
|
||||
result[16..40].clone_from_slice(&self.transform.as_bytes());
|
||||
|
||||
result[16..20].clone_from_slice(&self.transform[0].to_le_bytes());
|
||||
result[20..24].clone_from_slice(&self.transform[3].to_le_bytes());
|
||||
result[24..28].clone_from_slice(&self.transform[1].to_le_bytes());
|
||||
result[28..32].clone_from_slice(&self.transform[4].to_le_bytes());
|
||||
result[32..36].clone_from_slice(&self.transform[2].to_le_bytes());
|
||||
result[36..40].clone_from_slice(&self.transform[5].to_le_bytes());
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -61,7 +71,7 @@ mod tests {
|
|||
fn test_serialization() {
|
||||
let entry = TransformEntry {
|
||||
id: uuid!("550e8400-e29b-41d4-a716-446655440000"),
|
||||
transform: Matrix::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0),
|
||||
transform: Matrix::new_all(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 0.0, 0.0, 1.0),
|
||||
};
|
||||
|
||||
let bytes = entry.as_bytes();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue