Semantic delta · 17
src/compute/grid/types/grid_item.rs
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 94e543574..b5a4e0e7d 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -638,16 +638,15 @@ fn determine_flex_base_size(
)
.with_cross(dir, cross_axis_available_space);
- break 'flex_basis tree
- .measure_child_size(
- child.node,
- child_known_dimensions,
- child_parent_size,
- child_available_space,
- SizingMode::ContentSize,
- Line::FALSE,
- )
- .main(dir);
+ break 'flex_basis tree.measure_child_size(
+ child.node,
+ child_known_dimensions,
+ child_parent_size,
+ child_available_space,
+ SizingMode::ContentSize,
+ dir.main_axis(),
+ Line::FALSE,
+ );
};
// Floor flex-basis by the padding_border_sum (floors inner_flex_basis at zero)
@@ -686,7 +685,7 @@ fn determine_flex_base_size(
child.min_size.or(child.overflow.map(Overflow::maybe_into_automatic_min_size).into()).main(dir);
child.resolved_minimum_main_size = style_min_main_size.unwrap_or({
- let min_content_size = {
+ let min_content_main_size = {
let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
tree.measure_child_size(
@@ -695,14 +694,16 @@ fn determine_flex_base_size(
child_parent_size,
child_available_space,
SizingMode::ContentSize,
+ dir.main_axis(),
Line::FALSE,
)
};
// 4.5. Automatic Minimum Size of Flex Items
// https://www.w3.org/TR/css-flexbox-1/#min-size-auto
- let clamped_min_content_size = min_content_size.maybe_min(child.size).maybe_min(child.max_size);
- clamped_min_content_size.maybe_max(padding_border_axes_sums).main(dir)
+ let clamped_min_content_size =
+ min_content_main_size.maybe_min(child.size.main(dir)).maybe_min(child.max_size.main(dir));
+ clamped_min_content_size.maybe_max(padding_border_axes_sums.main(dir))
});
}
}
@@ -899,17 +900,15 @@ fn determine_container_main_size(
// Either the min- or max- content size depending on which constraint we are sizing under.
// TODO: Optimise by using already computed values where available
- let content_main_size = tree
- .measure_child_size(
- item.node,
- Size::NONE,
- constants.node_inner_size,
- child_available_space,
- SizingMode::InherentSize,
- Line::FALSE,
- )
- .main(constants.dir)
- + item.margin.main_axis_sum(constants.dir);
+ let content_main_size = tree.measure_child_size(
+ item.node,
+ Size::NONE,
+ constants.node_inner_size,
+ child_available_space,
+ SizingMode::InherentSize,
+ dir.main_axis(),
+ Line::FALSE,
+ ) + item.margin.main_axis_sum(constants.dir);
// This is somewhat bizarre in that it's asymetrical depending whether the flex container is a column or a row.
//
@@ -1231,9 +1230,9 @@ fn determine_hypothetical_cross_size(
height: if constants.is_row { child_available_cross } else { child_known_main },
},
SizingMode::ContentSize,
+ constants.dir.cross_axis(),
Line::FALSE,
)
- .cross(constants.dir)
.maybe_clamp(child.min_size.cross(constants.dir), child.max_size.cross(constants.dir))
.max(padding_border_sum)
});
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index e80cd4c87..86c4a1284 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -347,9 +347,9 @@ impl GridItem {
None => AvailableSpace::MinContent,
}),
SizingMode::InherentSize,
+ axis.as_abs_naive(),
Line::FALSE,
)
- .get(axis)
}
/// Retrieve the item's min content contribution from the cache or compute it using the provided parameters
@@ -386,9 +386,9 @@ impl GridItem {
None => AvailableSpace::MaxContent,
}),
SizingMode::InherentSize,
+ axis.as_abs_naive(),
Line::FALSE,
)
- .get(axis)
}
/// Retrieve the item's max content contribution from the cache or compute it using the provided parameters
diff --git a/src/geometry.rs b/src/geometry.rs
index 006a21491..8f781443f 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -61,12 +61,23 @@ pub enum AbstractAxis {
impl AbstractAxis {
/// Returns the other variant of the enum
+ #[inline]
pub fn other(&self) -> AbstractAxis {
match *self {
AbstractAxis::Inline => AbstractAxis::Block,
AbstractAxis::Block => AbstractAxis::Inline,
}
}
+
+ /// Convert an `AbstractAxis` into an `AbsoluteAxis` naively assuming that the Inline axis is Horizontal
+ /// This is currently always true, but will change if Taffy ever implements the `writing_mode` property
+ #[inline]
+ pub fn as_abs_naive(&self) -> AbsoluteAxis {
+ match self {
+ AbstractAxis::Inline => AbsoluteAxis::Horizontal,
+ AbstractAxis::Block => AbsoluteAxis::Vertical,
+ }
+ }
}
/// Container that holds an item in each absolute axis without specifying
diff --git a/src/style/flex.rs b/src/style/flex.rs
index 8cce6d051..c24f488d8 100644
--- a/src/style/flex.rs
+++ b/src/style/flex.rs
@@ -1,5 +1,7 @@
//! Style types for Flexbox layout
+use crate::geometry::AbsoluteAxis;
+
/// Controls whether flex items are forced onto one line or can wrap onto multiple lines.
///
/// Defaults to [`FlexWrap::NoWrap`]
@@ -78,6 +80,24 @@ impl FlexDirection {
pub(crate) fn is_reverse(self) -> bool {
matches!(self, Self::RowReverse | Self::ColumnReverse)
}
+
+ #[inline]
+ /// The `AbsoluteAxis` that corresponds to the main axis
+ pub(crate) fn main_axis(self) -> AbsoluteAxis {
+ match self {
+ Self::Row | Self::RowReverse => AbsoluteAxis::Horizontal,
+ Self::Column | Self::ColumnReverse => AbsoluteAxis::Vertical,
+ }
+ }
+
+ #[inline]
+ /// The `AbsoluteAxis` that corresponds to the cross axis
+ pub(crate) fn cross_axis(self) -> AbsoluteAxis {
+ match self {
+ Self::Row | Self::RowReverse => AbsoluteAxis::Vertical,
+ Self::Column | Self::ColumnReverse => AbsoluteAxis::Horizontal,
+ }
+ }
}
#[cfg(test)]
diff --git a/src/tree/layout.rs b/src/tree/layout.rs
index 27bd43571..2c43128f4 100644
--- a/src/tree/layout.rs
+++ b/src/tree/layout.rs
@@ -1,5 +1,5 @@
//! Final data structures that represent the high-level UI layout
-use crate::geometry::{Line, Point, Size};
+use crate::geometry::{AbsoluteAxis, Line, Point, Size};
use crate::prelude::TaffyMaxContent;
use crate::style::AvailableSpace;
use crate::util::sys::{f32_max, f32_min};
@@ -71,9 +71,46 @@ impl CollapsibleMarginSet {
}
}
+/// An axis that layout algorithms can be requested to compute a size for
+#[derive(Debug, Copy, Clone)]
+pub enum RequestedAxis {
+ /// The horizontal axis
+ Horizontal,
+ /// The vertical axis
+ Vertical,
+ /// Both axes
+ Both,
+}
+
+impl From<AbsoluteAxis> for RequestedAxis {
+ fn from(value: AbsoluteAxis) -> Self {
+ match value {
+ AbsoluteAxis::Horizontal => RequestedAxis::Horizontal,
+ AbsoluteAxis::Vertical => RequestedAxis::Vertical,
+ }
+ }
+}
+impl TryFrom<RequestedAxis> for AbsoluteAxis {
+ type Error = ();
+ fn try_from(value: RequestedAxis) -> Result<Self, Self::Error> {
+ match value {
+ RequestedAxis::Horizontal => Ok(AbsoluteAxis::Horizontal),
+ RequestedAxis::Vertical => Ok(AbsoluteAxis::Vertical),
+ RequestedAxis::Both => Err(()),
+ }
+ }
+}
+
/// A struct containing the inputs constraints/hints for laying out a node, which are passed in by the parent
#[derive(Debug, Copy, Clone)]
pub struct LayoutInput {
+ /// Whether we only need to know the Node's size, or whe
+ pub run_mode: RunMode,
+ /// Whether a Node's style sizes should be taken into account or ignored
+ pub sizing_mode: SizingMode,
+ /// Which axis we need the size of
+ pub axis: RequestedAxis,
+
/// Known dimensions represent dimensions (width/height) which should be taken as fixed when performing layout.
/// For example, if known_dimensions.width is set to Some(WIDTH) then this means something like:
///
@@ -89,10 +126,6 @@ pub struct LayoutInput {
/// Available space represents an amount of space to layout into, and is used as a soft constraint
/// for the purpose of wrapping.
pub available_space: Size<AvailableSpace>,
- /// Whether a Node's style sizes should be taken into account or ignored
- pub sizing_mode: SizingMode,
- /// Whether we only need to know the Node's size, or whe
- pub run_mode: RunMode,
/// Specific to CSS Block layout. Used for correctly computing margin collapsing. You probably want to set this to `Line::FALSE`.
pub vertical_margins_are_collapsible: Line<bool>,
}
@@ -107,6 +140,7 @@ impl LayoutInput {
parent_size: Size::NONE,
available_space: Size::MAX_CONTENT,
sizing_mode: SizingMode::InherentSize,
+ axis: RequestedAxis::Both,
vertical_margins_are_collapsible: Line::FALSE,
};
}
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
index fb9fee7c5..d89ab1a23 100644
--- a/src/tree/mod.rs
+++ b/src/tree/mod.rs
@@ -1,6 +1,6 @@
//! Contains both [a high-level interface to Taffy](crate::Taffy) using a ready-made node tree, and [a trait for defining a custom node trees](crate::tree::LayoutTree) / utility types to help with that.
-use crate::geometry::{Line, Size};
+use crate::geometry::{AbsoluteAxis, Line, Size};
use crate::style::{AvailableSpace, Style};
// Submodules
@@ -15,7 +15,7 @@ mod taffy_tree;
#[cfg(feature = "taffy_tree")]
pub use taffy_tree::{Taffy, TaffyError, TaffyResult};
mod layout;
-pub use layout::{CollapsibleMarginSet, Layout, LayoutInput, LayoutOutput, RunMode, SizingMode};
+pub use layout::{CollapsibleMarginSet, Layout, LayoutInput, LayoutOutput, RequestedAxis, RunMode, SizingMode};
/// This if the core abstraction in Taffy. Any type that *correctly* implements `PartialLayoutTree` can be laid out using Taffy's algorithms.
///
@@ -64,6 +64,7 @@ pub trait LayoutTree: PartialLayoutTree {
pub(crate) trait PartialLayoutTreeExt: PartialLayoutTree {
/// Compute the size of the node given the specified constraints
#[inline(always)]
+ #[allow(clippy::too_many_arguments)]
fn measure_child_size(
&mut self,
node_id: NodeId,
@@ -71,8 +72,9 @@ pub(crate) trait PartialLayoutTreeExt: PartialLayoutTree {
parent_size: Size<Option<f32>>,
available_space: Size<AvailableSpace>,
sizing_mode: SizingMode,
+ axis: AbsoluteAxis,
vertical_margins_are_collapsible: Line<bool>,
- ) -> Size<f32> {
+ ) -> f32 {
self.compute_child_layout(
node_id,
LayoutInput {
@@ -80,11 +82,13 @@ pub(crate) trait PartialLayoutTreeExt: PartialLayoutTree {
parent_size,
available_space,
sizing_mode,
+ axis: axis.into(),
run_mode: RunMode::ComputeSize,
vertical_margins_are_collapsible,
},
)
.size
+ .get_abs(axis)
}
/// Perform a full layout on the node given the specified constraints
@@ -105,6 +109,7 @@ pub(crate) trait PartialLayoutTreeExt: PartialLayoutTree {
parent_size,
available_space,
sizing_mode,
+ axis: RequestedAxis::Both,
run_mode: RunMode::PerformLayout,
vertical_margins_are_collapsible,
},