Feature flag calc values (#806)
Signed-off-by: Nico Burns <nico@nicoburns.com>
8437796cc084de78ee04e2d940086954c924cb98 · por Nico Burns · (hace 1 año) · padre bd0150f5f · ver el árbol en este commit
Delta semántico · 16
src/compute/grid/track_sizing.rs
src/style/compact_length.rs
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2d9c89742..46148c410 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -78,6 +78,15 @@ jobs:
test-features-default-except-content-size:
name: "Test Suite [default except content_size]"
runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo build --no-default-features --features std,taffy_tree,grid,flexbox,block_layout
+ - run: cargo test --tests --no-default-features --features std,taffy_tree,grid,flexbox,block_layout,calc
+
+ test-features-default-except-calc:
+ name: "Test Suite [default except calc]"
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
@@ -92,7 +101,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- run: cargo build --no-default-features --features std
- run: cargo build --no-default-features --features std,taffy_tree
- - run: cargo test --tests --no-default-features --features std,taffy_tree
+ - run: cargo test --tests --no-default-features --features std,taffy_tree,calc
# With std feature
test-features-flexbox:
diff --git a/Cargo.toml b/Cargo.toml
index c7bba5fa5..1a09ec92a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -40,6 +40,7 @@ default = [
"flexbox",
"grid",
"block_layout",
+ "calc",
"content_size",
"detailed_layout_info",
]
@@ -53,6 +54,8 @@ block_layout = []
flexbox = []
## Enables the CSS Grid layout algorithm. See [`compute_grid_layout`](crate::compute_grid_layout).
grid = ["alloc", "dep:grid"]
+## Enables calc() values for all layout algorithms
+calc = []
## Causes all algorithms to compute and output a content size for each node
content_size = []
## Causes algorithms to stores detailed information of the nodes in TaffyTree, with only CSS Grid supporting this.
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index 0b353b19a..49a09e365 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -612,6 +612,7 @@ fn resolve_intrinsic_track_sizes<Tree: LayoutPartialTree>(
track.base_size
}
// Handle calc() like percentage
+ #[cfg(feature = "calc")]
_ if track.min_track_sizing_function.0.is_calc() => {
if axis_inner_node_size.is_none() {
f32_max(track.base_size, item_sizer.min_content_contribution(item))
diff --git a/src/style/compact_length.rs b/src/style/compact_length.rs
index 89280f621..0a4b7f799 100644
--- a/src/style/compact_length.rs
+++ b/src/style/compact_length.rs
@@ -41,12 +41,6 @@ mod compat {
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
std::compile_error!("Taffy only supports targets with a pointer width of 32 or 64 bits");
-// /// Error serializing
-// enum SerializeErr {
-// /// Serializing calc values is not supported
-// CalcValue,
-// }
-
/// CompactLengthInner implementation for 64 bit platforms
#[cfg(target_pointer_width = "64")]
mod inner {
@@ -92,6 +86,7 @@ mod inner {
/// Get the calc tag (low 3 bits)
#[inline(always)]
+ #[cfg(feature = "calc")]
pub(super) fn calc_tag(self) -> usize {
(self.tagged_ptr as usize) & CALC_TAG_MASK
}
@@ -167,6 +162,7 @@ mod inner {
/// Get the calc tag (low 3 bits)
#[inline(always)]
+ #[cfg(feature = "calc")]
pub(super) fn calc_tag(self) -> usize {
self.tag
}
@@ -214,6 +210,7 @@ pub struct CompactLength(CompactLengthInner);
impl CompactLength {
/// The tag indicating a calc() value
+ #[cfg(feature = "calc")]
pub const CALC_TAG: usize = 0b000;
/// The tag indicating a length value
pub const LENGTH_TAG: usize = 0b0000_0001;
@@ -254,6 +251,7 @@ impl CompactLength {
///
/// The low 3 bits are used as a tag value and will be returned as 0.
#[inline]
+ #[cfg(feature = "calc")]
pub fn calc(ptr: *const ()) -> Self {
assert_ne!(ptr as u64, 0);
assert_eq!(ptr as u64 & 0b111, 0);
@@ -332,12 +330,14 @@ impl CompactLength {
/// Get the calc pointer of the `CompactLength`
#[inline(always)]
+ #[cfg(feature = "calc")]
pub fn calc_value(self) -> *const () {
self.0.ptr()
}
/// Returns true if the value is 0 px
#[inline(always)]
+ #[cfg(feature = "calc")]
pub fn is_calc(self) -> bool {
self.0.calc_tag() == 0
}
@@ -426,8 +426,14 @@ impl CompactLength {
/// Whether the track sizing functions depends on the size of the parent node
#[inline(always)]
pub fn uses_percentage(self) -> bool {
- // TODO: handle calc() values
- matches!(self.tag(), CompactLength::PERCENT_TAG | CompactLength::FIT_CONTENT_PERCENT_TAG) || self.is_calc()
+ #[cfg(feature = "calc")]
+ {
+ matches!(self.tag(), CompactLength::PERCENT_TAG | CompactLength::FIT_CONTENT_PERCENT_TAG) || self.is_calc()
+ }
+ #[cfg(not(feature = "calc"))]
+ {
+ matches!(self.tag(), CompactLength::PERCENT_TAG | CompactLength::FIT_CONTENT_PERCENT_TAG)
+ }
}
/// Resolve percentage values against the passed parent_size, returning Some(value)
@@ -440,6 +446,7 @@ impl CompactLength {
) -> Option<f32> {
match self.tag() {
CompactLength::PERCENT_TAG => Some(self.value() * parent_size),
+ #[cfg(feature = "calc")]
_ if self.is_calc() => Some(calc_resolver(self.0.ptr(), parent_size)),
_ => None,
}
@@ -490,11 +497,17 @@ impl serde::Serialize for CompactLength {
where
S: serde::Serializer,
{
- if self.tag() == Self::CALC_TAG {
- Err(serde::ser::Error::custom("Cannot serialize Calc value"))
- } else {
- serializer.serialize_u64(self.0.serialized())
+ #[cfg(feature = "calc")]
+ {
+ if self.tag() == Self::CALC_TAG {
+ Err(serde::ser::Error::custom("Cannot serialize Calc value"))
+ } else {
+ serializer.serialize_u64(self.0.serialized())
+ }
}
+
+ #[cfg(not(feature = "calc"))]
+ serializer.serialize_u64(self.0.serialized())
}
}
diff --git a/src/style/dimension.rs b/src/style/dimension.rs
index 2391d5ba3..ad270e48c 100644
--- a/src/style/dimension.rs
+++ b/src/style/dimension.rs
@@ -43,6 +43,7 @@ impl LengthPercentage {
///
/// The low 3 bits are used as a tag value and will be returned as 0.
#[inline(always)]
+ #[cfg(feature = "calc")]
pub fn calc(ptr: *const ()) -> Self {
Self(CompactLength::calc(ptr))
}
@@ -133,6 +134,7 @@ impl LengthPercentageAuto {
///
/// The low 3 bits are used as a tag value and will be returned as 0.
#[inline]
+ #[cfg(feature = "calc")]
pub fn calc(ptr: *const ()) -> Self {
Self(CompactLength::calc(ptr))
}
@@ -160,6 +162,7 @@ impl LengthPercentageAuto {
CompactLength::LENGTH_TAG => Some(self.0.value()),
CompactLength::PERCENT_TAG => Some(context * self.0.value()),
CompactLength::AUTO_TAG => None,
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => Some(calc_resolver(self.0.calc_value(), context)),
_ => unreachable!("LengthPercentageAuto values cannot be constructed with other tags"),
}
@@ -249,6 +252,7 @@ impl Dimension {
///
/// The low 3 bits are used as a tag value and will be returned as 0.
#[inline]
+ #[cfg(feature = "calc")]
pub fn calc(ptr: *const ()) -> Self {
Self(CompactLength::calc(ptr))
}
diff --git a/src/style/grid.rs b/src/style/grid.rs
index 9f800a25b..41f5bd09b 100644
--- a/src/style/grid.rs
+++ b/src/style/grid.rs
@@ -524,6 +524,7 @@ impl MaxTrackSizingFunction {
///
/// The low 3 bits are used as a tag value and will be returned as 0.
#[inline]
+ #[cfg(feature = "calc")]
pub fn calc(ptr: *const ()) -> Self {
Self(CompactLength::calc(ptr))
}
@@ -597,6 +598,7 @@ impl MaxTrackSizingFunction {
match self.0.tag() {
CompactLength::LENGTH_TAG => true,
CompactLength::PERCENT_TAG => parent_size.is_some(),
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => parent_size.is_some(),
_ => false,
}
@@ -614,6 +616,7 @@ impl MaxTrackSizingFunction {
match self.0.tag() {
CompactLength::LENGTH_TAG => Some(self.0.value()),
CompactLength::PERCENT_TAG => parent_size.map(|size| self.0.value() * size),
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => parent_size.map(|size| calc_resolver(self.0.calc_value(), size)),
_ => None,
}
@@ -768,6 +771,7 @@ impl MinTrackSizingFunction {
///
/// The low 3 bits are used as a tag value and will be returned as 0.
#[inline]
+ #[cfg(feature = "calc")]
pub fn calc(ptr: *const ()) -> Self {
Self(CompactLength::calc(ptr))
}
@@ -833,6 +837,7 @@ impl MinTrackSizingFunction {
match self.0.tag() {
CompactLength::LENGTH_TAG => Some(self.0.value()),
CompactLength::PERCENT_TAG => parent_size.map(|size| self.0.value() * size),
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => parent_size.map(|size| calc_resolver(self.0.calc_value(), size)),
_ => None,
}
@@ -852,7 +857,14 @@ impl MinTrackSizingFunction {
/// Whether the track sizing functions depends on the size of the parent node
#[inline(always)]
pub fn uses_percentage(self) -> bool {
- matches!(self.0.tag(), CompactLength::PERCENT_TAG) || self.0.is_calc()
+ #[cfg(feature = "calc")]
+ {
+ matches!(self.0.tag(), CompactLength::PERCENT_TAG) || self.0.is_calc()
+ }
+ #[cfg(not(feature = "calc"))]
+ {
+ matches!(self.0.tag(), CompactLength::PERCENT_TAG)
+ }
}
}
diff --git a/src/tree/traits.rs b/src/tree/traits.rs
index 191de42cb..a5b208b42 100644
--- a/src/tree/traits.rs
+++ b/src/tree/traits.rs
@@ -181,7 +181,12 @@ pub trait LayoutPartialTree: TraversePartialTree {
fn get_core_container_style(&self, node_id: NodeId) -> Self::CoreContainerStyle<'_>;
/// Resolve calc value
- fn resolve_calc_value(&self, val: *const (), basis: f32) -> f32;
+ #[inline(always)]
+ fn resolve_calc_value(&self, val: *const (), basis: f32) -> f32 {
+ let _ = val;
+ let _ = basis;
+ 0.0
+ }
/// Set the node's unrounded layout
fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout);
@@ -366,9 +371,17 @@ pub(crate) trait LayoutPartialTreeExt: LayoutPartialTree {
/// Alias to `resolve_calc_value` with a shorter function name
#[inline(always)]
+ #[cfg(feature = "calc")]
fn calc(&self, val: *const (), basis: f32) -> f32 {
self.resolve_calc_value(val, basis)
}
+
+ /// Alias to `resolve_calc_value` with a shorter function name
+ #[inline(always)]
+ #[cfg(not(feature = "calc"))]
+ fn calc(&self, _val: *const (), _basis: f32) -> f32 {
+ 0.0
+ }
}
impl<T: LayoutPartialTree> LayoutPartialTreeExt for T {}
diff --git a/src/util/resolve.rs b/src/util/resolve.rs
index a0e47b0ee..c40fec300 100644
--- a/src/util/resolve.rs
+++ b/src/util/resolve.rs
@@ -32,6 +32,7 @@ impl MaybeResolve<Option<f32>, Option<f32>> for LengthPercentage {
match self.0.tag() {
CompactLength::LENGTH_TAG => Some(self.0.value()),
CompactLength::PERCENT_TAG => context.map(|dim| dim * self.0.value()),
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => context.map(|dim| calc(self.0.calc_value(), dim)),
_ => unreachable!(),
}
@@ -46,6 +47,7 @@ impl MaybeResolve<Option<f32>, Option<f32>> for LengthPercentageAuto {
CompactLength::AUTO_TAG => None,
CompactLength::LENGTH_TAG => Some(self.0.value()),
CompactLength::PERCENT_TAG => context.map(|dim| dim * self.0.value()),
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => context.map(|dim| calc(self.0.calc_value(), dim)),
_ => unreachable!(),
}
@@ -61,6 +63,7 @@ impl MaybeResolve<Option<f32>, Option<f32>> for Dimension {
CompactLength::AUTO_TAG => None,
CompactLength::LENGTH_TAG => Some(self.0.value()),
CompactLength::PERCENT_TAG => context.map(|dim| dim * self.0.value()),
+ #[cfg(feature = "calc")]
_ if self.0.is_calc() => context.map(|dim| calc(self.0.calc_value(), dim)),
_ => unreachable!(),
}