Upgrade to Taffy 0.6 (#15844)

# Objective

- Keep Taffy version up to date

Taffy 0.6 doesn't include a huge amount relevant to Bevy. But it does:

- Add the `box_sizing` style
- Expose the computed `margin` in layout
- Traitifies the `Style` struct, which opens up the possibility of using
Bevy's `Style` struct directly (although Bevy currently does some style
resolution at conversion time which would no longer be cached if it was
used directly).
- Have a few bug fixes in the layout algorithms

## Solution

- Upgrade Taffy to `0.6.0`

## Testing

- I've run the `grid` example. All looks good.
- More testing is probably warranted. We have had regressions from Taffy
upgrades before
- Having said that, most of the algorithm changes this cycle were driven
by fixing WPT tests run through the new Servo integration. So they're
possibly less likely than usual to cause regressions.

## Breaking changes

The only "breaking" change is adding a field to `Style`. Probably
doesn't bear mentioning?

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
Nico Burns 2024-12-04 06:16:35 +13:00 committed by GitHub
parent a8b9c945c7
commit 1fe38b85f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 2 deletions

View file

@ -33,7 +33,7 @@ bevy_window = { path = "../bevy_window", version = "0.15.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
# other # other
taffy = { version = "0.5" } taffy = { version = "0.6" }
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
bytemuck = { version = "1.5", features = ["derive"] } bytemuck = { version = "1.5", features = ["derive"] }
derive_more = { version = "1", default-features = false, features = [ derive_more = { version = "1", default-features = false, features = [

View file

@ -1,7 +1,7 @@
use taffy::style_helpers; use taffy::style_helpers;
use crate::{ use crate::{
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, GridAutoFlow, AlignContent, AlignItems, AlignSelf, BoxSizing, Display, FlexDirection, FlexWrap, GridAutoFlow,
GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf, GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf,
MaxTrackSizingFunction, MinTrackSizingFunction, Node, OverflowAxis, PositionType, MaxTrackSizingFunction, MinTrackSizingFunction, Node, OverflowAxis, PositionType,
RepeatedGridTrack, UiRect, Val, RepeatedGridTrack, UiRect, Val,
@ -66,6 +66,9 @@ impl UiRect {
pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> taffy::style::Style { pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> taffy::style::Style {
taffy::style::Style { taffy::style::Style {
display: node.display.into(), display: node.display.into(),
box_sizing: node.box_sizing.into(),
item_is_table: false,
text_align: taffy::TextAlign::Auto,
overflow: taffy::Point { overflow: taffy::Point {
x: node.overflow.x.into(), x: node.overflow.x.into(),
y: node.overflow.y.into(), y: node.overflow.y.into(),
@ -247,6 +250,15 @@ impl From<Display> for taffy::style::Display {
} }
} }
impl From<BoxSizing> for taffy::style::BoxSizing {
fn from(value: BoxSizing) -> Self {
match value {
BoxSizing::BorderBox => taffy::style::BoxSizing::BorderBox,
BoxSizing::ContentBox => taffy::style::BoxSizing::ContentBox,
}
}
}
impl From<OverflowAxis> for taffy::style::Overflow { impl From<OverflowAxis> for taffy::style::Overflow {
fn from(value: OverflowAxis) -> Self { fn from(value: OverflowAxis) -> Self {
match value { match value {
@ -445,6 +457,7 @@ mod tests {
let node = Node { let node = Node {
display: Display::Flex, display: Display::Flex,
box_sizing: BoxSizing::ContentBox,
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
left: Val::ZERO, left: Val::ZERO,
right: Val::Percent(50.), right: Val::Percent(50.),
@ -513,6 +526,7 @@ mod tests {
let viewport_values = LayoutContext::new(1.0, bevy_math::Vec2::new(800., 600.)); let viewport_values = LayoutContext::new(1.0, bevy_math::Vec2::new(800., 600.));
let taffy_style = from_node(&node, &viewport_values, false); let taffy_style = from_node(&node, &viewport_values, false);
assert_eq!(taffy_style.display, taffy::style::Display::Flex); assert_eq!(taffy_style.display, taffy::style::Display::Flex);
assert_eq!(taffy_style.box_sizing, taffy::style::BoxSizing::ContentBox);
assert_eq!(taffy_style.position, taffy::style::Position::Absolute); assert_eq!(taffy_style.position, taffy::style::Position::Absolute);
assert_eq!( assert_eq!(
taffy_style.inset.left, taffy_style.inset.left,

View file

@ -324,6 +324,15 @@ pub struct Node {
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/display> /// <https://developer.mozilla.org/en-US/docs/Web/CSS/display>
pub display: Display, pub display: Display,
/// Which part of a Node's box length styles like width and height control
/// - [`BoxSizing::BorderBox`]: They refer to the "border box" size (size including padding and border)
/// - [`BoxSizing::ContentBox`]: They refer to the "content box" size (size excluding padding and border)
///
/// `BoxSizing::BorderBox` is generally considered more intuitive and is the default in Bevy even though it is not on the web.
///
/// See: <https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing>
pub box_sizing: BoxSizing,
/// Whether a node should be laid out in-flow with, or independently of its siblings: /// Whether a node should be laid out in-flow with, or independently of its siblings:
/// - [`PositionType::Relative`]: Layout this node in-flow with other nodes using the usual (flexbox/grid) layout algorithm. /// - [`PositionType::Relative`]: Layout this node in-flow with other nodes using the usual (flexbox/grid) layout algorithm.
/// - [`PositionType::Absolute`]: Layout this node on top and independently of other nodes. /// - [`PositionType::Absolute`]: Layout this node on top and independently of other nodes.
@ -591,6 +600,7 @@ pub struct Node {
impl Node { impl Node {
pub const DEFAULT: Self = Self { pub const DEFAULT: Self = Self {
display: Display::DEFAULT, display: Display::DEFAULT,
box_sizing: BoxSizing::DEFAULT,
position_type: PositionType::DEFAULT, position_type: PositionType::DEFAULT,
left: Val::Auto, left: Val::Auto,
right: Val::Auto, right: Val::Auto,
@ -925,6 +935,31 @@ impl Default for Display {
} }
} }
/// Which part of a Node's box length styles like width and height control
///
/// See: <https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing>
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)]
#[reflect(Default, PartialEq)]
#[cfg_attr(
feature = "serialize",
derive(serde::Serialize, serde::Deserialize),
reflect(Serialize, Deserialize)
)]
pub enum BoxSizing {
/// Length styles like width and height refer to the "border box" size (size including padding and border)
BorderBox,
/// Length styles like width and height refer to the "content box" size (size excluding padding and border)
ContentBox,
}
impl BoxSizing {
pub const DEFAULT: Self = Self::BorderBox;
}
impl Default for BoxSizing {
fn default() -> Self {
Self::DEFAULT
}
}
/// Defines how flexbox items are ordered within a flexbox /// Defines how flexbox items are ordered within a flexbox
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)]
#[reflect(Default, PartialEq)] #[reflect(Default, PartialEq)]