HTML 5544Rust 88Markdown 11TOML 91926 Sutichaykuna
Enable correct image measure functions (#661)
* Use InherentSize mode when sizing absolute children
* Add style parameter to measure functions
* Make MaybeMath, MaybeResolve, and ResolveOrZero traits public
* Fix clippy lints
diff --git a/examples/cosmic_text.rs b/examples/cosmic_text.rs
index d70de60b6..40ceef6a2 100644
--- a/examples/cosmic_text.rs
+++ b/examples/cosmic_text.rs
@@ -109,7 +109,7 @@ fn main() -> Result<(), taffy::TaffyError> {
Size::MAX_CONTENT,
// Note: this closure is a FnMut closure and can be used to borrow external context for the duration of layout
// For example, you may wish to borrow a global font registry and pass it into your text measuring function
- |known_dimensions, available_space, _node_id, node_context| {
+ |known_dimensions, available_space, _node_id, node_context, _style| {
measure_function(known_dimensions, available_space, node_context, &mut font_system)
},
)?;
diff --git a/examples/measure.rs b/examples/measure.rs
index d9943c4c9..9f68adb70 100644
--- a/examples/measure.rs
+++ b/examples/measure.rs
@@ -59,7 +59,7 @@ fn main() -> Result<(), taffy::TaffyError> {
Size::MAX_CONTENT,
// Note: this closure is a FnMut closure and can be used to borrow external context for the duration of layout
// For example, you may wish to borrow a global font registry and pass it into your text measuring function
- |known_dimensions, available_space, _node_id, node_context| {
+ |known_dimensions, available_space, _node_id, node_context, _style| {
measure_function(known_dimensions, available_space, node_context, &font_metrics)
},
)?;
diff --git a/src/compute/common/alignment.rs b/src/compute/common/alignment.rs
index f2c7170a2..bebd7f74a 100644
--- a/src/compute/common/alignment.rs
+++ b/src/compute/common/alignment.rs
@@ -36,6 +36,7 @@ pub(crate) fn apply_alignment_fallback(
/// Generic alignment function that is used:
/// - For both align-content and justify-content alignment
/// - For both the Flexbox and CSS Grid algorithms
+///
/// CSS Grid does not apply gaps as part of alignment, so the gap parameter should
/// always be set to zero for CSS Grid.
pub(crate) fn compute_alignment_offset(
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 464cd0a91..67b094dfb 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -509,6 +509,7 @@ fn generate_anonymous_flex_items(
/// # [9.2. Line Length Determination](https://www.w3.org/TR/css-flexbox-1/#line-sizing)
///
/// - [**Determine the available main and cross space for the flex items**](https://www.w3.org/TR/css-flexbox-1/#algo-available).
+///
/// For each dimension, if that dimension of the flex container’s content box is a definite size, use that;
/// if that dimension of the flex container is being sized under a min or max-content constraint, the available space in that dimension is that constraint;
/// otherwise, subtract the flex container’s margin, border, and padding from the space available to the flex container in that dimension and use that value.
@@ -1983,7 +1984,7 @@ fn perform_absolute_layout_on_absolute_children(
width: AvailableSpace::Definite(container_width.maybe_clamp(min_size.width, max_size.width)),
height: AvailableSpace::Definite(container_height.maybe_clamp(min_size.height, max_size.height)),
},
- SizingMode::ContentSize,
+ SizingMode::InherentSize,
Line::FALSE,
);
let measured_size = layout_output.size;
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index 8e5c73c9d..822d30798 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -134,6 +134,7 @@ where
/// - If the item’s computed preferred size behaves as auto or depends on the size of its containing block in the relevant axis:
/// Its minimum contribution is the outer size that would result from assuming the item’s used minimum size as its preferred size;
/// - Else the item’s minimum contribution is its min-content contribution.
+ ///
/// Because the minimum contribution often depends on the size of the item’s content, it is considered a type of intrinsic size contribution.
#[inline(always)]
fn minimum_contribution(&mut self, item: &mut GridItem, axis_tracks: &[GridTrack]) -> f32 {
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index ba18bc58a..8c33798a6 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -419,6 +419,7 @@ impl GridItem {
/// - If the item’s computed preferred size behaves as auto or depends on the size of its containing block in the relevant axis:
/// Its minimum contribution is the outer size that would result from assuming the item’s used minimum size as its preferred size;
/// - Else the item’s minimum contribution is its min-content contribution.
+ ///
/// Because the minimum contribution often depends on the size of the item’s content, it is considered a type of intrinsic size contribution.
/// See: https://www.w3.org/TR/css-grid-1/#min-size-auto
pub fn minimum_contribution(
diff --git a/src/compute/mod.rs b/src/compute/mod.rs
index f78a22df9..746997af4 100644
--- a/src/compute/mod.rs
+++ b/src/compute/mod.rs
@@ -131,6 +131,7 @@ where
/// parent-relative coordinates
/// - Compute width/height by first rounding the top/bottom/left/right and then computing the difference
/// rather than rounding the width/height directly
+///
/// See <https://github.com/facebook/yoga/commit/aa5b296ac78f7a22e1aeaf4891243c6bb76488e2> for more context
///
/// In order to prevent innacuracies caused by rounding already-rounded values, we read from `unrounded_layout`
diff --git a/src/lib.rs b/src/lib.rs
index 577abf778..f95d4c41c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -116,3 +116,4 @@ pub use crate::util::print_tree;
pub use crate::geometry::*;
pub use crate::style::*;
pub use crate::tree::*;
+pub use crate::util::*;
diff --git a/src/tree/taffy_tree.rs b/src/tree/taffy_tree.rs
index b465bed5a..664dc71cd 100644
--- a/src/tree/taffy_tree.rs
+++ b/src/tree/taffy_tree.rs
@@ -221,7 +221,8 @@ impl<NodeContext> PrintTree for TaffyTree<NodeContext> {
/// which makes the lifetimes of the context much more flexible.
pub(crate) struct TaffyView<'t, NodeContext, MeasureFunction>
where
- MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>,
{
/// A reference to the TaffyTree
pub(crate) taffy: &'t mut TaffyTree<NodeContext>,
@@ -232,7 +233,8 @@ where
// TraversePartialTree impl for TaffyView
impl<'t, NodeContext, MeasureFunction> TraversePartialTree for TaffyView<'t, NodeContext, MeasureFunction>
where
- MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>,
{
type ChildIter<'a> = TaffyTreeChildIter<'a> where Self: 'a;
@@ -254,14 +256,16 @@ where
// TraverseTree impl for TaffyView
impl<'t, NodeContext, MeasureFunction> TraverseTree for TaffyView<'t, NodeContext, MeasureFunction> where
- MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>
{
}
// LayoutPartialTree impl for TaffyView
impl<'t, NodeContext, MeasureFunction> LayoutPartialTree for TaffyView<'t, NodeContext, MeasureFunction>
where
- MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>,
{
#[inline(always)]
fn get_style(&self, node: NodeId) -> &Style {
@@ -320,7 +324,7 @@ where
let has_context = tree.taffy.nodes[node_key].has_context;
let node_context = has_context.then(|| tree.taffy.node_context_data.get_mut(node_key)).flatten();
let measure_function = |known_dimensions, available_space| {
- (tree.measure_function)(known_dimensions, available_space, node, node_context)
+ (tree.measure_function)(known_dimensions, available_space, node, node_context, style)
};
compute_leaf_layout(inputs, style, measure_function)
}
@@ -332,7 +336,8 @@ where
// RoundTree impl for TaffyView
impl<'t, NodeContext, MeasureFunction> RoundTree for TaffyView<'t, NodeContext, MeasureFunction>
where
- MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>,
{
#[inline(always)]
fn get_unrounded_layout(&self, node: NodeId) -> &Layout {
@@ -672,7 +677,8 @@ impl<NodeContext> TaffyTree<NodeContext> {
measure_function: MeasureFunction,
) -> Result<(), TaffyError>
where
- MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>,
{
let use_rounding = self.config.use_rounding;
let mut taffy_view = TaffyView { taffy: self, measure_function };
@@ -685,7 +691,7 @@ impl<NodeContext> TaffyTree<NodeContext> {
/// Updates the stored layout of the provided `node` and its children
pub fn compute_layout(&mut self, node: NodeId, available_space: Size<AvailableSpace>) -> Result<(), TaffyError> {
- self.compute_layout_with_measure(node, available_space, |_, _, _, _| Size::ZERO)
+ self.compute_layout_with_measure(node, available_space, |_, _, _, _, _| Size::ZERO)
}
/// Prints a debug representation of the tree's layout
@@ -697,7 +703,7 @@ impl<NodeContext> TaffyTree<NodeContext> {
/// Returns an instance of LayoutTree representing the TaffyTree
#[cfg(test)]
pub(crate) fn as_layout_tree(&mut self) -> impl LayoutPartialTree + '_ {
- TaffyView { taffy: self, measure_function: |_, _, _, _| Size::ZERO }
+ TaffyView { taffy: self, measure_function: |_, _, _, _, _| Size::ZERO }
}
}
@@ -714,6 +720,7 @@ mod tests {
_available_space: Size<AvailableSpace>,
_node_id: NodeId,
node_context: Option<&mut Size<f32>>,
+ _style: &Style,
) -> Size<f32> {
known_dimensions.unwrap_or(node_context.cloned().unwrap_or(Size::ZERO))
}
diff --git a/src/util/math.rs b/src/util/math.rs
index f9a43a678..35f5f60f7 100644
--- a/src/util/math.rs
+++ b/src/util/math.rs
@@ -8,7 +8,7 @@ use crate::style::AvailableSpace;
///
/// If the left-hand value is [`None`], these operations return [`None`].
/// If the right-hand value is [`None`], it is treated as zero.
-pub(crate) trait MaybeMath<In, Out> {
+pub trait MaybeMath<In, Out> {
/// Returns the minimum of `self` and `rhs`
fn maybe_min(self, rhs: In) -> Out;
diff --git a/src/util/mod.rs b/src/util/mod.rs
index 10312ea29..54615a199 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -3,8 +3,8 @@ mod math;
mod resolve;
pub(crate) mod sys;
-pub(crate) use math::MaybeMath;
-pub(crate) use resolve::{MaybeResolve, ResolveOrZero};
+pub use math::MaybeMath;
+pub use resolve::{MaybeResolve, ResolveOrZero};
#[doc(hidden)]
#[macro_use]
diff --git a/src/util/resolve.rs b/src/util/resolve.rs
index bc1dceaf8..a4d48b42d 100644
--- a/src/util/resolve.rs
+++ b/src/util/resolve.rs
@@ -9,7 +9,7 @@ use crate::style_helpers::TaffyZero;
/// a context-independent size or dimension.
///
/// Will return a `None` if it unable to resolve.
-pub(crate) trait MaybeResolve<In, Out> {
+pub trait MaybeResolve<In, Out> {
/// Resolve a dimension that might be dependent on a context, with `None` as fallback value
fn maybe_resolve(self, context: In) -> Out;
}
@@ -19,7 +19,7 @@ pub(crate) trait MaybeResolve<In, Out> {
/// a context-independent size or dimension.
///
/// Will return a default value if it unable to resolve.
-pub(crate) trait ResolveOrZero<TContext, TOutput: TaffyZero> {
+pub trait ResolveOrZero<TContext, TOutput: TaffyZero> {
/// Resolve a dimension that might be dependent on a context, with a default fallback value
fn resolve_or_zero(self, context: TContext) -> TOutput;
}
diff --git a/tests/caching.rs b/tests/caching.rs
index 74fce1aba..04e760049 100644
--- a/tests/caching.rs
+++ b/tests/caching.rs
@@ -16,6 +16,7 @@ mod caching {
_available_space: Size<AvailableSpace>,
_node_id: NodeId,
mut node_context: Option<&mut CountMeasure>,
+ _style: &Style,
) -> Size<f32> {
node_context.as_mut().unwrap().count += 1;
Size { width: known_dimensions.width.unwrap_or(50.0), height: known_dimensions.height.unwrap_or(50.0) }
diff --git a/tests/fixtures.rs b/tests/fixtures.rs
index e1f1b8851..ced2f8e99 100644
--- a/tests/fixtures.rs
+++ b/tests/fixtures.rs
@@ -19,13 +19,14 @@ struct TextMeasure {
#[allow(dead_code)]
fn test_measure_function(
- known_dimensions: taffy::geometry::Size<Option<f32>>,
- available_space: taffy::geometry::Size<taffy::style::AvailableSpace>,
- _node_id: taffy::tree::NodeId,
+ known_dimensions: taffy::Size<Option<f32>>,
+ available_space: taffy::Size<taffy::AvailableSpace>,
+ _node_id: taffy::NodeId,
node_context: Option<&mut TextMeasure>,
-) -> taffy::geometry::Size<f32> {
- use taffy::geometry::AbsoluteAxis;
+ _style: &taffy::Style,
+) -> taffy::Size<f32> {
use taffy::prelude::*;
+ use taffy::AbsoluteAxis;
const ZWS: char = '\u{200B}';
const H_WIDTH: f32 = 10.0;
diff --git a/tests/measure.rs b/tests/measure.rs
index be0afcab9..062147022 100644
--- a/tests/measure.rs
+++ b/tests/measure.rs
@@ -12,6 +12,7 @@ mod measure {
_available_space: Size<AvailableSpace>,
_node_id: NodeId,
node_context: Option<&mut FixedMeasure>,
+ _style: &Style,
) -> taffy::geometry::Size<f32> {
let size = node_context.copied().unwrap_or(FixedMeasure { width: 0.0, height: 0.0 });
Size {
@@ -29,6 +30,7 @@ mod measure {
_available_space: Size<AvailableSpace>,
_node_id: NodeId,
node_context: Option<&mut AspectRatioMeasure>,
+ _style: &Style,
) -> taffy::geometry::Size<f32> {
let Some(node_context) = node_context else { return Size::ZERO };
let width = known_dimensions.width.unwrap_or(node_context.width);
@@ -253,6 +255,7 @@ mod measure {
_available_space: Size<AvailableSpace>,
_node_id: NodeId,
_node_context: Option<&mut ()>,
+ _style: &Style,
) -> taffy::geometry::Size<f32> {
let height = known_dimensions.height.unwrap_or(50.0);
let width = known_dimensions.width.unwrap_or(height);