diff --git a/Cargo.lock b/Cargo.lock index 32c28eb..b80d548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -825,6 +825,7 @@ dependencies = [ "float-pigment-forest-macro", "float-pigment-layout", "float-pigment-mlp", + "fs_extra", "lazy_static", "lru", "piston_window", diff --git a/README.md b/README.md index 4f422ae..ebb6617 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Major crates: | ---------- | ----------- | ---- | | [float-pigment-css](https://crates.io/crates/float-pigment-css) | CSS parser. | [![docs.rs](https://img.shields.io/docsrs/float-pigment-css?style=flat-square)](https://docs.rs/float-pigment-css) | | [float-pigment-layout](https://crates.io/crates/float-pigment-layout) | Layout engine which supports common CSS `display`, including `flex` `block` and `inline`. | [![docs.rs](https://img.shields.io/docsrs/float-pigment-layout?style=flat-square)](https://docs.rs/float-pigment-layout) | -| [float-pigment-forest](https://crates.io/crates/float-pigment-forest) | Tree implementation that works with `float-pigment-layout`. | [![docs.rs](https://img.shields.io/docsrs/float-pigment-forest?style=flat-square)](https://docs.rs/float-pigment-forest) | +| [float-pigment-forest](https://crates.io/crates/float-pigment-forest) | Tree implementation that works with `float-pigment-layout` for C++ bondings. | [![docs.rs](https://img.shields.io/docsrs/float-pigment-forest?style=flat-square)](https://docs.rs/float-pigment-forest) | | [float-pigment](https://crates.io/crates/float-pigment) | The collection of all crates above, with C++ bindings. | [![docs.rs](https://img.shields.io/docsrs/float-pigment?style=flat-square)](https://docs.rs/float-pigment) | @@ -57,9 +57,9 @@ Supported `position`: float-pigment-layout requires an external node tree implementation. -Usually the node tree should be implemented in high-level code or some other dedicated modules, but that is not always this case. +Usually the node tree should be implemented in high-level code or some other dedicated modules. -If you do not implement a node tree yourself, or the tree implementation is not in rust, this crate can help. +However, if the main implementation is in C++, this crate can help you builds a tree in rust. ## LICENSE diff --git a/float-pigment-forest/Cargo.toml b/float-pigment-forest/Cargo.toml index 79173a1..d04e9be 100644 --- a/float-pigment-forest/Cargo.toml +++ b/float-pigment-forest/Cargo.toml @@ -33,7 +33,7 @@ harness = false [features] default = [] -build-cpp-header = ["cbindgen"] +build-cpp-header = ["cbindgen", "fs_extra"] [dependencies] float-pigment-css = { workspace = true } @@ -45,6 +45,7 @@ lru = "0.7.8" float-pigment-forest-macro = { workspace = true } bit-vec = "0.6.3" lazy_static = "1.4" +fs_extra = { version = "1.3", optional = true } [dev-dependencies] rand = "0.8.5" @@ -55,5 +56,5 @@ rustc-hash = "1.1.0" [target.'cfg(target_os="macos")'.dev-dependencies] piston_window = "0.128.0" -[lints] -workspace = true +[lints.clippy] +missing_safety_doc = "allow" diff --git a/float-pigment-forest/benches/layout.rs b/float-pigment-forest/benches/layout.rs index ca3d362..86b4aad 100644 --- a/float-pigment-forest/benches/layout.rs +++ b/float-pigment-forest/benches/layout.rs @@ -24,13 +24,15 @@ fn gen_tree() -> &'static Node { } fn layout_test(root: &Node) { - root.layout( - OptionSize::new( - OptionNum::some(30000.0.to_fixed()), - OptionNum::some(800.0.to_fixed()), - ), - Size::new(375.0.to_fixed(), 800.0.to_fixed()), - ); + unsafe { + root.layout( + OptionSize::new( + OptionNum::some(30000.0.to_fixed()), + OptionNum::some(800.0.to_fixed()), + ), + Size::new(375.0.to_fixed(), 800.0.to_fixed()), + ); + } } fn criterion_benchmark(c: &mut Criterion) { diff --git a/float-pigment-forest/src/layout/layout_impl.rs b/float-pigment-forest/src/layout/layout_impl.rs index abf8d91..b107cdb 100644 --- a/float-pigment-forest/src/layout/layout_impl.rs +++ b/float-pigment-forest/src/layout/layout_impl.rs @@ -101,7 +101,7 @@ impl LayoutTreeNode for Node { } } if !skip_measure { - if let Some(func) = self.measure_func() { + if let Some(func) = unsafe { self.measure_func() } { let mut width_measure_mode = MeasureMode::AtMost; let mut height_measure_mode = MeasureMode::AtMost; let (min_width, max_width) = if let Some(req_size_width) = req_size.width.val() { @@ -135,7 +135,7 @@ impl LayoutTreeNode for Node { }; let mut size_from_cache = false; if self.node_type() == NodeType::Text { - if let Some(cache) = self.measure_cache().as_mut() { + if let Some(cache) = unsafe { self.measure_cache() }.as_mut() { if let Some(size_cache) = cache.get(&( OptionSize::new( OptionNum::some(min_width).to_hashable(), @@ -183,7 +183,7 @@ impl LayoutTreeNode for Node { measure_size.height.clamp(min.height, max.height), ); if self.node_type() == NodeType::Text { - if let Some(cache) = self.measure_cache().as_mut() { + if let Some(cache) = unsafe { self.measure_cache() }.as_mut() { cache.put( ( OptionSize::new( @@ -209,7 +209,7 @@ impl LayoutTreeNode for Node { let mut baseline = size.to_vector(); let mut baseline_from_cache = false; if self.node_type() == NodeType::Text { - if let Some(cache) = self.baseline_cache().as_mut() { + if let Some(cache) = unsafe { self.baseline_cache() }.as_mut() { if let Some(baseline_cache) = cache.get(&Size::new(size.width, size.height)) { baseline_from_cache = true; baseline = Vector::new(Len::zero(), *baseline_cache); @@ -217,10 +217,10 @@ impl LayoutTreeNode for Node { } } if !baseline_from_cache { - if let Some(func) = self.baseline_func() { + if let Some(func) = unsafe { self.baseline_func() } { let ret = func(convert_node_ref_to_ptr(self), size.width, size.height); baseline = Vector::new(Len::zero(), ret); - if let Some(cache) = self.baseline_cache().as_mut() { + if let Some(cache) = unsafe { self.baseline_cache() }.as_mut() { cache.put(Size::new(size.width, size.height), ret); } } @@ -262,7 +262,7 @@ impl LayoutTreeNode for Node { impl LayoutTreeVisitor for Node { #[inline] fn parent(&self) -> Option<&Node> { - Node::parent(self) + unsafe { Node::parent(self) } } #[inline] @@ -271,7 +271,7 @@ impl LayoutTreeVisitor for Node { F: FnMut(&'a Node, usize), Node: 'a, { - self.for_each_child_node(f) + unsafe { self.for_each_child_node(f) } } #[inline] @@ -281,7 +281,7 @@ impl LayoutTreeVisitor for Node { #[inline] fn child_at(&self, index: usize) -> Option<&Node> { - self.get_child_at(index) + unsafe { self.get_child_at(index) } } } #[derive(Debug, Clone)] diff --git a/float-pigment-forest/src/node.rs b/float-pigment-forest/src/node.rs index 272394f..d7aa50d 100644 --- a/float-pigment-forest/src/node.rs +++ b/float-pigment-forest/src/node.rs @@ -66,9 +66,7 @@ pub(crate) type MeasureCache = LruCache< ), Size, >; -pub(crate) type MeasureCachePtr = *mut MeasureCache; pub(crate) type BaselineCache = LruCache::Hashable>, Len>; -pub(crate) type BaselineCachePtr = *mut BaselineCache; const CACHE_SIZE: usize = 3; @@ -95,11 +93,11 @@ pub enum DumpStyleMode { } pub trait DumpNode { - fn dump_to_html(&self, options: DumpOptions, current_depth: u8) -> String; + unsafe fn dump_to_html(&self, options: DumpOptions, current_depth: u8) -> String; } impl DumpNode for Node { - fn dump_to_html(&self, options: DumpOptions, current_depth: u8) -> String { + unsafe fn dump_to_html(&self, options: DumpOptions, current_depth: u8) -> String { let layout = options.layout.then_some(format!( "left: {}, top: {}, width: {}, height: {}", self.layout_position().left, @@ -193,29 +191,14 @@ pub struct Node { children: RefCell>, style_manager: RefCell, pub(crate) layout_node: LayoutNode, - measure_cache: Cell, - baseline_cache: Cell, + measure_cache: UnsafeCell>>, + baseline_cache: UnsafeCell>>, baseline_func: UnsafeCell>>>, measure_func: UnsafeCell>>>, resolve_calc: UnsafeCell>>>, dirty_callback: UnsafeCell>>, } -impl Drop for Node { - fn drop(&mut self) { - unsafe { - let measure_cache_ptr = self.measure_cache.get(); - if !measure_cache_ptr.is_null() { - drop(Box::from_raw(measure_cache_ptr)); - } - let baseline_cache_ptr = self.baseline_cache.get(); - if !baseline_cache_ptr.is_null() { - drop(Box::from_raw(baseline_cache_ptr)); - } - } - } -} - impl Node { pub fn new() -> Self { Self { @@ -230,21 +213,24 @@ impl Node { measure_func: UnsafeCell::new(None), resolve_calc: UnsafeCell::new(None), dirty_callback: UnsafeCell::new(None), - measure_cache: Cell::new(std::ptr::null_mut()), - baseline_cache: Cell::new(std::ptr::null_mut()), + measure_cache: UnsafeCell::new(None), + baseline_cache: UnsafeCell::new(None), } } + pub fn new_typed(node_type: NodeType) -> Self { + let ret = Self::new(); + ret.node_type.set(node_type); + ret + } pub fn new_ptr() -> NodePtr { let self_node = Box::new(Self::new()); Box::into_raw(self_node) } - pub fn parent(&self) -> Option<&Node> { - unsafe { - if self.parent.get().is_null() { - None - } else { - Some(&*self.parent.get()) - } + pub unsafe fn parent(&self) -> Option<&Node> { + if self.parent.get().is_null() { + None + } else { + Some(&*self.parent.get()) } } pub fn set_parent(&self, parent: Option) { @@ -261,11 +247,11 @@ impl Node { Some(self.parent.get()) } } - pub fn children(&self) -> Vec<&Node> { + pub unsafe fn children(&self) -> Vec<&Node> { self.children .borrow() .iter() - .map(|node| unsafe { &**node }) + .map(|node| &**node) .collect::>() } pub fn children_len(&self) -> usize { @@ -280,38 +266,36 @@ impl Node { pub(crate) fn computed_style(&self) -> ComputedStyle { self.layout_node.computed_style() } - pub fn set_node_type(&self, node_type: NodeType) { + pub unsafe fn set_node_type(&self, node_type: NodeType) { if self.node_type.get() != node_type { self.node_type.replace(node_type); } if node_type == NodeType::Text { - self.measure_cache - .replace(Box::into_raw(Box::new(LruCache::new(CACHE_SIZE)))); - self.baseline_cache - .replace(Box::into_raw(Box::new(LruCache::new(CACHE_SIZE)))); + *self.measure_cache.get() = Some(Box::new(LruCache::new(CACHE_SIZE))); + *self.baseline_cache.get() = Some(Box::new(LruCache::new(CACHE_SIZE))); } } - pub(crate) fn measure_cache(&self) -> Option<&mut MeasureCache> { - if self.measure_cache.get().is_null() { - None - } else { - unsafe { Some(&mut *self.measure_cache.get()) } - } + #[inline(always)] + pub(crate) unsafe fn measure_cache(&self) -> Option<&mut MeasureCache> { + let ret: *mut _ = self.measure_cache.get(); + (*ret).as_deref_mut() } - pub(crate) fn clear_measure_cache(&self) { + + pub(crate) unsafe fn clear_measure_cache(&self) { if let Some(cache) = self.measure_cache() { cache.clear(); } + } - pub(crate) fn baseline_cache(&self) -> Option<&mut BaselineCache> { - if self.baseline_cache.get().is_null() { - None - } else { - unsafe { Some(&mut *self.baseline_cache.get()) } - } + + #[inline(always)] + pub(crate) unsafe fn baseline_cache(&self) -> Option<&mut BaselineCache> { + let ret: *mut _ = self.baseline_cache.get(); + (*ret).as_deref_mut() } - pub(crate) fn clear_baseline_cache(&self) { + + pub(crate) unsafe fn clear_baseline_cache(&self) { if let Some(cache) = self.baseline_cache() { cache.clear(); } @@ -319,20 +303,20 @@ impl Node { pub(crate) fn node_type(&self) -> NodeType { self.node_type.get() } - pub(crate) fn baseline_func(&self) -> Option<&BaselineFn> { - unsafe { (*self.baseline_func.get()).as_deref() } + pub(crate) unsafe fn baseline_func(&self) -> Option<&BaselineFn> { + (*self.baseline_func.get()).as_deref() } - pub fn set_baseline_func(&self, baseline_func: Option>>) { + pub unsafe fn set_baseline_func(&self, baseline_func: Option>>) { drop(std::mem::replace( - unsafe { &mut *self.baseline_func.get() }, + &mut *self.baseline_func.get(), baseline_func, )); } - pub fn has_baseline_func(&self) -> bool { - unsafe { (*self.baseline_func.get()).is_some() } + pub unsafe fn has_baseline_func(&self) -> bool { + (*self.baseline_func.get()).is_some() } - pub(crate) fn measure_func(&self) -> Option<&MeasureFn> { - unsafe { (*self.measure_func.get()).as_deref() } + pub(crate) unsafe fn measure_func(&self) -> Option<&MeasureFn> { + (*self.measure_func.get()).as_deref() } pub fn set_measure_func(&self, measure_func: Option>>) { drop(std::mem::replace( @@ -384,7 +368,7 @@ impl Node { pub(crate) fn clear_dirty(&self) { self.is_dirty.set(false) } - pub(crate) fn clear_dirty_recursive(&self) { + pub(crate) unsafe fn clear_dirty_recursive(&self) { if self.is_dirty() { self.clear_dirty(); self.children() @@ -392,7 +376,7 @@ impl Node { .for_each(|child| child.clear_dirty_recursive()); } } - pub fn mark_self_dirty(&self) { + pub unsafe fn mark_self_dirty(&self) { if self.is_dirty() { return; } @@ -406,7 +390,7 @@ impl Node { } self.layout_node.mark_dirty(self); } - pub fn mark_dirty_propagate_to_descendants(&self) { + pub unsafe fn mark_dirty_propagate_to_descendants(&self) { self.mark_self_dirty(); unsafe { self.children @@ -415,7 +399,7 @@ impl Node { .for_each(|node| (**node).mark_dirty_propagate_to_descendants()) } } - pub fn mark_dirty_propagate(&self) { + pub unsafe fn mark_dirty_propagate(&self) { if !self.is_dirty() { self.mark_self_dirty(); if let Some(parent) = self.parent() { @@ -439,7 +423,7 @@ impl Node { available_size, ); } - pub fn layout( + pub unsafe fn layout( &self, available_size: OptionSize, viewport_size: float_pigment_layout::Size, @@ -457,7 +441,7 @@ impl Node { self.clear_dirty_recursive(); } - pub fn layout_with_containing_size( + pub unsafe fn layout_with_containing_size( &self, available_size: OptionSize, viewport_size: float_pigment_layout::Size, @@ -492,191 +476,183 @@ impl Default for Node { } } pub trait ChildOperation { - fn get_child_at(&self, idx: usize) -> Option<&Node>; - fn get_child_ptr_at(&self, idx: usize) -> Option; - fn get_child_index(&self, child: NodePtr) -> Option; - fn append_child(&self, child: NodePtr); - fn insert_child_at(&self, child: NodePtr, idx: usize); - fn insert_child_before(&self, child: NodePtr, pivot: NodePtr); - fn remove_child(&self, child: NodePtr); - fn remove_child_at(&self, idx: usize); - fn remove_all_children(&self); - fn for_each_child_node<'a, 'b: 'a, F>(&'b self, func: F) + unsafe fn get_child_at(&self, idx: usize) -> Option<&Node>; + unsafe fn get_child_ptr_at(&self, idx: usize) -> Option; + unsafe fn get_child_index(&self, child: NodePtr) -> Option; + unsafe fn append_child(&self, child: NodePtr); + unsafe fn insert_child_at(&self, child: NodePtr, idx: usize); + unsafe fn insert_child_before(&self, child: NodePtr, pivot: NodePtr); + unsafe fn remove_child(&self, child: NodePtr); + unsafe fn remove_child_at(&self, idx: usize); + unsafe fn remove_all_children(&self); + unsafe fn for_each_child_node<'a, 'b: 'a, F>(&'b self, func: F) where F: FnMut(&'a Self, usize); } impl ChildOperation for Node { - fn get_child_at(&self, idx: usize) -> Option<&Node> { + unsafe fn get_child_at(&self, idx: usize) -> Option<&Node> { self.children().get(idx).copied() } - fn get_child_ptr_at(&self, idx: usize) -> Option { + unsafe fn get_child_ptr_at(&self, idx: usize) -> Option { self.children.borrow().get(idx).copied() } - fn get_child_index(&self, child: NodePtr) -> Option { + unsafe fn get_child_index(&self, child: NodePtr) -> Option { self.children() .iter() .position(|node| ptr::eq(*node, child)) } #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn append_child(&self, child: NodePtr) { - unsafe { (*child).set_parent(Some(convert_node_ref_to_ptr(self))) } + unsafe fn append_child(&self, child: NodePtr) { + (*child).set_parent(Some(convert_node_ref_to_ptr(self))); self.children.borrow_mut().push(child); self.mark_dirty_propagate() } #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn insert_child_at(&self, child: NodePtr, idx: usize) { - unsafe { (*child).set_parent(Some(convert_node_ref_to_ptr(self))) } + unsafe fn insert_child_at(&self, child: NodePtr, idx: usize) { + (*child).set_parent(Some(convert_node_ref_to_ptr(self))); self.children.borrow_mut().insert(idx, child); self.mark_dirty_propagate() } #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn insert_child_before(&self, child: NodePtr, pivot: NodePtr) { - unsafe { - (*child).set_parent(Some(convert_node_ref_to_ptr(self))); - let idx = self - .children - .borrow() - .iter() - .position(|node| std::ptr::eq(*node, pivot)); - if let Some(idx) = idx { - self.children.borrow_mut().insert(idx, child) - } + unsafe fn insert_child_before(&self, child: NodePtr, pivot: NodePtr) { + (*child).set_parent(Some(convert_node_ref_to_ptr(self))); + let idx = self + .children + .borrow() + .iter() + .position(|node| std::ptr::eq(*node, pivot)); + if let Some(idx) = idx { + self.children.borrow_mut().insert(idx, child) } self.mark_dirty_propagate(); } - fn remove_child(&self, child: NodePtr) { + unsafe fn remove_child(&self, child: NodePtr) { if self.children_len() == 0 { return; } - unsafe { - if let Some((idx, node)) = self - .children - .borrow() - .iter() - .enumerate() - .find(|(_, node)| std::ptr::eq(**node, child)) - { - (**node).set_parent(None); - (*self.children.as_ptr()).remove(idx); - } + if let Some((idx, node)) = self + .children + .borrow() + .iter() + .enumerate() + .find(|(_, node)| std::ptr::eq(**node, child)) + { + (**node).set_parent(None); + (*self.children.as_ptr()).remove(idx); } self.mark_dirty_propagate(); } - fn remove_child_at(&self, idx: usize) { + unsafe fn remove_child_at(&self, idx: usize) { let len = self.children_len(); if len == 0 || idx >= len { return; } - unsafe { - if let Some(node) = self.children.borrow().get(idx) { - (**node).set_parent(None); - } + if let Some(node) = self.children.borrow().get(idx) { + (**node).set_parent(None); } self.children.borrow_mut().remove(idx); self.mark_dirty_propagate(); } - fn remove_all_children(&self) { + unsafe fn remove_all_children(&self) { self.for_each_child_node(|node, _| { (*node).set_parent(None); }); self.children.borrow_mut().clear(); self.mark_dirty_propagate() } - fn for_each_child_node<'a, 'b: 'a, F>(&'b self, func: F) + unsafe fn for_each_child_node<'a, 'b: 'a, F>(&'b self, func: F) where F: FnMut(&'a Self, usize), { let mut func = func; - unsafe { - self.children - .borrow_mut() - .iter_mut() - .enumerate() - .for_each(|(idx, node)| func(&**node, idx)) - } + self.children + .borrow_mut() + .iter_mut() + .enumerate() + .for_each(|(idx, node)| func(&**node, idx)) } } pub trait StyleSetter { - fn set_display(&self, value: Display); - fn set_box_sizing(&self, value: BoxSizing); - fn set_direction(&self, value: Direction); - fn set_writing_mode(&self, value: WritingMode); - fn set_position(&self, value: Position); - fn set_left(&self, value: Length); - fn set_top(&self, value: Length); - fn set_right(&self, value: Length); - fn set_bottom(&self, value: Length); - fn set_overflow_x(&self, value: Overflow); - fn set_overflow_y(&self, value: Overflow); - fn set_width(&self, value: Length); - fn set_height(&self, value: Length); - fn set_min_width(&self, value: Length); - fn set_min_height(&self, value: Length); - fn set_max_width(&self, value: Length); - fn set_max_height(&self, value: Length); - fn set_margin(&self, value: Length); - fn set_margin_left(&self, value: Length); - fn set_margin_top(&self, value: Length); - fn set_margin_right(&self, value: Length); - fn set_margin_bottom(&self, value: Length); - fn set_padding(&self, value: Length); - fn set_padding_left(&self, value: Length); - fn set_padding_top(&self, value: Length); - fn set_padding_right(&self, value: Length); - fn set_padding_bottom(&self, value: Length); - fn set_border(&self, value: Length); - fn set_border_left(&self, value: Length); - fn set_border_top(&self, value: Length); - fn set_border_right(&self, value: Length); - fn set_border_bottom(&self, value: Length); - fn set_flex_grow(&self, value: f32); - fn set_flex_shrink(&self, value: f32); - fn set_flex_basis(&self, value: Length); - fn set_flex_direction(&self, value: FlexDirection); - fn set_flex_wrap(&self, value: FlexWrap); - fn set_justify_content(&self, value: JustifyContent); - fn set_align_content(&self, value: AlignContent); - fn set_align_items(&self, value: AlignItems); - fn set_align_self(&self, value: AlignSelf); - fn set_aspect_ratio(&self, value: Option); - fn set_order(&self, value: i32); - fn set_text_align(&self, value: TextAlign); + unsafe fn set_display(&self, value: Display); + unsafe fn set_box_sizing(&self, value: BoxSizing); + unsafe fn set_direction(&self, value: Direction); + unsafe fn set_writing_mode(&self, value: WritingMode); + unsafe fn set_position(&self, value: Position); + unsafe fn set_left(&self, value: Length); + unsafe fn set_top(&self, value: Length); + unsafe fn set_right(&self, value: Length); + unsafe fn set_bottom(&self, value: Length); + unsafe fn set_overflow_x(&self, value: Overflow); + unsafe fn set_overflow_y(&self, value: Overflow); + unsafe fn set_width(&self, value: Length); + unsafe fn set_height(&self, value: Length); + unsafe fn set_min_width(&self, value: Length); + unsafe fn set_min_height(&self, value: Length); + unsafe fn set_max_width(&self, value: Length); + unsafe fn set_max_height(&self, value: Length); + unsafe fn set_margin(&self, value: Length); + unsafe fn set_margin_left(&self, value: Length); + unsafe fn set_margin_top(&self, value: Length); + unsafe fn set_margin_right(&self, value: Length); + unsafe fn set_margin_bottom(&self, value: Length); + unsafe fn set_padding(&self, value: Length); + unsafe fn set_padding_left(&self, value: Length); + unsafe fn set_padding_top(&self, value: Length); + unsafe fn set_padding_right(&self, value: Length); + unsafe fn set_padding_bottom(&self, value: Length); + unsafe fn set_border(&self, value: Length); + unsafe fn set_border_left(&self, value: Length); + unsafe fn set_border_top(&self, value: Length); + unsafe fn set_border_right(&self, value: Length); + unsafe fn set_border_bottom(&self, value: Length); + unsafe fn set_flex_grow(&self, value: f32); + unsafe fn set_flex_shrink(&self, value: f32); + unsafe fn set_flex_basis(&self, value: Length); + unsafe fn set_flex_direction(&self, value: FlexDirection); + unsafe fn set_flex_wrap(&self, value: FlexWrap); + unsafe fn set_justify_content(&self, value: JustifyContent); + unsafe fn set_align_content(&self, value: AlignContent); + unsafe fn set_align_items(&self, value: AlignItems); + unsafe fn set_align_self(&self, value: AlignSelf); + unsafe fn set_aspect_ratio(&self, value: Option); + unsafe fn set_order(&self, value: i32); + unsafe fn set_text_align(&self, value: TextAlign); } impl StyleSetter for Node { - fn set_flex_direction(&self, flex_direction: FlexDirection) { + unsafe fn set_flex_direction(&self, flex_direction: FlexDirection) { if self.style_manager_mut().set_flex_direction(flex_direction) { self.mark_dirty_propagate(); } } - fn set_direction(&self, direction: Direction) { + unsafe fn set_direction(&self, direction: Direction) { if self.style_manager_mut().set_direction(direction) { self.mark_dirty_propagate(); } } - fn set_align_content(&self, align_content: AlignContent) { + unsafe fn set_align_content(&self, align_content: AlignContent) { if self.style_manager_mut().set_align_content(align_content) { self.mark_dirty_propagate(); } } - fn set_align_items(&self, align_items: AlignItems) { + unsafe fn set_align_items(&self, align_items: AlignItems) { if self.style_manager_mut().set_align_items(align_items) { self.mark_dirty_propagate(); } } - fn set_align_self(&self, align_self: AlignSelf) { + unsafe fn set_align_self(&self, align_self: AlignSelf) { if self.style_manager_mut().set_align_self(align_self) { self.mark_dirty_propagate(); } } - fn set_aspect_ratio(&self, aspect_ratio: Option) { + unsafe fn set_aspect_ratio(&self, aspect_ratio: Option) { if self.style_manager_mut().set_aspect_ratio(aspect_ratio) { self.mark_dirty_propagate(); } } - fn set_border(&self, border: Length) { + unsafe fn set_border(&self, border: Length) { let top_changed = self.style_manager_mut().set_border_top(border); let right_changed = self.style_manager_mut().set_border_right(border); let bottom_changed = self.style_manager_mut().set_border_bottom(border); @@ -685,87 +661,87 @@ impl StyleSetter for Node { self.mark_dirty_propagate(); } } - fn set_border_left(&self, border_left: Length) { + unsafe fn set_border_left(&self, border_left: Length) { if self.style_manager_mut().set_border_left(border_left) { self.mark_dirty_propagate(); } } - fn set_border_right(&self, border_right: Length) { + unsafe fn set_border_right(&self, border_right: Length) { if self.style_manager_mut().set_border_right(border_right) { self.mark_dirty_propagate(); } } - fn set_border_top(&self, border_top: Length) { + unsafe fn set_border_top(&self, border_top: Length) { if self.style_manager_mut().set_border_top(border_top) { self.mark_dirty_propagate(); } } - fn set_border_bottom(&self, border_bottom: Length) { + unsafe fn set_border_bottom(&self, border_bottom: Length) { if self.style_manager_mut().set_border_bottom(border_bottom) { self.mark_dirty_propagate(); } } - fn set_box_sizing(&self, box_sizing: BoxSizing) { + unsafe fn set_box_sizing(&self, box_sizing: BoxSizing) { if self.style_manager_mut().set_box_sizing(box_sizing) { self.mark_dirty_propagate(); } } - fn set_display(&self, display: Display) { + unsafe fn set_display(&self, display: Display) { if self.style_manager_mut().set_display(display) { self.mark_dirty_propagate(); } } - fn set_height(&self, height: Length) { + unsafe fn set_height(&self, height: Length) { if self.style_manager_mut().set_height(height) { self.mark_dirty_propagate(); } } - fn set_width(&self, width: Length) { + unsafe fn set_width(&self, width: Length) { if self.style_manager_mut().set_width(width) { self.mark_dirty_propagate(); } } - fn set_left(&self, left: Length) { + unsafe fn set_left(&self, left: Length) { if self.style_manager_mut().set_left(left) { self.mark_dirty_propagate(); } } - fn set_right(&self, right: Length) { + unsafe fn set_right(&self, right: Length) { if self.style_manager_mut().set_right(right) { self.mark_dirty_propagate(); } } - fn set_top(&self, top: Length) { + unsafe fn set_top(&self, top: Length) { if self.style_manager_mut().set_top(top) { self.mark_dirty_propagate(); } } - fn set_bottom(&self, bottom: Length) { + unsafe fn set_bottom(&self, bottom: Length) { if self.style_manager_mut().set_bottom(bottom) { self.mark_dirty_propagate(); } } - fn set_flex_shrink(&self, flex_shrink: f32) { + unsafe fn set_flex_shrink(&self, flex_shrink: f32) { if self.style_manager_mut().set_flex_shrink(flex_shrink) { self.mark_dirty_propagate(); } } - fn set_flex_grow(&self, flex_grow: f32) { + unsafe fn set_flex_grow(&self, flex_grow: f32) { if self.style_manager_mut().set_flex_grow(flex_grow) { self.mark_dirty_propagate(); } } - fn set_flex_wrap(&self, flex_wrap: FlexWrap) { + unsafe fn set_flex_wrap(&self, flex_wrap: FlexWrap) { if self.style_manager_mut().set_flex_wrap(flex_wrap) { self.mark_dirty_propagate(); } } - fn set_flex_basis(&self, flex_basis: Length) { + unsafe fn set_flex_basis(&self, flex_basis: Length) { if self.style_manager_mut().set_flex_basis(flex_basis) { self.mark_dirty_propagate(); } } - fn set_justify_content(&self, justify_content: JustifyContent) { + unsafe fn set_justify_content(&self, justify_content: JustifyContent) { if self .style_manager_mut() .set_justify_content(justify_content) @@ -773,27 +749,27 @@ impl StyleSetter for Node { self.mark_dirty_propagate(); } } - fn set_position(&self, position: Position) { + unsafe fn set_position(&self, position: Position) { if self.style_manager_mut().set_position(position) { self.mark_dirty_propagate(); } } - fn set_overflow_x(&self, overflow_x: Overflow) { + unsafe fn set_overflow_x(&self, overflow_x: Overflow) { if self.style_manager_mut().set_overflow_x(overflow_x) { self.mark_dirty_propagate(); } } - fn set_overflow_y(&self, overflow_y: Overflow) { + unsafe fn set_overflow_y(&self, overflow_y: Overflow) { if self.style_manager_mut().set_overflow_y(overflow_y) { self.mark_dirty_propagate(); } } - fn set_writing_mode(&self, writing_mode: WritingMode) { + unsafe fn set_writing_mode(&self, writing_mode: WritingMode) { if self.style_manager_mut().set_writing_mode(writing_mode) { self.mark_dirty_propagate(); } } - fn set_margin(&self, margin: Length) { + unsafe fn set_margin(&self, margin: Length) { let top_changed = self.style_manager_mut().set_margin_top(margin); let right_changed = self.style_manager_mut().set_margin_right(margin); let bottom_changed = self.style_manager_mut().set_margin_bottom(margin); @@ -802,48 +778,48 @@ impl StyleSetter for Node { self.mark_dirty_propagate(); } } - fn set_margin_bottom(&self, margin_bottom: Length) { + unsafe fn set_margin_bottom(&self, margin_bottom: Length) { if self.style_manager_mut().set_margin_bottom(margin_bottom) { self.mark_dirty_propagate(); } } - fn set_margin_left(&self, margin_left: Length) { + unsafe fn set_margin_left(&self, margin_left: Length) { if self.style_manager_mut().set_margin_left(margin_left) { self.mark_dirty_propagate(); } } - fn set_margin_right(&self, margin_right: Length) { + unsafe fn set_margin_right(&self, margin_right: Length) { if self.style_manager_mut().set_margin_right(margin_right) { self.mark_dirty_propagate(); } } - fn set_margin_top(&self, margin_top: Length) { + unsafe fn set_margin_top(&self, margin_top: Length) { if self.style_manager_mut().set_margin_top(margin_top) { self.mark_dirty_propagate(); } } - fn set_max_height(&self, max_height: Length) { + unsafe fn set_max_height(&self, max_height: Length) { if self.style_manager_mut().set_max_height(max_height) { self.mark_dirty_propagate(); } } - fn set_max_width(&self, max_width: Length) { + unsafe fn set_max_width(&self, max_width: Length) { if self.style_manager_mut().set_max_width(max_width) { self.mark_dirty_propagate(); } } - fn set_min_height(&self, min_height: Length) { + unsafe fn set_min_height(&self, min_height: Length) { if self.style_manager_mut().set_min_height(min_height) { self.mark_dirty_propagate(); } } - fn set_min_width(&self, min_width: Length) { + unsafe fn set_min_width(&self, min_width: Length) { if self.style_manager_mut().set_min_width(min_width) { self.mark_dirty_propagate(); } } - fn set_padding(&self, padding: Length) { + unsafe fn set_padding(&self, padding: Length) { let top_changed = self.style_manager_mut().set_padding_top(padding); let right_changed = self.style_manager_mut().set_padding_right(padding); let bottom_changed = self.style_manager_mut().set_padding_bottom(padding); @@ -852,32 +828,32 @@ impl StyleSetter for Node { self.mark_dirty_propagate(); } } - fn set_padding_left(&self, padding_left: Length) { + unsafe fn set_padding_left(&self, padding_left: Length) { if self.style_manager_mut().set_padding_left(padding_left) { self.mark_dirty_propagate(); } } - fn set_padding_right(&self, padding_right: Length) { + unsafe fn set_padding_right(&self, padding_right: Length) { if self.style_manager_mut().set_padding_right(padding_right) { self.mark_dirty_propagate(); } } - fn set_padding_top(&self, padding_top: Length) { + unsafe fn set_padding_top(&self, padding_top: Length) { if self.style_manager_mut().set_padding_top(padding_top) { self.mark_dirty_propagate(); } } - fn set_padding_bottom(&self, padding_bottom: Length) { + unsafe fn set_padding_bottom(&self, padding_bottom: Length) { if self.style_manager_mut().set_padding_bottom(padding_bottom) { self.mark_dirty_propagate(); } } - fn set_order(&self, order: i32) { + unsafe fn set_order(&self, order: i32) { if self.style_manager_mut().set_order(order) { self.mark_dirty_propagate(); } } - fn set_text_align(&self, text_align: TextAlign) { + unsafe fn set_text_align(&self, text_align: TextAlign) { if self.style_manager_mut().set_text_align(text_align) { self.mark_dirty_propagate(); } @@ -897,10 +873,10 @@ mod test { fn append_child() { let (node_a, node_a_ptr) = new_node(); let (node_b, node_b_ptr) = new_node(); - node_a.append_child(node_b_ptr); - assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); - assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_b)); unsafe { + node_a.append_child(node_b_ptr); + assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); + assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_b)); drop(Box::from_raw(node_a_ptr)); drop(Box::from_raw(node_b_ptr)); } @@ -910,13 +886,13 @@ mod test { let (node_a, node_a_ptr) = new_node(); let (node_b, node_b_ptr) = new_node(); let (node_c, node_c_ptr) = new_node(); - node_a.insert_child_at(node_b_ptr, 0); - node_a.insert_child_at(node_c_ptr, 0); - assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); - assert!(std::ptr::eq(node_a, node_c.parent().unwrap())); - assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_c)); - assert!(std::ptr::eq(node_a.get_child_at(1).unwrap(), node_b)); unsafe { + node_a.insert_child_at(node_b_ptr, 0); + node_a.insert_child_at(node_c_ptr, 0); + assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); + assert!(std::ptr::eq(node_a, node_c.parent().unwrap())); + assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_c)); + assert!(std::ptr::eq(node_a.get_child_at(1).unwrap(), node_b)); drop(Box::from_raw(node_a_ptr)); drop(Box::from_raw(node_b_ptr)); drop(Box::from_raw(node_c_ptr)); @@ -927,13 +903,13 @@ mod test { fn remove_child() { let (node_a, node_a_ptr) = new_node(); let (node_b, node_b_ptr) = new_node(); - node_a.insert_child_at(node_b_ptr, 0); - assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); - assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_b)); - node_a.remove_child(node_b_ptr); - assert!(node_b.parent().is_none()); - assert_eq!(node_a.children_len(), 0usize); unsafe { + node_a.insert_child_at(node_b_ptr, 0); + assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); + assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_b)); + node_a.remove_child(node_b_ptr); + assert!(node_b.parent().is_none()); + assert_eq!(node_a.children_len(), 0usize); drop(Box::from_raw(node_a_ptr)); drop(Box::from_raw(node_b_ptr)); } @@ -943,13 +919,13 @@ mod test { fn remove_child_at() { let (node_a, node_a_ptr) = new_node(); let (node_b, node_b_ptr) = new_node(); - node_a.insert_child_at(node_b_ptr, 0); - assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); - assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_b)); - node_a.remove_child_at(0); - assert_eq!(node_a.children_len(), 0usize); - assert!(node_b.parent().is_none()); unsafe { + node_a.insert_child_at(node_b_ptr, 0); + assert!(std::ptr::eq(node_a, node_b.parent().unwrap())); + assert!(std::ptr::eq(node_a.get_child_at(0).unwrap(), node_b)); + node_a.remove_child_at(0); + assert_eq!(node_a.children_len(), 0usize); + assert!(node_b.parent().is_none()); drop(Box::from_raw(node_a_ptr)); drop(Box::from_raw(node_b_ptr)); } diff --git a/float-pigment-forest/tests/mod.rs b/float-pigment-forest/tests/mod.rs index e5570f2..df5b98f 100644 --- a/float-pigment-forest/tests/mod.rs +++ b/float-pigment-forest/tests/mod.rs @@ -147,15 +147,17 @@ impl TestCtx { ); } - node.for_each_child_node(|node, _| { - self.update_layout_pos_recursive( - node, - Some(( - parent_offset.unwrap_or((Len::zero(), Len::zero())).0 + position.left, - parent_offset.unwrap_or((Len::zero(), Len::zero())).1 + position.top, - )), - ) - }); + unsafe { + node.for_each_child_node(|node, _| { + self.update_layout_pos_recursive( + node, + Some(( + parent_offset.unwrap_or((Len::zero(), Len::zero())).0 + position.left, + parent_offset.unwrap_or((Len::zero(), Len::zero())).1 + position.top, + )), + ) + }); + } } #[inline] pub fn layout(&mut self, dump_style: bool) { @@ -278,7 +280,7 @@ impl TestCtx { }; let mut node_props = NodeProperties::new(parent_node_props); if let Some(style) = e.attributes().get("style") { - TestCtx::set_style(&*node, &style, &mut node_props, parent_node_props); + unsafe { TestCtx::set_style(&*node, &style, &mut node_props, parent_node_props); } } self.set_expect_layout_pos(node, e.attributes()); e.children_mut().iter().for_each(|item| { @@ -316,7 +318,7 @@ impl TestCtx { } // style - pub fn set_style( + pub unsafe fn set_style( node: &Node, style: &str, node_props: &mut NodeProperties,