Skip to content

Commit

Permalink
Enable correct image measure functions (#661)
Browse files Browse the repository at this point in the history
* Use InherentSize mode when sizing absolute children

* Add style parameter to measure functions

* Make MaybeMath, MaybeResolve, and ResolveOrZero traits public

* Fix clippy lints
  • Loading branch information
nicoburns authored May 30, 2024
1 parent bad7c40 commit 09c7a71
Show file tree
Hide file tree
Showing 15 changed files with 40 additions and 22 deletions.
2 changes: 1 addition & 1 deletion examples/cosmic_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
},
)?;
Expand Down
2 changes: 1 addition & 1 deletion examples/measure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
},
)?;
Expand Down
1 change: 1 addition & 0 deletions src/compute/common/alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/compute/grid/track_sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/compute/grid/types/grid_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions src/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
25 changes: 16 additions & 9 deletions src/tree/taffy_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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;

Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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 };
Expand All @@ -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
Expand All @@ -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 }
}
}

Expand All @@ -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))
}
Expand Down
2 changes: 1 addition & 1 deletion src/util/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
4 changes: 2 additions & 2 deletions src/util/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions tests/caching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down
11 changes: 6 additions & 5 deletions tests/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions tests/measure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 09c7a71

Please sign in to comment.