mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
✨ Add scale_content to shapes_pool
This commit is contained in:
@@ -982,10 +982,6 @@
|
|||||||
[]
|
[]
|
||||||
(h/call wasm/internal-module "_clean_modifiers"))
|
(h/call wasm/internal-module "_clean_modifiers"))
|
||||||
|
|
||||||
(defn clean-geometry-modifiers
|
|
||||||
[]
|
|
||||||
(h/call wasm/internal-module "_clean_geometry_modifiers"))
|
|
||||||
|
|
||||||
(defn set-modifiers
|
(defn set-modifiers
|
||||||
[modifiers]
|
[modifiers]
|
||||||
|
|
||||||
|
|||||||
@@ -541,6 +541,7 @@ pub extern "C" fn set_structure_modifiers() {
|
|||||||
|
|
||||||
with_state_mut!(state, {
|
with_state_mut!(state, {
|
||||||
let mut structure = HashMap::new();
|
let mut structure = HashMap::new();
|
||||||
|
let mut scale_content = HashMap::new();
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
match entry.entry_type {
|
match entry.entry_type {
|
||||||
StructureEntryType::ScaleContent => {
|
StructureEntryType::ScaleContent => {
|
||||||
@@ -548,7 +549,7 @@ pub extern "C" fn set_structure_modifiers() {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for id in shape.all_children(&state.shapes, true, true) {
|
for id in shape.all_children(&state.shapes, true, true) {
|
||||||
state.scale_content.insert(id, entry.value);
|
scale_content.insert(id, entry.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -560,6 +561,9 @@ pub extern "C" fn set_structure_modifiers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !scale_content.is_empty() {
|
||||||
|
state.shapes.set_scale_content(scale_content);
|
||||||
|
}
|
||||||
if !structure.is_empty() {
|
if !structure.is_empty() {
|
||||||
state.shapes.set_structure(structure);
|
state.shapes.set_structure(structure);
|
||||||
}
|
}
|
||||||
@@ -571,16 +575,7 @@ pub extern "C" fn set_structure_modifiers() {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn clean_modifiers() {
|
pub extern "C" fn clean_modifiers() {
|
||||||
with_state_mut!(state, {
|
with_state_mut!(state, {
|
||||||
state.scale_content.clear();
|
state.shapes.clean_all();
|
||||||
state.shapes.clean_modifiers();
|
|
||||||
state.shapes.clean_structure();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn clean_geometry_modifiers() {
|
|
||||||
with_state_mut!(state, {
|
|
||||||
state.shapes.clean_modifiers();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ mod ui;
|
|||||||
|
|
||||||
use skia_safe::{self as skia, Matrix, RRect, Rect};
|
use skia_safe::{self as skia, Matrix, RRect, Rect};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use gpu_state::GpuState;
|
use gpu_state::GpuState;
|
||||||
use options::RenderOptions;
|
use options::RenderOptions;
|
||||||
@@ -439,7 +439,6 @@ impl RenderState {
|
|||||||
pub fn render_shape(
|
pub fn render_shape(
|
||||||
&mut self,
|
&mut self,
|
||||||
shape: &Shape,
|
shape: &Shape,
|
||||||
scale_content: Option<&f32>,
|
|
||||||
clip_bounds: Option<(Rect, Option<Corners>, Matrix)>,
|
clip_bounds: Option<(Rect, Option<Corners>, Matrix)>,
|
||||||
fills_surface_id: SurfaceId,
|
fills_surface_id: SurfaceId,
|
||||||
strokes_surface_id: SurfaceId,
|
strokes_surface_id: SurfaceId,
|
||||||
@@ -449,12 +448,6 @@ impl RenderState {
|
|||||||
offset: Option<(f32, f32)>,
|
offset: Option<(f32, f32)>,
|
||||||
parent_shadows: Option<Vec<skia_safe::Paint>>,
|
parent_shadows: Option<Vec<skia_safe::Paint>>,
|
||||||
) {
|
) {
|
||||||
let shape = if let Some(scale_content) = scale_content {
|
|
||||||
&shape.scale_content(*scale_content)
|
|
||||||
} else {
|
|
||||||
shape
|
|
||||||
};
|
|
||||||
|
|
||||||
let surface_ids = fills_surface_id as u32
|
let surface_ids = fills_surface_id as u32
|
||||||
| strokes_surface_id as u32
|
| strokes_surface_id as u32
|
||||||
| innershadows_surface_id as u32
|
| innershadows_surface_id as u32
|
||||||
@@ -819,12 +812,7 @@ impl RenderState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_render_loop(
|
pub fn start_render_loop(&mut self, tree: ShapesPoolRef, timestamp: i32) -> Result<(), String> {
|
||||||
&mut self,
|
|
||||||
tree: ShapesPoolRef,
|
|
||||||
scale_content: &HashMap<Uuid, f32>,
|
|
||||||
timestamp: i32,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let scale = self.get_scale();
|
let scale = self.get_scale();
|
||||||
self.tile_viewbox.update(self.viewbox, scale);
|
self.tile_viewbox.update(self.viewbox, scale);
|
||||||
|
|
||||||
@@ -872,7 +860,7 @@ impl RenderState {
|
|||||||
self.current_tile = None;
|
self.current_tile = None;
|
||||||
self.render_in_progress = true;
|
self.render_in_progress = true;
|
||||||
self.apply_drawing_to_render_canvas(None);
|
self.apply_drawing_to_render_canvas(None);
|
||||||
self.process_animation_frame(tree, scale_content, timestamp)?;
|
self.process_animation_frame(tree, timestamp)?;
|
||||||
performance::end_measure!("start_render_loop");
|
performance::end_measure!("start_render_loop");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -880,13 +868,12 @@ impl RenderState {
|
|||||||
pub fn process_animation_frame(
|
pub fn process_animation_frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: ShapesPoolRef,
|
tree: ShapesPoolRef,
|
||||||
scale_content: &HashMap<Uuid, f32>,
|
|
||||||
timestamp: i32,
|
timestamp: i32,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
performance::begin_measure!("process_animation_frame");
|
performance::begin_measure!("process_animation_frame");
|
||||||
if self.render_in_progress {
|
if self.render_in_progress {
|
||||||
if tree.len() != 0 {
|
if tree.len() != 0 {
|
||||||
self.render_shape_tree_partial(tree, scale_content, timestamp)?;
|
self.render_shape_tree_partial(tree, timestamp)?;
|
||||||
} else {
|
} else {
|
||||||
println!("Empty tree");
|
println!("Empty tree");
|
||||||
}
|
}
|
||||||
@@ -956,12 +943,7 @@ impl RenderState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn render_shape_exit(
|
pub fn render_shape_exit(&mut self, element: &Shape, visited_mask: bool) {
|
||||||
&mut self,
|
|
||||||
element: &Shape,
|
|
||||||
visited_mask: bool,
|
|
||||||
scale_content: Option<&f32>,
|
|
||||||
) {
|
|
||||||
if visited_mask {
|
if visited_mask {
|
||||||
// Because masked groups needs two rendering passes (first drawing
|
// Because masked groups needs two rendering passes (first drawing
|
||||||
// the content and then drawing the mask), we need to do an
|
// the content and then drawing the mask), we need to do an
|
||||||
@@ -1016,7 +998,6 @@ impl RenderState {
|
|||||||
element_strokes.to_mut().clip_content = false;
|
element_strokes.to_mut().clip_content = false;
|
||||||
self.render_shape(
|
self.render_shape(
|
||||||
&element_strokes,
|
&element_strokes,
|
||||||
scale_content,
|
|
||||||
None,
|
None,
|
||||||
SurfaceId::Fills,
|
SurfaceId::Fills,
|
||||||
SurfaceId::Strokes,
|
SurfaceId::Strokes,
|
||||||
@@ -1102,7 +1083,6 @@ impl RenderState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
shape: &Shape,
|
shape: &Shape,
|
||||||
shadow: &Shadow,
|
shadow: &Shadow,
|
||||||
scale_content: Option<&f32>,
|
|
||||||
clip_bounds: Option<(Rect, Option<Corners>, Matrix)>,
|
clip_bounds: Option<(Rect, Option<Corners>, Matrix)>,
|
||||||
scale: f32,
|
scale: f32,
|
||||||
translation: (f32, f32),
|
translation: (f32, f32),
|
||||||
@@ -1152,7 +1132,6 @@ impl RenderState {
|
|||||||
|
|
||||||
self.render_shape(
|
self.render_shape(
|
||||||
&plain_shape,
|
&plain_shape,
|
||||||
scale_content,
|
|
||||||
clip_bounds,
|
clip_bounds,
|
||||||
SurfaceId::DropShadows,
|
SurfaceId::DropShadows,
|
||||||
SurfaceId::DropShadows,
|
SurfaceId::DropShadows,
|
||||||
@@ -1169,7 +1148,6 @@ impl RenderState {
|
|||||||
pub fn render_shape_tree_partial_uncached(
|
pub fn render_shape_tree_partial_uncached(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: ShapesPoolRef,
|
tree: ShapesPoolRef,
|
||||||
scale_content: &HashMap<Uuid, f32>,
|
|
||||||
timestamp: i32,
|
timestamp: i32,
|
||||||
) -> Result<(bool, bool), String> {
|
) -> Result<(bool, bool), String> {
|
||||||
let mut iteration = 0;
|
let mut iteration = 0;
|
||||||
@@ -1198,7 +1176,7 @@ impl RenderState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if visited_children {
|
if visited_children {
|
||||||
self.render_shape_exit(element, visited_mask, scale_content.get(&element.id));
|
self.render_shape_exit(element, visited_mask);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1260,7 +1238,6 @@ impl RenderState {
|
|||||||
self.render_drop_black_shadow(
|
self.render_drop_black_shadow(
|
||||||
element,
|
element,
|
||||||
shadow,
|
shadow,
|
||||||
scale_content.get(&element.id),
|
|
||||||
clip_bounds,
|
clip_bounds,
|
||||||
scale,
|
scale,
|
||||||
translation,
|
translation,
|
||||||
@@ -1280,7 +1257,6 @@ impl RenderState {
|
|||||||
self.render_drop_black_shadow(
|
self.render_drop_black_shadow(
|
||||||
shadow_shape,
|
shadow_shape,
|
||||||
shadow,
|
shadow,
|
||||||
scale_content.get(&element.id),
|
|
||||||
clip_bounds,
|
clip_bounds,
|
||||||
scale,
|
scale,
|
||||||
translation,
|
translation,
|
||||||
@@ -1314,7 +1290,6 @@ impl RenderState {
|
|||||||
|
|
||||||
self.render_shape(
|
self.render_shape(
|
||||||
shadow_shape,
|
shadow_shape,
|
||||||
scale_content.get(&element.id),
|
|
||||||
clip_bounds,
|
clip_bounds,
|
||||||
SurfaceId::DropShadows,
|
SurfaceId::DropShadows,
|
||||||
SurfaceId::DropShadows,
|
SurfaceId::DropShadows,
|
||||||
@@ -1352,7 +1327,6 @@ impl RenderState {
|
|||||||
|
|
||||||
self.render_shape(
|
self.render_shape(
|
||||||
element,
|
element,
|
||||||
scale_content.get(&element.id),
|
|
||||||
clip_bounds,
|
clip_bounds,
|
||||||
SurfaceId::Fills,
|
SurfaceId::Fills,
|
||||||
SurfaceId::Strokes,
|
SurfaceId::Strokes,
|
||||||
@@ -1426,7 +1400,6 @@ impl RenderState {
|
|||||||
pub fn render_shape_tree_partial(
|
pub fn render_shape_tree_partial(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: ShapesPoolRef,
|
tree: ShapesPoolRef,
|
||||||
scale_content: &HashMap<Uuid, f32>,
|
|
||||||
timestamp: i32,
|
timestamp: i32,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let mut should_stop = false;
|
let mut should_stop = false;
|
||||||
@@ -1453,7 +1426,7 @@ impl RenderState {
|
|||||||
} else {
|
} else {
|
||||||
performance::begin_measure!("render_shape_tree::uncached");
|
performance::begin_measure!("render_shape_tree::uncached");
|
||||||
let (is_empty, early_return) =
|
let (is_empty, early_return) =
|
||||||
self.render_shape_tree_partial_uncached(tree, scale_content, timestamp)?;
|
self.render_shape_tree_partial_uncached(tree, timestamp)?;
|
||||||
if early_return {
|
if early_return {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ pub struct Shape {
|
|||||||
pub extrect: OnceCell<math::Rect>,
|
pub extrect: OnceCell<math::Rect>,
|
||||||
pub bounds: OnceCell<math::Bounds>,
|
pub bounds: OnceCell<math::Bounds>,
|
||||||
pub svg_transform: Option<Matrix>,
|
pub svg_transform: Option<Matrix>,
|
||||||
|
pub ignore_constraints: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns all ancestor shapes of this shape, traversing up the parent hierarchy
|
// Returns all ancestor shapes of this shape, traversing up the parent hierarchy
|
||||||
@@ -265,30 +266,24 @@ impl Shape {
|
|||||||
extrect: OnceCell::new(),
|
extrect: OnceCell::new(),
|
||||||
bounds: OnceCell::new(),
|
bounds: OnceCell::new(),
|
||||||
svg_transform: None,
|
svg_transform: None,
|
||||||
|
ignore_constraints: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scale_content(&self, value: f32) -> Self {
|
pub fn scale_content(&mut self, value: f32) {
|
||||||
let mut result = self.clone();
|
self.ignore_constraints = true;
|
||||||
result.shape_type.scale_content(value);
|
self.shape_type.scale_content(value);
|
||||||
result
|
self.strokes.iter_mut().for_each(|s| s.scale_content(value));
|
||||||
.strokes
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|s| s.scale_content(value));
|
|
||||||
result
|
|
||||||
.shadows
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|s| s.scale_content(value));
|
|
||||||
|
|
||||||
if let Some(blur) = result.blur.as_mut() {
|
self.shadows.iter_mut().for_each(|s| s.scale_content(value));
|
||||||
|
|
||||||
|
if let Some(blur) = self.blur.as_mut() {
|
||||||
blur.scale_content(value);
|
blur.scale_content(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
self.layout_item
|
||||||
.layout_item
|
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.for_each(|i| i.scale_content(value));
|
.for_each(|i| i.scale_content(value));
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalidate_extrect(&mut self) {
|
pub fn invalidate_extrect(&mut self) {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ fn propagate_children(
|
|||||||
parent_bounds_after: &Bounds,
|
parent_bounds_after: &Bounds,
|
||||||
transform: Matrix,
|
transform: Matrix,
|
||||||
bounds: &HashMap<Uuid, Bounds>,
|
bounds: &HashMap<Uuid, Bounds>,
|
||||||
scale_content: &HashMap<Uuid, f32>,
|
|
||||||
) -> VecDeque<Modifier> {
|
) -> VecDeque<Modifier> {
|
||||||
let children_ids = shape.children_ids(true);
|
let children_ids = shape.children_ids(true);
|
||||||
|
|
||||||
@@ -38,8 +37,6 @@ fn propagate_children(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let ignore_constraints = scale_content.contains_key(child_id);
|
|
||||||
|
|
||||||
let child_bounds = bounds.find(child);
|
let child_bounds = bounds.find(child);
|
||||||
|
|
||||||
let constraint_h = match &shape.shape_type {
|
let constraint_h = match &shape.shape_type {
|
||||||
@@ -77,7 +74,7 @@ fn propagate_children(
|
|||||||
constraint_h,
|
constraint_h,
|
||||||
constraint_v,
|
constraint_v,
|
||||||
transform,
|
transform,
|
||||||
ignore_constraints,
|
child.ignore_constraints,
|
||||||
);
|
);
|
||||||
|
|
||||||
result.push_back(Modifier::transform(*child_id, transform));
|
result.push_back(Modifier::transform(*child_id, transform));
|
||||||
@@ -229,7 +226,6 @@ fn propagate_transform(
|
|||||||
&shape_bounds_after,
|
&shape_bounds_after,
|
||||||
transform,
|
transform,
|
||||||
bounds,
|
bounds,
|
||||||
&state.scale_content,
|
|
||||||
);
|
);
|
||||||
entries.append(&mut children);
|
entries.append(&mut children);
|
||||||
}
|
}
|
||||||
@@ -343,12 +339,6 @@ fn reflow_shape(
|
|||||||
|
|
||||||
let shapes = &state.shapes;
|
let shapes = &state.shapes;
|
||||||
|
|
||||||
let shape = if let Some(scale_content) = state.scale_content.get(id) {
|
|
||||||
&shape.scale_content(*scale_content)
|
|
||||||
} else {
|
|
||||||
shape
|
|
||||||
};
|
|
||||||
|
|
||||||
let Type::Frame(frame_data) = &shape.shape_type else {
|
let Type::Frame(frame_data) = &shape.shape_type else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -468,7 +458,6 @@ mod tests {
|
|||||||
&bounds_after,
|
&bounds_after,
|
||||||
transform,
|
transform,
|
||||||
&HashMap::new(),
|
&HashMap::new(),
|
||||||
&HashMap::new(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(result.len(), 1);
|
assert_eq!(result.len(), 1);
|
||||||
@@ -499,8 +488,7 @@ mod tests {
|
|||||||
|
|
||||||
let parent = shapes.get(&parent_id).unwrap();
|
let parent = shapes.get(&parent_id).unwrap();
|
||||||
|
|
||||||
let bounds =
|
let bounds = calculate_group_bounds(parent, &shapes, &HashMap::new()).unwrap();
|
||||||
calculate_group_bounds(parent, &shapes, &HashMap::new()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(bounds.width(), 3.0);
|
assert_eq!(bounds.width(), 3.0);
|
||||||
assert_eq!(bounds.height(), 3.0);
|
assert_eq!(bounds.height(), 3.0);
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ pub(crate) struct State<'a> {
|
|||||||
pub text_editor_state: TextEditorState,
|
pub text_editor_state: TextEditorState,
|
||||||
pub current_id: Option<Uuid>,
|
pub current_id: Option<Uuid>,
|
||||||
pub shapes: ShapesPool<'a>,
|
pub shapes: ShapesPool<'a>,
|
||||||
pub scale_content: HashMap<Uuid, f32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> State<'a> {
|
impl<'a> State<'a> {
|
||||||
@@ -33,7 +32,6 @@ impl<'a> State<'a> {
|
|||||||
text_editor_state: TextEditorState::new(),
|
text_editor_state: TextEditorState::new(),
|
||||||
current_id: None,
|
current_id: None,
|
||||||
shapes: ShapesPool::new(),
|
shapes: ShapesPool::new(),
|
||||||
scale_content: HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,13 +63,13 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn start_render_loop(&mut self, timestamp: i32) -> Result<(), String> {
|
pub fn start_render_loop(&mut self, timestamp: i32) -> Result<(), String> {
|
||||||
self.render_state
|
self.render_state
|
||||||
.start_render_loop(&self.shapes, &self.scale_content, timestamp)?;
|
.start_render_loop(&self.shapes, timestamp)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_animation_frame(&mut self, timestamp: i32) -> Result<(), String> {
|
pub fn process_animation_frame(&mut self, timestamp: i32) -> Result<(), String> {
|
||||||
self.render_state
|
self.render_state
|
||||||
.process_animation_frame(&self.shapes, &self.scale_content, timestamp)?;
|
.process_animation_frame(&self.shapes, timestamp)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ pub struct ShapesPoolImpl<'a> {
|
|||||||
modified_shape_cache: HashMap<&'a Uuid, OnceCell<Shape>>,
|
modified_shape_cache: HashMap<&'a Uuid, OnceCell<Shape>>,
|
||||||
modifiers: HashMap<&'a Uuid, skia::Matrix>,
|
modifiers: HashMap<&'a Uuid, skia::Matrix>,
|
||||||
structure: HashMap<&'a Uuid, Vec<StructureEntry>>,
|
structure: HashMap<&'a Uuid, Vec<StructureEntry>>,
|
||||||
|
scale_content: HashMap<&'a Uuid, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type aliases to avoid writing lifetimes everywhere
|
// Type aliases to avoid writing lifetimes everywhere
|
||||||
@@ -50,6 +51,7 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
modified_shape_cache: HashMap::default(),
|
modified_shape_cache: HashMap::default(),
|
||||||
modifiers: HashMap::default(),
|
modifiers: HashMap::default(),
|
||||||
structure: HashMap::default(),
|
structure: HashMap::default(),
|
||||||
|
scale_content: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +164,20 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebuild scale_content with fresh references
|
||||||
|
if !self.scale_content.is_empty() {
|
||||||
|
let old_scale_content: Vec<(Uuid, f32)> = self
|
||||||
|
.scale_content
|
||||||
|
.drain()
|
||||||
|
.map(|(uuid_ref, scale)| (*uuid_ref, scale))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for (uuid, scale) in old_scale_content {
|
||||||
|
if let Some(uuid_ref) = self.get_uuid_ref(&uuid) {
|
||||||
|
self.scale_content.insert(uuid_ref, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Rebuild modified_shape_cache with fresh references
|
// Rebuild modified_shape_cache with fresh references
|
||||||
if !self.modified_shape_cache.is_empty() {
|
if !self.modified_shape_cache.is_empty() {
|
||||||
let old_cache: Vec<(Uuid, OnceCell<Shape>)> = self
|
let old_cache: Vec<(Uuid, OnceCell<Shape>)> = self
|
||||||
@@ -204,6 +220,7 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
let shape_ptr = &self.shapes[idx] as *const Shape;
|
let shape_ptr = &self.shapes[idx] as *const Shape;
|
||||||
let modifiers_ptr = &self.modifiers as *const HashMap<&'a Uuid, skia::Matrix>;
|
let modifiers_ptr = &self.modifiers as *const HashMap<&'a Uuid, skia::Matrix>;
|
||||||
let structure_ptr = &self.structure as *const HashMap<&'a Uuid, Vec<StructureEntry>>;
|
let structure_ptr = &self.structure as *const HashMap<&'a Uuid, Vec<StructureEntry>>;
|
||||||
|
let scale_content_ptr = &self.scale_content as *const HashMap<&'a Uuid, f32>;
|
||||||
let cache_ptr = &self.modified_shape_cache as *const HashMap<&'a Uuid, OnceCell<Shape>>;
|
let cache_ptr = &self.modified_shape_cache as *const HashMap<&'a Uuid, OnceCell<Shape>>;
|
||||||
|
|
||||||
// Extend the lifetime of id to 'a - safe because it's the same Uuid stored in shapes[idx].id
|
// Extend the lifetime of id to 'a - safe because it's the same Uuid stored in shapes[idx].id
|
||||||
@@ -212,15 +229,19 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
if self.to_update_bool(&*shape_ptr)
|
if self.to_update_bool(&*shape_ptr)
|
||||||
|| (*modifiers_ptr).contains_key(&id_ref)
|
|| (*modifiers_ptr).contains_key(&id_ref)
|
||||||
|| (*structure_ptr).contains_key(&id_ref)
|
|| (*structure_ptr).contains_key(&id_ref)
|
||||||
|
|| (*scale_content_ptr).contains_key(&id_ref)
|
||||||
{
|
{
|
||||||
if let Some(cell) = (*cache_ptr).get(&id_ref) {
|
if let Some(cell) = (*cache_ptr).get(&id_ref) {
|
||||||
Some(cell.get_or_init(|| {
|
Some(cell.get_or_init(|| {
|
||||||
let shape = &*shape_ptr;
|
let mut shape = (*shape_ptr).transformed(
|
||||||
shape.transformed(
|
|
||||||
self,
|
self,
|
||||||
(*modifiers_ptr).get(&id_ref),
|
(*modifiers_ptr).get(&id_ref),
|
||||||
(*structure_ptr).get(&id_ref),
|
(*structure_ptr).get(&id_ref),
|
||||||
)
|
);
|
||||||
|
if let Some(scale) = (*scale_content_ptr).get(&id_ref) {
|
||||||
|
shape.scale_content(*scale);
|
||||||
|
}
|
||||||
|
shape
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Some(&*shape_ptr)
|
Some(&*shape_ptr)
|
||||||
@@ -240,12 +261,10 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
self.shapes.iter_mut()
|
self.shapes.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn clean_shape_cache(&mut self) {
|
fn clean_shape_cache(&mut self) {
|
||||||
self.modified_shape_cache.clear()
|
self.modified_shape_cache.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn set_modifiers(&mut self, modifiers: HashMap<Uuid, skia::Matrix>) {
|
pub fn set_modifiers(&mut self, modifiers: HashMap<Uuid, skia::Matrix>) {
|
||||||
// self.clean_shape_cache();
|
// self.clean_shape_cache();
|
||||||
|
|
||||||
@@ -272,7 +291,6 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn set_structure(&mut self, structure: HashMap<Uuid, Vec<StructureEntry>>) {
|
pub fn set_structure(&mut self, structure: HashMap<Uuid, Vec<StructureEntry>>) {
|
||||||
// Convert HashMap<Uuid, V> to HashMap<&'a Uuid, V> using references from shapes and
|
// Convert HashMap<Uuid, V> to HashMap<&'a Uuid, V> using references from shapes and
|
||||||
// Initialize the cache cells because later we don't want to have the mutable pointer
|
// Initialize the cache cells because later we don't want to have the mutable pointer
|
||||||
@@ -295,16 +313,33 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn set_scale_content(&mut self, scale_content: HashMap<Uuid, f32>) {
|
||||||
pub fn clean_modifiers(&mut self) {
|
// Convert HashMap<Uuid, V> to HashMap<&'a Uuid, V> using references from shapes and
|
||||||
self.clean_shape_cache();
|
// Initialize the cache cells because later we don't want to have the mutable pointer
|
||||||
self.modifiers = HashMap::default();
|
let mut scale_content_with_refs = HashMap::with_capacity(scale_content.len());
|
||||||
|
let mut ids = Vec::<Uuid>::new();
|
||||||
|
|
||||||
|
for (uuid, value) in scale_content {
|
||||||
|
if let Some(uuid_ref) = self.get_uuid_ref(&uuid) {
|
||||||
|
scale_content_with_refs.insert(uuid_ref, value);
|
||||||
|
ids.push(*uuid_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.scale_content = scale_content_with_refs;
|
||||||
|
|
||||||
|
let all_ids = shapes::all_with_ancestors(&ids, self, true);
|
||||||
|
for uuid in all_ids {
|
||||||
|
if let Some(uuid_ref) = self.get_uuid_ref(&uuid) {
|
||||||
|
self.modified_shape_cache.insert(uuid_ref, OnceCell::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn clean_all(&mut self) {
|
||||||
pub fn clean_structure(&mut self) {
|
|
||||||
self.clean_shape_cache();
|
self.clean_shape_cache();
|
||||||
|
self.modifiers = HashMap::default();
|
||||||
self.structure = HashMap::default();
|
self.structure = HashMap::default();
|
||||||
|
self.scale_content = HashMap::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the Uuid stored in a shape, if it exists
|
/// Get a reference to the Uuid stored in a shape, if it exists
|
||||||
@@ -346,6 +381,7 @@ impl<'a> ShapesPoolImpl<'a> {
|
|||||||
modified_shape_cache: HashMap::default(),
|
modified_shape_cache: HashMap::default(),
|
||||||
modifiers: HashMap::default(),
|
modifiers: HashMap::default(),
|
||||||
structure: HashMap::default(),
|
structure: HashMap::default(),
|
||||||
|
scale_content: HashMap::default(),
|
||||||
};
|
};
|
||||||
result.rebuild_references();
|
result.rebuild_references();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user