From 9746a2fda6c4263075d78b6435b88ab91e532ea5 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 24 Feb 2026 23:58:21 -0800 Subject: [PATCH 1/4] CSS Grid 1/9: Grid style types and public API Summary: Add the foundational data types, enums, style properties, and C API for expressing CSS Grid layouts in Yoga. Includes: - Grid style types (GridLine.h, GridTrack.h, GridTrackType.h) - Updated enums (Display::Grid, Align::Start/End, Justify::Auto/Stretch/Start/End) - Grid event (LayoutPassReason::kGridLayout) - Style property accessors and member variables - Public C API (YGGridTrackList.h/cpp, YGNodeStyle grid setters/getters) - Layout helpers updated for new enum values (Align.h, AbsoluteLayout.cpp, CalculateLayout.cpp/h partial) - Node.h: relativePosition made public - React Native mirror of all C++ changes Differential Revision: D93946262 --- enums.py | 9 +- java/com/facebook/yoga/YogaAlign.java | 6 +- java/com/facebook/yoga/YogaDisplay.java | 4 +- java/com/facebook/yoga/YogaGridTrackType.java | 39 ++++ java/com/facebook/yoga/YogaJustify.java | 32 ++-- javascript/src/generated/YGEnums.ts | 39 +++- yoga/YGEnums.cpp | 30 +++ yoga/YGEnums.h | 21 +- yoga/YGGridTrackList.cpp | 179 ++++++++++++++++++ yoga/YGGridTrackList.h | 96 ++++++++++ yoga/YGNodeStyle.cpp | 100 ++++++++++ yoga/YGNodeStyle.h | 32 +++- yoga/Yoga.h | 1 + yoga/algorithm/AbsoluteLayout.cpp | 48 ++++- yoga/algorithm/Align.h | 13 +- yoga/algorithm/CalculateLayout.cpp | 24 ++- yoga/algorithm/CalculateLayout.h | 22 +++ yoga/enums/Align.h | 4 +- yoga/enums/Display.h | 3 +- yoga/enums/GridTrackType.h | 43 +++++ yoga/enums/Justify.h | 6 +- yoga/event/event.cpp | 2 + yoga/event/event.h | 1 + yoga/node/Node.h | 8 +- yoga/style/GridLine.h | 61 ++++++ yoga/style/GridTrack.h | 65 +++++++ yoga/style/Style.h | 112 ++++++++++- yoga/style/StyleSizeLength.h | 8 +- 28 files changed, 960 insertions(+), 48 deletions(-) create mode 100644 java/com/facebook/yoga/YogaGridTrackType.java create mode 100644 yoga/YGGridTrackList.cpp create mode 100644 yoga/YGGridTrackList.h create mode 100644 yoga/enums/GridTrackType.h create mode 100644 yoga/style/GridLine.h create mode 100644 yoga/style/GridTrack.h diff --git a/enums.py b/enums.py index d43dd6c147..2c53672a2e 100755 --- a/enums.py +++ b/enums.py @@ -19,12 +19,16 @@ ], "FlexDirection": ["Column", "ColumnReverse", "Row", "RowReverse"], "Justify": [ + "Auto", "FlexStart", "Center", "FlexEnd", "SpaceBetween", "SpaceAround", "SpaceEvenly", + "Stretch", + "Start", + "End", ], "Overflow": ["Visible", "Hidden", "Scroll"], "Align": [ @@ -37,9 +41,11 @@ "SpaceBetween", "SpaceAround", "SpaceEvenly", + "Start", + "End", ], "PositionType": ["Static", "Relative", "Absolute"], - "Display": ["Flex", "None", "Contents"], + "Display": ["Flex", "None", "Contents", "Grid"], "Wrap": ["NoWrap", "Wrap", "WrapReverse"], "BoxSizing": ["BorderBox", "ContentBox"], "MeasureMode": ["Undefined", "Exactly", "AtMost"], @@ -62,6 +68,7 @@ "WebFlexBasis", ], "Gutter": ["Column", "Row", "All"], + "GridTrackType": ["Auto", "Points", "Percent", "Fr", "Minmax"], # Known incorrect behavior which can be enabled for compatibility "Errata": [ # Default: Standards conformant mode diff --git a/java/com/facebook/yoga/YogaAlign.java b/java/com/facebook/yoga/YogaAlign.java index 00535154fc..6f1c456581 100644 --- a/java/com/facebook/yoga/YogaAlign.java +++ b/java/com/facebook/yoga/YogaAlign.java @@ -18,7 +18,9 @@ public enum YogaAlign { BASELINE(5), SPACE_BETWEEN(6), SPACE_AROUND(7), - SPACE_EVENLY(8); + SPACE_EVENLY(8), + START(9), + END(10); private final int mIntValue; @@ -41,6 +43,8 @@ public static YogaAlign fromInt(int value) { case 6: return SPACE_BETWEEN; case 7: return SPACE_AROUND; case 8: return SPACE_EVENLY; + case 9: return START; + case 10: return END; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/java/com/facebook/yoga/YogaDisplay.java b/java/com/facebook/yoga/YogaDisplay.java index 4dae871936..8e7e0f83cd 100644 --- a/java/com/facebook/yoga/YogaDisplay.java +++ b/java/com/facebook/yoga/YogaDisplay.java @@ -12,7 +12,8 @@ public enum YogaDisplay { FLEX(0), NONE(1), - CONTENTS(2); + CONTENTS(2), + GRID(3); private final int mIntValue; @@ -29,6 +30,7 @@ public static YogaDisplay fromInt(int value) { case 0: return FLEX; case 1: return NONE; case 2: return CONTENTS; + case 3: return GRID; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/java/com/facebook/yoga/YogaGridTrackType.java b/java/com/facebook/yoga/YogaGridTrackType.java new file mode 100644 index 0000000000..e3d22d25be --- /dev/null +++ b/java/com/facebook/yoga/YogaGridTrackType.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py + +package com.facebook.yoga; + +public enum YogaGridTrackType { + AUTO(0), + POINTS(1), + PERCENT(2), + FR(3), + MINMAX(4); + + private final int mIntValue; + + YogaGridTrackType(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static YogaGridTrackType fromInt(int value) { + switch (value) { + case 0: return AUTO; + case 1: return POINTS; + case 2: return PERCENT; + case 3: return FR; + case 4: return MINMAX; + default: throw new IllegalArgumentException("Unknown enum value: " + value); + } + } +} diff --git a/java/com/facebook/yoga/YogaJustify.java b/java/com/facebook/yoga/YogaJustify.java index 4be1ed71d3..778238ec66 100644 --- a/java/com/facebook/yoga/YogaJustify.java +++ b/java/com/facebook/yoga/YogaJustify.java @@ -10,12 +10,16 @@ package com.facebook.yoga; public enum YogaJustify { - FLEX_START(0), - CENTER(1), - FLEX_END(2), - SPACE_BETWEEN(3), - SPACE_AROUND(4), - SPACE_EVENLY(5); + AUTO(0), + FLEX_START(1), + CENTER(2), + FLEX_END(3), + SPACE_BETWEEN(4), + SPACE_AROUND(5), + SPACE_EVENLY(6), + STRETCH(7), + START(8), + END(9); private final int mIntValue; @@ -29,12 +33,16 @@ public int intValue() { public static YogaJustify fromInt(int value) { switch (value) { - case 0: return FLEX_START; - case 1: return CENTER; - case 2: return FLEX_END; - case 3: return SPACE_BETWEEN; - case 4: return SPACE_AROUND; - case 5: return SPACE_EVENLY; + case 0: return AUTO; + case 1: return FLEX_START; + case 2: return CENTER; + case 3: return FLEX_END; + case 4: return SPACE_BETWEEN; + case 5: return SPACE_AROUND; + case 6: return SPACE_EVENLY; + case 7: return STRETCH; + case 8: return START; + case 9: return END; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/javascript/src/generated/YGEnums.ts b/javascript/src/generated/YGEnums.ts index f389fe2fdf..f50aa88a73 100644 --- a/javascript/src/generated/YGEnums.ts +++ b/javascript/src/generated/YGEnums.ts @@ -17,6 +17,8 @@ export enum Align { SpaceBetween = 6, SpaceAround = 7, SpaceEvenly = 8, + Start = 9, + End = 10, } export enum BoxSizing { @@ -39,6 +41,7 @@ export enum Display { Flex = 0, None = 1, Contents = 2, + Grid = 3, } export enum Edge { @@ -73,6 +76,14 @@ export enum FlexDirection { RowReverse = 3, } +export enum GridTrackType { + Auto = 0, + Points = 1, + Percent = 2, + Fr = 3, + Minmax = 4, +} + export enum Gutter { Column = 0, Row = 1, @@ -80,12 +91,16 @@ export enum Gutter { } export enum Justify { - FlexStart = 0, - Center = 1, - FlexEnd = 2, - SpaceBetween = 3, - SpaceAround = 4, - SpaceEvenly = 5, + Auto = 0, + FlexStart = 1, + Center = 2, + FlexEnd = 3, + SpaceBetween = 4, + SpaceAround = 5, + SpaceEvenly = 6, + Stretch = 7, + Start = 8, + End = 9, } export enum LogLevel { @@ -146,6 +161,8 @@ const constants = { ALIGN_SPACE_BETWEEN: Align.SpaceBetween, ALIGN_SPACE_AROUND: Align.SpaceAround, ALIGN_SPACE_EVENLY: Align.SpaceEvenly, + ALIGN_START: Align.Start, + ALIGN_END: Align.End, BOX_SIZING_BORDER_BOX: BoxSizing.BorderBox, BOX_SIZING_CONTENT_BOX: BoxSizing.ContentBox, DIMENSION_WIDTH: Dimension.Width, @@ -156,6 +173,7 @@ const constants = { DISPLAY_FLEX: Display.Flex, DISPLAY_NONE: Display.None, DISPLAY_CONTENTS: Display.Contents, + DISPLAY_GRID: Display.Grid, EDGE_LEFT: Edge.Left, EDGE_TOP: Edge.Top, EDGE_RIGHT: Edge.Right, @@ -176,15 +194,24 @@ const constants = { FLEX_DIRECTION_COLUMN_REVERSE: FlexDirection.ColumnReverse, FLEX_DIRECTION_ROW: FlexDirection.Row, FLEX_DIRECTION_ROW_REVERSE: FlexDirection.RowReverse, + GRID_TRACK_TYPE_AUTO: GridTrackType.Auto, + GRID_TRACK_TYPE_POINTS: GridTrackType.Points, + GRID_TRACK_TYPE_PERCENT: GridTrackType.Percent, + GRID_TRACK_TYPE_FR: GridTrackType.Fr, + GRID_TRACK_TYPE_MINMAX: GridTrackType.Minmax, GUTTER_COLUMN: Gutter.Column, GUTTER_ROW: Gutter.Row, GUTTER_ALL: Gutter.All, + JUSTIFY_AUTO: Justify.Auto, JUSTIFY_FLEX_START: Justify.FlexStart, JUSTIFY_CENTER: Justify.Center, JUSTIFY_FLEX_END: Justify.FlexEnd, JUSTIFY_SPACE_BETWEEN: Justify.SpaceBetween, JUSTIFY_SPACE_AROUND: Justify.SpaceAround, JUSTIFY_SPACE_EVENLY: Justify.SpaceEvenly, + JUSTIFY_STRETCH: Justify.Stretch, + JUSTIFY_START: Justify.Start, + JUSTIFY_END: Justify.End, LOG_LEVEL_ERROR: LogLevel.Error, LOG_LEVEL_WARN: LogLevel.Warn, LOG_LEVEL_INFO: LogLevel.Info, diff --git a/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index 4bdace6b7a..9fc4a83a82 100644 --- a/yoga/YGEnums.cpp +++ b/yoga/YGEnums.cpp @@ -29,6 +29,10 @@ const char* YGAlignToString(const YGAlign value) { return "space-around"; case YGAlignSpaceEvenly: return "space-evenly"; + case YGAlignStart: + return "start"; + case YGAlignEnd: + return "end"; } return "unknown"; } @@ -73,6 +77,8 @@ const char* YGDisplayToString(const YGDisplay value) { return "none"; case YGDisplayContents: return "contents"; + case YGDisplayGrid: + return "grid"; } return "unknown"; } @@ -141,6 +147,22 @@ const char* YGFlexDirectionToString(const YGFlexDirection value) { return "unknown"; } +const char* YGGridTrackTypeToString(const YGGridTrackType value) { + switch (value) { + case YGGridTrackTypeAuto: + return "auto"; + case YGGridTrackTypePoints: + return "points"; + case YGGridTrackTypePercent: + return "percent"; + case YGGridTrackTypeFr: + return "fr"; + case YGGridTrackTypeMinmax: + return "minmax"; + } + return "unknown"; +} + const char* YGGutterToString(const YGGutter value) { switch (value) { case YGGutterColumn: @@ -155,6 +177,8 @@ const char* YGGutterToString(const YGGutter value) { const char* YGJustifyToString(const YGJustify value) { switch (value) { + case YGJustifyAuto: + return "auto"; case YGJustifyFlexStart: return "flex-start"; case YGJustifyCenter: @@ -167,6 +191,12 @@ const char* YGJustifyToString(const YGJustify value) { return "space-around"; case YGJustifySpaceEvenly: return "space-evenly"; + case YGJustifyStretch: + return "stretch"; + case YGJustifyStart: + return "start"; + case YGJustifyEnd: + return "end"; } return "unknown"; } diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index bb83bcfac9..1b69f09318 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -22,7 +22,9 @@ YG_ENUM_DECL( YGAlignBaseline, YGAlignSpaceBetween, YGAlignSpaceAround, - YGAlignSpaceEvenly) + YGAlignSpaceEvenly, + YGAlignStart, + YGAlignEnd) YG_ENUM_DECL( YGBoxSizing, @@ -44,7 +46,8 @@ YG_ENUM_DECL( YGDisplay, YGDisplayFlex, YGDisplayNone, - YGDisplayContents) + YGDisplayContents, + YGDisplayGrid) YG_ENUM_DECL( YGEdge, @@ -79,6 +82,14 @@ YG_ENUM_DECL( YGFlexDirectionRow, YGFlexDirectionRowReverse) +YG_ENUM_DECL( + YGGridTrackType, + YGGridTrackTypeAuto, + YGGridTrackTypePoints, + YGGridTrackTypePercent, + YGGridTrackTypeFr, + YGGridTrackTypeMinmax) + YG_ENUM_DECL( YGGutter, YGGutterColumn, @@ -87,12 +98,16 @@ YG_ENUM_DECL( YG_ENUM_DECL( YGJustify, + YGJustifyAuto, YGJustifyFlexStart, YGJustifyCenter, YGJustifyFlexEnd, YGJustifySpaceBetween, YGJustifySpaceAround, - YGJustifySpaceEvenly) + YGJustifySpaceEvenly, + YGJustifyStretch, + YGJustifyStart, + YGJustifyEnd) YG_ENUM_DECL( YGLogLevel, diff --git a/yoga/YGGridTrackList.cpp b/yoga/YGGridTrackList.cpp new file mode 100644 index 0000000000..7417656758 --- /dev/null +++ b/yoga/YGGridTrackList.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include +#include + +using namespace facebook::yoga; + +// Internal representation of a grid track value +struct YGGridTrackValue { + enum class Type { Points, Percent, Fr, Auto, MinMax }; + + Type type; + float value; + YGGridTrackValue* minValue; + YGGridTrackValue* maxValue; + + YGGridTrackValue(Type t, float v = 0.0f) + : type(t), value(v), minValue(nullptr), maxValue(nullptr) {} + + YGGridTrackValue(YGGridTrackValue* min, YGGridTrackValue* max) + : type(Type::MinMax), value(0.0f), minValue(min), maxValue(max) {} + + ~YGGridTrackValue() { + // MinMax owns its min/max values + if (type == Type::MinMax) { + delete minValue; + delete maxValue; + } + } + + StyleSizeLength toStyleSizeLength() const { + switch (type) { + case Type::Points: + return StyleSizeLength::points(value); + case Type::Percent: + return StyleSizeLength::percent(value); + case Type::Fr: + return StyleSizeLength::stretch(value); + case Type::Auto: + return StyleSizeLength::ofAuto(); + case Type::MinMax: + // MinMax should not call this, it needs special handling + return StyleSizeLength::ofAuto(); + } + return StyleSizeLength::ofAuto(); + } +}; + +// Internal representation of a grid track list +struct YGGridTrackList { + std::vector tracks; + + YGGridTrackList() = default; + YGGridTrackList(const YGGridTrackList&) = delete; + YGGridTrackList& operator=(const YGGridTrackList&) = delete; + YGGridTrackList(YGGridTrackList&&) = delete; + YGGridTrackList& operator=(YGGridTrackList&&) = delete; + + ~YGGridTrackList() { + for (auto* track : tracks) { + delete track; + } + } + + GridTrackList toGridTrackList() const { + GridTrackList result; + result.reserve(tracks.size()); + + for (auto* track : tracks) { + if (track->type == YGGridTrackValue::Type::MinMax) { + auto min = track->minValue->toStyleSizeLength(); + auto max = track->maxValue->toStyleSizeLength(); + result.push_back(GridTrackSize::minmax(min, max)); + } else { + switch (track->type) { + case YGGridTrackValue::Type::Points: + result.push_back(GridTrackSize::length(track->value)); + break; + case YGGridTrackValue::Type::Percent: + result.push_back(GridTrackSize::percent(track->value)); + break; + case YGGridTrackValue::Type::Fr: + result.push_back(GridTrackSize::fr(track->value)); + break; + case YGGridTrackValue::Type::Auto: + result.push_back(GridTrackSize::auto_()); + break; + case YGGridTrackValue::Type::MinMax: + // Already handled above + break; + } + } + } + + return result; + } +}; + +YGGridTrackListRef YGGridTrackListCreate() { + return new YGGridTrackList(); +} + +void YGGridTrackListFree(YGGridTrackListRef list) { + delete list; +} + +void YGGridTrackListAddTrack( + YGGridTrackListRef list, + YGGridTrackValueRef trackValue) { + if (list && trackValue) { + list->tracks.push_back(trackValue); + } +} + +YGGridTrackValueRef YGPoints(float points) { + return new YGGridTrackValue(YGGridTrackValue::Type::Points, points); +} + +YGGridTrackValueRef YGPercent(float percent) { + return new YGGridTrackValue(YGGridTrackValue::Type::Percent, percent); +} + +YGGridTrackValueRef YGFr(float fr) { + return new YGGridTrackValue(YGGridTrackValue::Type::Fr, fr); +} + +YGGridTrackValueRef YGAuto() { + return new YGGridTrackValue(YGGridTrackValue::Type::Auto); +} + +YGGridTrackValueRef YGMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max) { + return new YGGridTrackValue(min, max); +} + +void YGNodeStyleSetGridTemplateRows( + YGNodeRef node, + YGGridTrackListRef trackList) { + if (node && trackList) { + auto* n = resolveRef(node); + n->style().setGridTemplateRows(trackList->toGridTrackList()); + n->markDirtyAndPropagate(); + } +} + +void YGNodeStyleSetGridTemplateColumns( + YGNodeRef node, + YGGridTrackListRef trackList) { + if (node && trackList) { + auto* n = resolveRef(node); + n->style().setGridTemplateColumns(trackList->toGridTrackList()); + n->markDirtyAndPropagate(); + } +} + +void YGNodeStyleSetGridAutoRows(YGNodeRef node, YGGridTrackListRef trackList) { + if (node && trackList) { + auto* n = resolveRef(node); + n->style().setGridAutoRows(trackList->toGridTrackList()); + n->markDirtyAndPropagate(); + } +} + +void YGNodeStyleSetGridAutoColumns( + YGNodeRef node, + YGGridTrackListRef trackList) { + if (node && trackList) { + auto* n = resolveRef(node); + n->style().setGridAutoColumns(trackList->toGridTrackList()); + n->markDirtyAndPropagate(); + } +} diff --git a/yoga/YGGridTrackList.h b/yoga/YGGridTrackList.h new file mode 100644 index 0000000000..a89e92cca6 --- /dev/null +++ b/yoga/YGGridTrackList.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +YG_EXTERN_C_BEGIN + +/** + * Opaque handle to a grid track list for building grid-template-rows/columns. + */ +typedef struct YGGridTrackList* YGGridTrackListRef; + +/** + * Opaque handle to a grid track value. + */ +typedef struct YGGridTrackValue* YGGridTrackValueRef; + +/** + * Create a new grid track list. + */ +YG_EXPORT YGGridTrackListRef YGGridTrackListCreate(void); + +/** + * Free a grid track list. + */ +YG_EXPORT void YGGridTrackListFree(YGGridTrackListRef list); + +/** + * Add a track to the grid track list. + */ +YG_EXPORT void YGGridTrackListAddTrack( + YGGridTrackListRef list, + YGGridTrackValueRef trackValue); + +/** + * Create a grid track value with a points (px) length. + */ +YG_EXPORT YGGridTrackValueRef YGPoints(float points); + +/** + * Create a grid track value with a percentage length. + */ +YG_EXPORT YGGridTrackValueRef YGPercent(float percent); + +/** + * Create a grid track value with a flexible (fr) length. + */ +YG_EXPORT YGGridTrackValueRef YGFr(float fr); + +/** + * Create a grid track value with auto sizing. + */ +YG_EXPORT YGGridTrackValueRef YGAuto(void); + +/** + * Create a grid track value with minmax(min, max) sizing. + */ +YG_EXPORT YGGridTrackValueRef +YGMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max); + +/** + * Set the grid-template-rows property on a node. + */ +YG_EXPORT void YGNodeStyleSetGridTemplateRows( + YGNodeRef node, + YGGridTrackListRef trackList); + +/** + * Set the grid-template-columns property on a node. + */ +YG_EXPORT void YGNodeStyleSetGridTemplateColumns( + YGNodeRef node, + YGGridTrackListRef trackList); + +/** + * Set the grid-auto-rows property on a node. + */ +YG_EXPORT void YGNodeStyleSetGridAutoRows( + YGNodeRef node, + YGGridTrackListRef trackList); + +/** + * Set the grid-auto-columns property on a node. + */ +YG_EXPORT void YGNodeStyleSetGridAutoColumns( + YGNodeRef node, + YGGridTrackListRef trackList); + +YG_EXTERN_C_END diff --git a/yoga/YGNodeStyle.cpp b/yoga/YGNodeStyle.cpp index 4e77405b6c..f859c8427a 100644 --- a/yoga/YGNodeStyle.cpp +++ b/yoga/YGNodeStyle.cpp @@ -74,6 +74,24 @@ YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->style().justifyContent()); } +void YGNodeStyleSetJustifyItems(YGNodeRef node, const YGJustify justifyItems) { + updateStyle<&Style::justifyItems, &Style::setJustifyItems>( + node, scopedEnum(justifyItems)); +} + +YGJustify YGNodeStyleGetJustifyItems(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().justifyItems()); +} + +void YGNodeStyleSetJustifySelf(YGNodeRef node, const YGJustify justifySelf) { + updateStyle<&Style::justifySelf, &Style::setJustifySelf>( + node, scopedEnum(justifySelf)); +} + +YGJustify YGNodeStyleGetJustifySelf(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().justifySelf()); +} + void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { @@ -503,3 +521,85 @@ void YGNodeStyleSetMaxHeightStretch(const YGNodeRef node) { YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Height); } + +// Grid Item Placement Properties + +void YGNodeStyleSetGridColumnStart(YGNodeRef node, int32_t gridColumnStart) { + updateStyle<&Style::gridColumnStart, &Style::setGridColumnStart>( + node, GridLine::fromInteger(gridColumnStart)); +} + +void YGNodeStyleSetGridColumnStartAuto(YGNodeRef node) { + updateStyle<&Style::gridColumnStart, &Style::setGridColumnStart>( + node, GridLine::auto_()); +} + +void YGNodeStyleSetGridColumnStartSpan(YGNodeRef node, int32_t span) { + updateStyle<&Style::gridColumnStart, &Style::setGridColumnStart>( + node, GridLine::span(span)); +} + +int32_t YGNodeStyleGetGridColumnStart(YGNodeConstRef node) { + const auto& gridLine = resolveRef(node)->style().gridColumnStart(); + return gridLine.isInteger() ? gridLine.integer : 0; +} + +void YGNodeStyleSetGridColumnEnd(YGNodeRef node, int32_t gridColumnEnd) { + updateStyle<&Style::gridColumnEnd, &Style::setGridColumnEnd>( + node, GridLine::fromInteger(gridColumnEnd)); +} + +void YGNodeStyleSetGridColumnEndAuto(YGNodeRef node) { + updateStyle<&Style::gridColumnEnd, &Style::setGridColumnEnd>( + node, GridLine::auto_()); +} + +void YGNodeStyleSetGridColumnEndSpan(YGNodeRef node, int32_t span) { + updateStyle<&Style::gridColumnEnd, &Style::setGridColumnEnd>( + node, GridLine::span(span)); +} + +int32_t YGNodeStyleGetGridColumnEnd(YGNodeConstRef node) { + const auto& gridLine = resolveRef(node)->style().gridColumnEnd(); + return gridLine.isInteger() ? gridLine.integer : 0; +} + +void YGNodeStyleSetGridRowStart(YGNodeRef node, int32_t gridRowStart) { + updateStyle<&Style::gridRowStart, &Style::setGridRowStart>( + node, GridLine::fromInteger(gridRowStart)); +} + +void YGNodeStyleSetGridRowStartAuto(YGNodeRef node) { + updateStyle<&Style::gridRowStart, &Style::setGridRowStart>( + node, GridLine::auto_()); +} + +void YGNodeStyleSetGridRowStartSpan(YGNodeRef node, int32_t span) { + updateStyle<&Style::gridRowStart, &Style::setGridRowStart>( + node, GridLine::span(span)); +} + +int32_t YGNodeStyleGetGridRowStart(YGNodeConstRef node) { + const auto& gridLine = resolveRef(node)->style().gridRowStart(); + return gridLine.isInteger() ? gridLine.integer : 0; +} + +void YGNodeStyleSetGridRowEnd(YGNodeRef node, int32_t gridRowEnd) { + updateStyle<&Style::gridRowEnd, &Style::setGridRowEnd>( + node, GridLine::fromInteger(gridRowEnd)); +} + +void YGNodeStyleSetGridRowEndAuto(YGNodeRef node) { + updateStyle<&Style::gridRowEnd, &Style::setGridRowEnd>( + node, GridLine::auto_()); +} + +void YGNodeStyleSetGridRowEndSpan(YGNodeRef node, int32_t span) { + updateStyle<&Style::gridRowEnd, &Style::setGridRowEnd>( + node, GridLine::span(span)); +} + +int32_t YGNodeStyleGetGridRowEnd(YGNodeConstRef node) { + const auto& gridLine = resolveRef(node)->style().gridRowEnd(); + return gridLine.isInteger() ? gridLine.integer : 0; +} diff --git a/yoga/YGNodeStyle.h b/yoga/YGNodeStyle.h index 21b8326d85..d1afd5c8ae 100644 --- a/yoga/YGNodeStyle.h +++ b/yoga/YGNodeStyle.h @@ -8,7 +8,6 @@ #pragma once #include - #include #include @@ -29,6 +28,14 @@ YG_EXPORT void YGNodeStyleSetJustifyContent( YGJustify justifyContent); YG_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node); +YG_EXPORT void YGNodeStyleSetJustifyItems( + YGNodeRef node, + YGJustify justifyItems); +YG_EXPORT YGJustify YGNodeStyleGetJustifyItems(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetJustifySelf(YGNodeRef node, YGJustify justifySelf); +YG_EXPORT YGJustify YGNodeStyleGetJustifySelf(YGNodeConstRef node); + YG_EXPORT void YGNodeStyleSetAlignContent(YGNodeRef node, YGAlign alignContent); YG_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node); @@ -148,4 +155,27 @@ YG_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio); YG_EXPORT float YGNodeStyleGetAspectRatio(YGNodeConstRef node); +// Grid Item Properties +YG_EXPORT void YGNodeStyleSetGridColumnStart( + YGNodeRef node, + int gridColumnStart); +YG_EXPORT void YGNodeStyleSetGridColumnStartAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetGridColumnStartSpan(YGNodeRef node, int span); +YG_EXPORT int YGNodeStyleGetGridColumnStart(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetGridColumnEnd(YGNodeRef node, int gridColumnEnd); +YG_EXPORT void YGNodeStyleSetGridColumnEndAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetGridColumnEndSpan(YGNodeRef node, int span); +YG_EXPORT int YGNodeStyleGetGridColumnEnd(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetGridRowStart(YGNodeRef node, int gridRowStart); +YG_EXPORT void YGNodeStyleSetGridRowStartAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetGridRowStartSpan(YGNodeRef node, int span); +YG_EXPORT int YGNodeStyleGetGridRowStart(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetGridRowEnd(YGNodeRef node, int gridRowEnd); +YG_EXPORT void YGNodeStyleSetGridRowEndAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetGridRowEndSpan(YGNodeRef node, int span); +YG_EXPORT int YGNodeStyleGetGridRowEnd(YGNodeConstRef node); + YG_EXTERN_C_END diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 97f05ed3ea..25b7a8e83c 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -13,6 +13,7 @@ #include // IWYU pragma: export #include // IWYU pragma: export +#include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export diff --git a/yoga/algorithm/AbsoluteLayout.cpp b/yoga/algorithm/AbsoluteLayout.cpp index b2d8d8dbef..181dfcb1b0 100644 --- a/yoga/algorithm/AbsoluteLayout.cpp +++ b/yoga/algorithm/AbsoluteLayout.cpp @@ -23,7 +23,11 @@ static inline void setFlexStartLayoutPosition( axis, direction, containingBlockWidth) + parent->getLayout().border(flexStartEdge(axis)); - if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + // https://www.w3.org/TR/css-grid-1/#abspos + // absolute positioned grid items are positioned relative to the padding edge + // of the grid container + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding) && + parent->style().display() != Display::Grid) { position += parent->getLayout().padding(flexStartEdge(axis)); } @@ -40,7 +44,11 @@ static inline void setFlexEndLayoutPosition( child->style().computeFlexEndMargin( axis, direction, containingBlockWidth); - if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + // https://www.w3.org/TR/css-grid-1/#abspos + // absolute positioned grid items are positioned relative to the padding edge + // of the grid container + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding) && + parent->style().display() != Display::Grid) { flexEndPosition += parent->getLayout().padding(flexEndEdge(axis)); } @@ -60,7 +68,11 @@ static inline void setCenterLayoutPosition( parent->getLayout().border(flexStartEdge(axis)) - parent->getLayout().border(flexEndEdge(axis)); - if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + // https://www.w3.org/TR/css-grid-1/#abspos + // absolute positioned grid items are positioned relative to the padding edge + // of the grid container + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding) && + parent->style().display() != Display::Grid) { parentContentBoxSize -= parent->getLayout().padding(flexStartEdge(axis)); parentContentBoxSize -= parent->getLayout().padding(flexEndEdge(axis)); } @@ -74,7 +86,11 @@ static inline void setCenterLayoutPosition( child->style().computeFlexStartMargin( axis, direction, containingBlockWidth); - if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + // https://www.w3.org/TR/css-grid-1/#abspos + // absolute positioned grid items are positioned relative to the padding edge + // of the grid container + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding) && + parent->style().display() != Display::Grid) { position += parent->getLayout().padding(flexStartEdge(axis)); } @@ -87,13 +103,19 @@ static void justifyAbsoluteChild( const Direction direction, const FlexDirection mainAxis, const float containingBlockWidth) { - const Justify parentJustifyContent = parent->style().justifyContent(); - switch (parentJustifyContent) { + const Justify justify = parent->style().display() == Display::Grid + ? resolveChildJustification(parent, child) + : parent->style().justifyContent(); + switch (justify) { + case Justify::Start: + case Justify::Auto: + case Justify::Stretch: case Justify::FlexStart: case Justify::SpaceBetween: setFlexStartLayoutPosition( parent, child, direction, mainAxis, containingBlockWidth); break; + case Justify::End: case Justify::FlexEnd: setFlexEndLayoutPosition( parent, child, direction, mainAxis, containingBlockWidth); @@ -124,6 +146,7 @@ static void alignAbsoluteChild( } switch (itemAlign) { + case Align::Start: case Align::Auto: case Align::FlexStart: case Align::Baseline: @@ -134,6 +157,7 @@ static void alignAbsoluteChild( setFlexStartLayoutPosition( parent, child, direction, crossAxis, containingBlockWidth); break; + case Align::End: case Align::FlexEnd: setFlexEndLayoutPosition( parent, child, direction, crossAxis, containingBlockWidth); @@ -234,9 +258,15 @@ void layoutAbsoluteChild( LayoutData& layoutMarkerData, const uint32_t depth, const uint32_t generationCount) { - const FlexDirection mainAxis = - resolveDirection(node->style().flexDirection(), direction); - const FlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); + // For grid containers, use inline (Row) and block (Column) axes for + // positioning, since grid alignment properties (justify-self, align-self) + // operate on inline/block axes, not main/cross axes based on flex-direction. + const FlexDirection mainAxis = node->style().display() == Display::Grid + ? resolveDirection(FlexDirection::Row, direction) + : resolveDirection(node->style().flexDirection(), direction); + const FlexDirection crossAxis = node->style().display() == Display::Grid + ? FlexDirection::Column + : resolveCrossDirection(mainAxis, direction); const bool isMainAxisRow = isRow(mainAxis); float childWidth = YGUndefined; diff --git a/yoga/algorithm/Align.h b/yoga/algorithm/Align.h index bb21fe5dca..b12ae7fd53 100644 --- a/yoga/algorithm/Align.h +++ b/yoga/algorithm/Align.h @@ -20,12 +20,23 @@ inline Align resolveChildAlignment( const Align align = child->style().alignSelf() == Align::Auto ? node->style().alignItems() : child->style().alignSelf(); - if (align == Align::Baseline && isColumn(node->style().flexDirection())) { + + if (node->style().display() == Display::Flex && align == Align::Baseline && + isColumn(node->style().flexDirection())) { return Align::FlexStart; } + return align; } +inline Justify resolveChildJustification( + const yoga::Node* node, + const yoga::Node* child) { + return child->style().justifySelf() == Justify::Auto + ? node->style().justifyItems() + : child->style().justifySelf(); +} + /** * Fallback alignment to use on overflow * https://www.w3.org/TR/css-align-3/#distribution-values diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 81a5f3b8a0..95a2ba513b 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -35,7 +35,7 @@ namespace facebook::yoga { std::atomic gCurrentGenerationCount(0); -static void constrainMaxSizeForMode( +void constrainMaxSizeForMode( const yoga::Node* node, Direction direction, FlexDirection axis, @@ -468,7 +468,7 @@ static bool measureNodeWithFixedSize( return false; } -static void zeroOutLayoutRecursively(yoga::Node* const node) { +void zeroOutLayoutRecursively(yoga::Node* const node) { node->getLayout() = {}; node->setLayoutDimension(0, Dimension::Width); node->setLayoutDimension(0, Dimension::Height); @@ -480,7 +480,7 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) { } } -static void cleanupContentsNodesRecursively(yoga::Node* const node) { +void cleanupContentsNodesRecursively(yoga::Node* const node) { if (node->hasContentsChildren()) [[unlikely]] { node->cloneContentsChildrenIfNeeded(); for (auto child : node->getChildren()) { @@ -498,7 +498,7 @@ static void cleanupContentsNodesRecursively(yoga::Node* const node) { } } -static float calculateAvailableInnerDimension( +float calculateAvailableInnerDimension( const yoga::Node* const node, const Direction direction, const Dimension dimension, @@ -1046,6 +1046,14 @@ static void justifyMainAxis( if (flexLine.numberOfAutoMargins == 0) { switch (justifyContent) { + case Justify::Start: + case Justify::End: + case Justify::Auto: + // No-Op + break; + case Justify::Stretch: + // No-Op + break; case Justify::Center: leadingMainDim = flexLine.layout.remainingFreeSpace / 2; break; @@ -1799,6 +1807,10 @@ static void calculateLayoutImpl( : fallbackAlignment(node->style().alignContent()); switch (alignContent) { + case Align::Start: + case Align::End: + // No-Op + break; case Align::FlexEnd: currentLead += remainingAlignContentDim; break; @@ -1886,6 +1898,10 @@ static void calculateLayoutImpl( } if (child->style().positionType() != PositionType::Absolute) { switch (resolveChildAlignment(node, child)) { + case Align::Start: + case Align::End: + // No-Op + break; case Align::FlexStart: { child->setLayoutPosition( currentLead + diff --git a/yoga/algorithm/CalculateLayout.h b/yoga/algorithm/CalculateLayout.h index 5e6884ec1a..86b3c61afe 100644 --- a/yoga/algorithm/CalculateLayout.h +++ b/yoga/algorithm/CalculateLayout.h @@ -35,4 +35,26 @@ bool calculateLayoutInternal( uint32_t depth, uint32_t generationCount); +void constrainMaxSizeForMode( + const yoga::Node* node, + Direction direction, + FlexDirection axis, + float ownerAxisSize, + float ownerWidth, + /*in_out*/ SizingMode* mode, + /*in_out*/ float* size); + +float calculateAvailableInnerDimension( + const yoga::Node* const node, + const Direction direction, + const Dimension dimension, + const float availableDim, + const float paddingAndBorder, + const float ownerDim, + const float ownerWidth); + +void zeroOutLayoutRecursively(yoga::Node* const node); + +void cleanupContentsNodesRecursively(yoga::Node* const node); + } // namespace facebook::yoga diff --git a/yoga/enums/Align.h b/yoga/enums/Align.h index 3896fe2b8b..e1b8b29bd7 100644 --- a/yoga/enums/Align.h +++ b/yoga/enums/Align.h @@ -25,11 +25,13 @@ enum class Align : uint8_t { SpaceBetween = YGAlignSpaceBetween, SpaceAround = YGAlignSpaceAround, SpaceEvenly = YGAlignSpaceEvenly, + Start = YGAlignStart, + End = YGAlignEnd, }; template <> constexpr int32_t ordinalCount() { - return 9; + return 11; } constexpr Align scopedEnum(YGAlign unscoped) { diff --git a/yoga/enums/Display.h b/yoga/enums/Display.h index 9bf23c0ac7..9edbee80b5 100644 --- a/yoga/enums/Display.h +++ b/yoga/enums/Display.h @@ -19,11 +19,12 @@ enum class Display : uint8_t { Flex = YGDisplayFlex, None = YGDisplayNone, Contents = YGDisplayContents, + Grid = YGDisplayGrid, }; template <> constexpr int32_t ordinalCount() { - return 3; + return 4; } constexpr Display scopedEnum(YGDisplay unscoped) { diff --git a/yoga/enums/GridTrackType.h b/yoga/enums/GridTrackType.h new file mode 100644 index 0000000000..eb6e8332bc --- /dev/null +++ b/yoga/enums/GridTrackType.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class GridTrackType : uint8_t { + Auto = YGGridTrackTypeAuto, + Points = YGGridTrackTypePoints, + Percent = YGGridTrackTypePercent, + Fr = YGGridTrackTypeFr, + Minmax = YGGridTrackTypeMinmax, +}; + +template <> +constexpr int32_t ordinalCount() { + return 5; +} + +constexpr GridTrackType scopedEnum(YGGridTrackType unscoped) { + return static_cast(unscoped); +} + +constexpr YGGridTrackType unscopedEnum(GridTrackType scoped) { + return static_cast(scoped); +} + +inline const char* toString(GridTrackType e) { + return YGGridTrackTypeToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Justify.h b/yoga/enums/Justify.h index 255baa6e27..db4afece9a 100644 --- a/yoga/enums/Justify.h +++ b/yoga/enums/Justify.h @@ -16,17 +16,21 @@ namespace facebook::yoga { enum class Justify : uint8_t { + Auto = YGJustifyAuto, FlexStart = YGJustifyFlexStart, Center = YGJustifyCenter, FlexEnd = YGJustifyFlexEnd, SpaceBetween = YGJustifySpaceBetween, SpaceAround = YGJustifySpaceAround, SpaceEvenly = YGJustifySpaceEvenly, + Stretch = YGJustifyStretch, + Start = YGJustifyStart, + End = YGJustifyEnd, }; template <> constexpr int32_t ordinalCount() { - return 6; + return 10; } constexpr Justify scopedEnum(YGJustify unscoped) { diff --git a/yoga/event/event.cpp b/yoga/event/event.cpp index e286ded055..ac6735d6d4 100644 --- a/yoga/event/event.cpp +++ b/yoga/event/event.cpp @@ -29,6 +29,8 @@ const char* LayoutPassReasonToString(const LayoutPassReason value) { return "abs_measure"; case LayoutPassReason::kFlexMeasure: return "flex_measure"; + case LayoutPassReason::kGridLayout: + return "grid_layout"; default: return "unknown"; } diff --git a/yoga/event/event.h b/yoga/event/event.h index 587c1cd063..0d032240dd 100644 --- a/yoga/event/event.h +++ b/yoga/event/event.h @@ -32,6 +32,7 @@ enum struct LayoutPassReason : int { kMeasureChild = 5, kAbsMeasureChild = 6, kFlexMeasure = 7, + kGridLayout = 8, COUNT }; diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 8068c81497..d22c4c1ef0 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -294,15 +294,15 @@ class YG_EXPORT Node : public ::YGNode { bool isNodeFlexible(); void reset(); - private: - // Used to allow resetting the node - Node& operator=(Node&&) noexcept = default; - float relativePosition( FlexDirection axis, Direction direction, float axisSize) const; + private: + // Used to allow resetting the node + Node& operator=(Node&&) noexcept = default; + void useWebDefaults() { style_.setFlexDirection(FlexDirection::Row); style_.setAlignContent(Align::Stretch); diff --git a/yoga/style/GridLine.h b/yoga/style/GridLine.h new file mode 100644 index 0000000000..a330fe1b02 --- /dev/null +++ b/yoga/style/GridLine.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +// https://www.w3.org/TR/css-grid-1/#typedef-grid-row-start-grid-line +enum class GridLineType : uint8_t { + Auto, + Integer, + Span, +}; + +struct GridLine { + GridLineType type; + // Line position (1, 2, -1, -2, etc) + int32_t integer; + + static GridLine auto_() { + return GridLine{GridLineType::Auto, 0}; + } + + static GridLine fromInteger(int32_t value) { + return GridLine{GridLineType::Integer, value}; + } + + static GridLine span(int32_t value) { + return GridLine{GridLineType::Span, value}; + } + + bool isAuto() const { + return type == GridLineType::Auto; + } + + bool isInteger() const { + return type == GridLineType::Integer; + } + + bool isSpan() const { + return type == GridLineType::Span; + } + + bool operator==(const GridLine& other) const { + return type == other.type && integer == other.integer; + } + + bool operator!=(const GridLine& other) const { + return !(*this == other); + } +}; + +} // namespace facebook::yoga diff --git a/yoga/style/GridTrack.h b/yoga/style/GridTrack.h new file mode 100644 index 0000000000..4b4c1c1a19 --- /dev/null +++ b/yoga/style/GridTrack.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook::yoga { +// https://www.w3.org/TR/css-grid-1/#typedef-track-size +struct GridTrackSize { + StyleSizeLength minSizingFunction; + StyleSizeLength maxSizingFunction; + + // These are used in the grid layout algorithm when distributing spaces among + // tracks + // TODO: maybe move them to TrackSizing since these are track states + float baseSize = 0.0f; + float growthLimit = 0.0f; + bool infinitelyGrowable = false; + + // Static factory methods for common cases + static GridTrackSize auto_() { + return GridTrackSize{StyleSizeLength::ofAuto(), StyleSizeLength::ofAuto()}; + } + + static GridTrackSize length(float points) { + auto len = StyleSizeLength::points(points); + return GridTrackSize{len, len}; + } + + static GridTrackSize fr(float fraction) { + // Flex sizing function is always a max sizing function + return GridTrackSize{ + StyleSizeLength::ofAuto(), StyleSizeLength::stretch(fraction)}; + } + + static GridTrackSize percent(float percentage) { + return GridTrackSize{ + StyleSizeLength::percent(percentage), + StyleSizeLength::percent(percentage)}; + } + + static GridTrackSize minmax(StyleSizeLength min, StyleSizeLength max) { + return GridTrackSize{min, max}; + } + + bool operator==(const GridTrackSize& other) const { + return minSizingFunction == other.minSizingFunction && + maxSizingFunction == other.maxSizingFunction; + } + + bool operator!=(const GridTrackSize& other) const { + return !(*this == other); + } +}; + +// Grid track list for grid-template-rows/columns properties +using GridTrackList = std::vector; + +} // namespace facebook::yoga diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 566b6934e6..728cc283b2 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -65,6 +67,20 @@ class YG_EXPORT Style { justifyContent_ = value; } + Justify justifyItems() const { + return justifyItems_; + } + void setJustifyItems(Justify value) { + justifyItems_ = value; + } + + Justify justifySelf() const { + return justifySelf_; + } + void setJustifySelf(Justify value) { + justifySelf_ = value; + } + Align alignContent() const { return alignContent_; } @@ -191,6 +207,64 @@ class YG_EXPORT Style { pool_.store(minDimensions_[yoga::to_underlying(axis)], value); } + // Grid Container Properties + const GridTrackList& gridTemplateColumns() const { + return gridTemplateColumns_; + } + void setGridTemplateColumns(GridTrackList value) { + gridTemplateColumns_ = std::move(value); + } + + const GridTrackList& gridTemplateRows() const { + return gridTemplateRows_; + } + void setGridTemplateRows(GridTrackList value) { + gridTemplateRows_ = std::move(value); + } + + const GridTrackList& gridAutoColumns() const { + return gridAutoColumns_; + } + void setGridAutoColumns(GridTrackList value) { + gridAutoColumns_ = std::move(value); + } + + const GridTrackList& gridAutoRows() const { + return gridAutoRows_; + } + void setGridAutoRows(GridTrackList value) { + gridAutoRows_ = std::move(value); + } + + // Grid Item Properties + const GridLine& gridColumnStart() const { + return gridColumnStart_; + } + void setGridColumnStart(GridLine value) { + gridColumnStart_ = std::move(value); + } + + const GridLine& gridColumnEnd() const { + return gridColumnEnd_; + } + void setGridColumnEnd(GridLine value) { + gridColumnEnd_ = std::move(value); + } + + const GridLine& gridRowStart() const { + return gridRowStart_; + } + void setGridRowStart(GridLine value) { + gridRowStart_ = std::move(value); + } + + const GridLine& gridRowEnd() const { + return gridRowEnd_; + } + void setGridRowEnd(GridLine value) { + gridRowEnd_ = std::move(value); + } + FloatOptional resolvedMinDimension( Direction direction, Dimension axis, @@ -515,6 +589,12 @@ class YG_EXPORT Style { return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f); } + float computeGapForDimension(Dimension dimension, float ownerSize) const { + auto gap = + dimension == Dimension::Width ? computeColumnGap() : computeRowGap(); + return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f); + } + bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const { return computeMargin(flexStartEdge(axis), direction).isAuto(); } @@ -523,10 +603,20 @@ class YG_EXPORT Style { return computeMargin(flexEndEdge(axis), direction).isAuto(); } + bool inlineStartMarginIsAuto(FlexDirection axis, Direction direction) const { + return computeMargin(inlineStartEdge(axis, direction), direction).isAuto(); + } + + bool inlineEndMarginIsAuto(FlexDirection axis, Direction direction) const { + return computeMargin(inlineEndEdge(axis, direction), direction).isAuto(); + } + bool operator==(const Style& other) const { return direction_ == other.direction_ && flexDirection_ == other.flexDirection_ && justifyContent_ == other.justifyContent_ && + justifyItems_ == other.justifyItems_ && + justifySelf_ == other.justifySelf_ && alignContent_ == other.alignContent_ && alignItems_ == other.alignItems_ && alignSelf_ == other.alignSelf_ && positionType_ == other.positionType_ && flexWrap_ == other.flexWrap_ && @@ -545,7 +635,15 @@ class YG_EXPORT Style { minDimensions_, pool_, other.minDimensions_, other.pool_) && lengthsEqual( maxDimensions_, pool_, other.maxDimensions_, other.pool_) && - numbersEqual(aspectRatio_, pool_, other.aspectRatio_, other.pool_); + numbersEqual(aspectRatio_, pool_, other.aspectRatio_, other.pool_) && + gridTemplateColumns_ == other.gridTemplateColumns_ && + gridTemplateRows_ == other.gridTemplateRows_ && + gridAutoColumns_ == other.gridAutoColumns_ && + gridAutoRows_ == other.gridAutoRows_ && + gridColumnStart_ == other.gridColumnStart_ && + gridColumnEnd_ == other.gridColumnEnd_ && + gridRowStart_ == other.gridRowStart_ && + gridRowEnd_ == other.gridRowEnd_; } bool operator!=(const Style& other) const { @@ -727,6 +825,8 @@ class YG_EXPORT Style { FlexDirection flexDirection_ : bitCount() = FlexDirection::Column; Justify justifyContent_ : bitCount() = Justify::FlexStart; + Justify justifyItems_ : bitCount() = Justify::Stretch; + Justify justifySelf_ : bitCount() = Justify::Auto; Align alignContent_ : bitCount() = Align::FlexStart; Align alignItems_ : bitCount() = Align::Stretch; Align alignSelf_ : bitCount() = Align::Auto; @@ -753,6 +853,16 @@ class YG_EXPORT Style { Dimensions maxDimensions_{}; StyleValueHandle aspectRatio_{}; + // Grid properties + GridTrackList gridTemplateColumns_{}; + GridTrackList gridTemplateRows_{}; + GridTrackList gridAutoColumns_{}; + GridTrackList gridAutoRows_{}; + GridLine gridColumnStart_{}; + GridLine gridColumnEnd_{}; + GridLine gridRowStart_{}; + GridLine gridRowEnd_{}; + StyleValuePool pool_; }; diff --git a/yoga/style/StyleSizeLength.h b/yoga/style/StyleSizeLength.h index fc4d371e42..76e079b2da 100644 --- a/yoga/style/StyleSizeLength.h +++ b/yoga/style/StyleSizeLength.h @@ -42,6 +42,12 @@ class StyleSizeLength { : StyleSizeLength{FloatOptional{value}, Unit::Percent}; } + constexpr static StyleSizeLength stretch(float fraction) { + return yoga::isUndefined(fraction) || yoga::isinf(fraction) + ? undefined() + : StyleSizeLength{FloatOptional{fraction}, Unit::Stretch}; + } + constexpr static StyleSizeLength ofAuto() { return StyleSizeLength{{}, Unit::Auto}; } @@ -98,7 +104,7 @@ class StyleSizeLength { return value_; } - constexpr FloatOptional resolve(float referenceLength) { + constexpr FloatOptional resolve(float referenceLength) const { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wswitch-enum" From a1fb9c51f8254869d3d0f0bc27b82ad26bf46cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nishan=20=28o=5E=E2=96=BD=5Eo=29?= Date: Sat, 28 Feb 2026 05:01:55 +0530 Subject: [PATCH 2/4] pr feedback --- yoga/YGGridTrackList.cpp | 54 +++++++++++++++++----------------------- yoga/YGGridTrackList.h | 40 +++++------------------------ yoga/YGNodeStyle.h | 15 +++++++++++ 3 files changed, 44 insertions(+), 65 deletions(-) diff --git a/yoga/YGGridTrackList.cpp b/yoga/YGGridTrackList.cpp index 7417656758..19bad4354f 100644 --- a/yoga/YGGridTrackList.cpp +++ b/yoga/YGGridTrackList.cpp @@ -9,32 +9,28 @@ #include #include #include +#include #include using namespace facebook::yoga; -// Internal representation of a grid track value struct YGGridTrackValue { enum class Type { Points, Percent, Fr, Auto, MinMax }; Type type; float value; - YGGridTrackValue* minValue; - YGGridTrackValue* maxValue; + std::unique_ptr minValue; + std::unique_ptr maxValue; - YGGridTrackValue(Type t, float v = 0.0f) - : type(t), value(v), minValue(nullptr), maxValue(nullptr) {} + YGGridTrackValue(Type t, float v = 0.0f) : type(t), value(v) {} - YGGridTrackValue(YGGridTrackValue* min, YGGridTrackValue* max) - : type(Type::MinMax), value(0.0f), minValue(min), maxValue(max) {} - - ~YGGridTrackValue() { - // MinMax owns its min/max values - if (type == Type::MinMax) { - delete minValue; - delete maxValue; - } - } + YGGridTrackValue( + std::unique_ptr min, + std::unique_ptr max) + : type(Type::MinMax), + value(0.0f), + minValue(std::move(min)), + maxValue(std::move(max)) {} StyleSizeLength toStyleSizeLength() const { switch (type) { @@ -54,9 +50,8 @@ struct YGGridTrackValue { } }; -// Internal representation of a grid track list struct YGGridTrackList { - std::vector tracks; + std::vector> tracks; YGGridTrackList() = default; YGGridTrackList(const YGGridTrackList&) = delete; @@ -64,17 +59,11 @@ struct YGGridTrackList { YGGridTrackList(YGGridTrackList&&) = delete; YGGridTrackList& operator=(YGGridTrackList&&) = delete; - ~YGGridTrackList() { - for (auto* track : tracks) { - delete track; - } - } - GridTrackList toGridTrackList() const { GridTrackList result; result.reserve(tracks.size()); - for (auto* track : tracks) { + for (const auto& track : tracks) { if (track->type == YGGridTrackValue::Type::MinMax) { auto min = track->minValue->toStyleSizeLength(); auto max = track->maxValue->toStyleSizeLength(); @@ -116,28 +105,31 @@ void YGGridTrackListAddTrack( YGGridTrackListRef list, YGGridTrackValueRef trackValue) { if (list && trackValue) { - list->tracks.push_back(trackValue); + list->tracks.push_back(std::unique_ptr(trackValue)); } } -YGGridTrackValueRef YGPoints(float points) { +YGGridTrackValueRef YGGridTrackPoints(float points) { return new YGGridTrackValue(YGGridTrackValue::Type::Points, points); } -YGGridTrackValueRef YGPercent(float percent) { +YGGridTrackValueRef YGGridTrackPercent(float percent) { return new YGGridTrackValue(YGGridTrackValue::Type::Percent, percent); } -YGGridTrackValueRef YGFr(float fr) { +YGGridTrackValueRef YGGridTrackFr(float fr) { return new YGGridTrackValue(YGGridTrackValue::Type::Fr, fr); } -YGGridTrackValueRef YGAuto() { +YGGridTrackValueRef YGGridTrackAuto() { return new YGGridTrackValue(YGGridTrackValue::Type::Auto); } -YGGridTrackValueRef YGMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max) { - return new YGGridTrackValue(min, max); +YGGridTrackValueRef +YGGridTrackMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max) { + return new YGGridTrackValue( + std::unique_ptr(min), + std::unique_ptr(max)); } void YGNodeStyleSetGridTemplateRows( diff --git a/yoga/YGGridTrackList.h b/yoga/YGGridTrackList.h index a89e92cca6..2b1d8a770d 100644 --- a/yoga/YGGridTrackList.h +++ b/yoga/YGGridTrackList.h @@ -42,55 +42,27 @@ YG_EXPORT void YGGridTrackListAddTrack( /** * Create a grid track value with a points (px) length. */ -YG_EXPORT YGGridTrackValueRef YGPoints(float points); +YG_EXPORT YGGridTrackValueRef YGGridTrackPoints(float points); /** * Create a grid track value with a percentage length. */ -YG_EXPORT YGGridTrackValueRef YGPercent(float percent); +YG_EXPORT YGGridTrackValueRef YGGridTrackPercent(float percent); /** * Create a grid track value with a flexible (fr) length. */ -YG_EXPORT YGGridTrackValueRef YGFr(float fr); +YG_EXPORT YGGridTrackValueRef YGGridTrackFr(float fr); /** * Create a grid track value with auto sizing. */ -YG_EXPORT YGGridTrackValueRef YGAuto(void); +YG_EXPORT YGGridTrackValueRef YGGridTrackAuto(void); /** * Create a grid track value with minmax(min, max) sizing. */ -YG_EXPORT YGGridTrackValueRef -YGMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max); - -/** - * Set the grid-template-rows property on a node. - */ -YG_EXPORT void YGNodeStyleSetGridTemplateRows( - YGNodeRef node, - YGGridTrackListRef trackList); - -/** - * Set the grid-template-columns property on a node. - */ -YG_EXPORT void YGNodeStyleSetGridTemplateColumns( - YGNodeRef node, - YGGridTrackListRef trackList); - -/** - * Set the grid-auto-rows property on a node. - */ -YG_EXPORT void YGNodeStyleSetGridAutoRows( - YGNodeRef node, - YGGridTrackListRef trackList); - -/** - * Set the grid-auto-columns property on a node. - */ -YG_EXPORT void YGNodeStyleSetGridAutoColumns( - YGNodeRef node, - YGGridTrackListRef trackList); +YG_EXPORT YGGridTrackValueRef +YGGridTrackMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max); YG_EXTERN_C_END diff --git a/yoga/YGNodeStyle.h b/yoga/YGNodeStyle.h index d1afd5c8ae..d6faeda534 100644 --- a/yoga/YGNodeStyle.h +++ b/yoga/YGNodeStyle.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -178,4 +179,18 @@ YG_EXPORT void YGNodeStyleSetGridRowEndAuto(YGNodeRef node); YG_EXPORT void YGNodeStyleSetGridRowEndSpan(YGNodeRef node, int span); YG_EXPORT int YGNodeStyleGetGridRowEnd(YGNodeConstRef node); +// Grid Container Properties +YG_EXPORT void YGNodeStyleSetGridTemplateRows( + YGNodeRef node, + YGGridTrackListRef trackList); +YG_EXPORT void YGNodeStyleSetGridTemplateColumns( + YGNodeRef node, + YGGridTrackListRef trackList); +YG_EXPORT void YGNodeStyleSetGridAutoRows( + YGNodeRef node, + YGGridTrackListRef trackList); +YG_EXPORT void YGNodeStyleSetGridAutoColumns( + YGNodeRef node, + YGGridTrackListRef trackList); + YG_EXTERN_C_END From e614f12c60a786d11635998dba48f787cd9a933f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nishan=20=28o=5E=E2=96=BD=5Eo=29?= Date: Sat, 28 Feb 2026 14:08:14 +0530 Subject: [PATCH 3/4] refactor grid track public api to use internal vector instead of allocating new list --- yoga/YGGridTrackList.cpp | 171 --------------------------------------- yoga/YGGridTrackList.h | 68 ---------------- yoga/YGNodeStyle.cpp | 169 ++++++++++++++++++++++++++++++++++++++ yoga/YGNodeStyle.h | 70 +++++++++++++--- yoga/Yoga.h | 1 - yoga/style/GridLine.h | 20 ++--- yoga/style/GridTrack.h | 19 ++--- yoga/style/Style.h | 24 ++++++ 8 files changed, 267 insertions(+), 275 deletions(-) delete mode 100644 yoga/YGGridTrackList.cpp delete mode 100644 yoga/YGGridTrackList.h diff --git a/yoga/YGGridTrackList.cpp b/yoga/YGGridTrackList.cpp deleted file mode 100644 index 19bad4354f..0000000000 --- a/yoga/YGGridTrackList.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include -#include -#include -#include - -using namespace facebook::yoga; - -struct YGGridTrackValue { - enum class Type { Points, Percent, Fr, Auto, MinMax }; - - Type type; - float value; - std::unique_ptr minValue; - std::unique_ptr maxValue; - - YGGridTrackValue(Type t, float v = 0.0f) : type(t), value(v) {} - - YGGridTrackValue( - std::unique_ptr min, - std::unique_ptr max) - : type(Type::MinMax), - value(0.0f), - minValue(std::move(min)), - maxValue(std::move(max)) {} - - StyleSizeLength toStyleSizeLength() const { - switch (type) { - case Type::Points: - return StyleSizeLength::points(value); - case Type::Percent: - return StyleSizeLength::percent(value); - case Type::Fr: - return StyleSizeLength::stretch(value); - case Type::Auto: - return StyleSizeLength::ofAuto(); - case Type::MinMax: - // MinMax should not call this, it needs special handling - return StyleSizeLength::ofAuto(); - } - return StyleSizeLength::ofAuto(); - } -}; - -struct YGGridTrackList { - std::vector> tracks; - - YGGridTrackList() = default; - YGGridTrackList(const YGGridTrackList&) = delete; - YGGridTrackList& operator=(const YGGridTrackList&) = delete; - YGGridTrackList(YGGridTrackList&&) = delete; - YGGridTrackList& operator=(YGGridTrackList&&) = delete; - - GridTrackList toGridTrackList() const { - GridTrackList result; - result.reserve(tracks.size()); - - for (const auto& track : tracks) { - if (track->type == YGGridTrackValue::Type::MinMax) { - auto min = track->minValue->toStyleSizeLength(); - auto max = track->maxValue->toStyleSizeLength(); - result.push_back(GridTrackSize::minmax(min, max)); - } else { - switch (track->type) { - case YGGridTrackValue::Type::Points: - result.push_back(GridTrackSize::length(track->value)); - break; - case YGGridTrackValue::Type::Percent: - result.push_back(GridTrackSize::percent(track->value)); - break; - case YGGridTrackValue::Type::Fr: - result.push_back(GridTrackSize::fr(track->value)); - break; - case YGGridTrackValue::Type::Auto: - result.push_back(GridTrackSize::auto_()); - break; - case YGGridTrackValue::Type::MinMax: - // Already handled above - break; - } - } - } - - return result; - } -}; - -YGGridTrackListRef YGGridTrackListCreate() { - return new YGGridTrackList(); -} - -void YGGridTrackListFree(YGGridTrackListRef list) { - delete list; -} - -void YGGridTrackListAddTrack( - YGGridTrackListRef list, - YGGridTrackValueRef trackValue) { - if (list && trackValue) { - list->tracks.push_back(std::unique_ptr(trackValue)); - } -} - -YGGridTrackValueRef YGGridTrackPoints(float points) { - return new YGGridTrackValue(YGGridTrackValue::Type::Points, points); -} - -YGGridTrackValueRef YGGridTrackPercent(float percent) { - return new YGGridTrackValue(YGGridTrackValue::Type::Percent, percent); -} - -YGGridTrackValueRef YGGridTrackFr(float fr) { - return new YGGridTrackValue(YGGridTrackValue::Type::Fr, fr); -} - -YGGridTrackValueRef YGGridTrackAuto() { - return new YGGridTrackValue(YGGridTrackValue::Type::Auto); -} - -YGGridTrackValueRef -YGGridTrackMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max) { - return new YGGridTrackValue( - std::unique_ptr(min), - std::unique_ptr(max)); -} - -void YGNodeStyleSetGridTemplateRows( - YGNodeRef node, - YGGridTrackListRef trackList) { - if (node && trackList) { - auto* n = resolveRef(node); - n->style().setGridTemplateRows(trackList->toGridTrackList()); - n->markDirtyAndPropagate(); - } -} - -void YGNodeStyleSetGridTemplateColumns( - YGNodeRef node, - YGGridTrackListRef trackList) { - if (node && trackList) { - auto* n = resolveRef(node); - n->style().setGridTemplateColumns(trackList->toGridTrackList()); - n->markDirtyAndPropagate(); - } -} - -void YGNodeStyleSetGridAutoRows(YGNodeRef node, YGGridTrackListRef trackList) { - if (node && trackList) { - auto* n = resolveRef(node); - n->style().setGridAutoRows(trackList->toGridTrackList()); - n->markDirtyAndPropagate(); - } -} - -void YGNodeStyleSetGridAutoColumns( - YGNodeRef node, - YGGridTrackListRef trackList) { - if (node && trackList) { - auto* n = resolveRef(node); - n->style().setGridAutoColumns(trackList->toGridTrackList()); - n->markDirtyAndPropagate(); - } -} diff --git a/yoga/YGGridTrackList.h b/yoga/YGGridTrackList.h deleted file mode 100644 index 2b1d8a770d..0000000000 --- a/yoga/YGGridTrackList.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -YG_EXTERN_C_BEGIN - -/** - * Opaque handle to a grid track list for building grid-template-rows/columns. - */ -typedef struct YGGridTrackList* YGGridTrackListRef; - -/** - * Opaque handle to a grid track value. - */ -typedef struct YGGridTrackValue* YGGridTrackValueRef; - -/** - * Create a new grid track list. - */ -YG_EXPORT YGGridTrackListRef YGGridTrackListCreate(void); - -/** - * Free a grid track list. - */ -YG_EXPORT void YGGridTrackListFree(YGGridTrackListRef list); - -/** - * Add a track to the grid track list. - */ -YG_EXPORT void YGGridTrackListAddTrack( - YGGridTrackListRef list, - YGGridTrackValueRef trackValue); - -/** - * Create a grid track value with a points (px) length. - */ -YG_EXPORT YGGridTrackValueRef YGGridTrackPoints(float points); - -/** - * Create a grid track value with a percentage length. - */ -YG_EXPORT YGGridTrackValueRef YGGridTrackPercent(float percent); - -/** - * Create a grid track value with a flexible (fr) length. - */ -YG_EXPORT YGGridTrackValueRef YGGridTrackFr(float fr); - -/** - * Create a grid track value with auto sizing. - */ -YG_EXPORT YGGridTrackValueRef YGGridTrackAuto(void); - -/** - * Create a grid track value with minmax(min, max) sizing. - */ -YG_EXPORT YGGridTrackValueRef -YGGridTrackMinMax(YGGridTrackValueRef min, YGGridTrackValueRef max); - -YG_EXTERN_C_END diff --git a/yoga/YGNodeStyle.cpp b/yoga/YGNodeStyle.cpp index f859c8427a..7f5303ee44 100644 --- a/yoga/YGNodeStyle.cpp +++ b/yoga/YGNodeStyle.cpp @@ -8,6 +8,7 @@ #include #include #include +#include using namespace facebook; using namespace facebook::yoga; @@ -603,3 +604,171 @@ int32_t YGNodeStyleGetGridRowEnd(YGNodeConstRef node) { const auto& gridLine = resolveRef(node)->style().gridRowEnd(); return gridLine.isInteger() ? gridLine.integer : 0; } + +// Grid Container Properties + +namespace { + +GridTrackSize gridTrackSizeFromTypeAndValue(YGGridTrackType type, float value) { + switch (type) { + case YGGridTrackTypePoints: + return GridTrackSize::length(value); + case YGGridTrackTypePercent: + return GridTrackSize::percent(value); + case YGGridTrackTypeFr: + return GridTrackSize::fr(value); + case YGGridTrackTypeAuto: + return GridTrackSize::auto_(); + default: + return GridTrackSize::auto_(); + } +} + +StyleSizeLength styleSizeLengthFromTypeAndValue( + YGGridTrackType type, + float value) { + switch (type) { + case YGGridTrackTypePoints: + return StyleSizeLength::points(value); + case YGGridTrackTypePercent: + return StyleSizeLength::percent(value); + case YGGridTrackTypeFr: + return StyleSizeLength::stretch(value); + case YGGridTrackTypeAuto: + return StyleSizeLength::ofAuto(); + default: + return StyleSizeLength::ofAuto(); + } +} + +} // namespace + +// GridTemplateColumns + +void YGNodeStyleSetGridTemplateColumnsCount( + YGNodeRef node, + uint32_t count) { + resolveRef(node)->style().resizeGridTemplateColumns(count); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridTemplateColumn( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value) { + resolveRef(node)->style().setGridTemplateColumnAt( + index, gridTrackSizeFromTypeAndValue(type, value)); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridTemplateColumnMinMax( + YGNodeRef node, + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue) { + resolveRef(node)->style().setGridTemplateColumnAt( + index, + GridTrackSize::minmax( + styleSizeLengthFromTypeAndValue(minType, minValue), + styleSizeLengthFromTypeAndValue(maxType, maxValue))); + resolveRef(node)->markDirtyAndPropagate(); +} + +// GridTemplateRows + +void YGNodeStyleSetGridTemplateRowsCount(YGNodeRef node, uint32_t count) { + resolveRef(node)->style().resizeGridTemplateRows(count); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridTemplateRow( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value) { + resolveRef(node)->style().setGridTemplateRowAt( + index, gridTrackSizeFromTypeAndValue(type, value)); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridTemplateRowMinMax( + YGNodeRef node, + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue) { + resolveRef(node)->style().setGridTemplateRowAt( + index, + GridTrackSize::minmax( + styleSizeLengthFromTypeAndValue(minType, minValue), + styleSizeLengthFromTypeAndValue(maxType, maxValue))); + resolveRef(node)->markDirtyAndPropagate(); +} + +// GridAutoColumns + +void YGNodeStyleSetGridAutoColumnsCount(YGNodeRef node, uint32_t count) { + resolveRef(node)->style().resizeGridAutoColumns(count); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridAutoColumn( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value) { + resolveRef(node)->style().setGridAutoColumnAt( + index, gridTrackSizeFromTypeAndValue(type, value)); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridAutoColumnMinMax( + YGNodeRef node, + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue) { + resolveRef(node)->style().setGridAutoColumnAt( + index, + GridTrackSize::minmax( + styleSizeLengthFromTypeAndValue(minType, minValue), + styleSizeLengthFromTypeAndValue(maxType, maxValue))); + resolveRef(node)->markDirtyAndPropagate(); +} + +// GridAutoRows + +void YGNodeStyleSetGridAutoRowsCount(YGNodeRef node, uint32_t count) { + resolveRef(node)->style().resizeGridAutoRows(count); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridAutoRow( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value) { + resolveRef(node)->style().setGridAutoRowAt( + index, gridTrackSizeFromTypeAndValue(type, value)); + resolveRef(node)->markDirtyAndPropagate(); +} + +void YGNodeStyleSetGridAutoRowMinMax( + YGNodeRef node, + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue) { + resolveRef(node)->style().setGridAutoRowAt( + index, + GridTrackSize::minmax( + styleSizeLengthFromTypeAndValue(minType, minValue), + styleSizeLengthFromTypeAndValue(maxType, maxValue))); + resolveRef(node)->markDirtyAndPropagate(); +} diff --git a/yoga/YGNodeStyle.h b/yoga/YGNodeStyle.h index d6faeda534..3f29d7a81d 100644 --- a/yoga/YGNodeStyle.h +++ b/yoga/YGNodeStyle.h @@ -8,7 +8,8 @@ #pragma once #include -#include +#include +#include #include #include @@ -180,17 +181,68 @@ YG_EXPORT void YGNodeStyleSetGridRowEndSpan(YGNodeRef node, int span); YG_EXPORT int YGNodeStyleGetGridRowEnd(YGNodeConstRef node); // Grid Container Properties -YG_EXPORT void YGNodeStyleSetGridTemplateRows( +YG_EXPORT void YGNodeStyleSetGridTemplateColumnsCount( YGNodeRef node, - YGGridTrackListRef trackList); -YG_EXPORT void YGNodeStyleSetGridTemplateColumns( + uint32_t count); +YG_EXPORT void YGNodeStyleSetGridTemplateColumn( YGNodeRef node, - YGGridTrackListRef trackList); -YG_EXPORT void YGNodeStyleSetGridAutoRows( + uint32_t index, + YGGridTrackType type, + float value); +YG_EXPORT void YGNodeStyleSetGridTemplateColumnMinMax( YGNodeRef node, - YGGridTrackListRef trackList); -YG_EXPORT void YGNodeStyleSetGridAutoColumns( + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue); + +YG_EXPORT void YGNodeStyleSetGridTemplateRowsCount( + YGNodeRef node, + uint32_t count); +YG_EXPORT void YGNodeStyleSetGridTemplateRow( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value); +YG_EXPORT void YGNodeStyleSetGridTemplateRowMinMax( + YGNodeRef node, + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue); + +YG_EXPORT void YGNodeStyleSetGridAutoColumnsCount( + YGNodeRef node, + uint32_t count); +YG_EXPORT void YGNodeStyleSetGridAutoColumn( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value); +YG_EXPORT void YGNodeStyleSetGridAutoColumnMinMax( + YGNodeRef node, + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue); + +YG_EXPORT void YGNodeStyleSetGridAutoRowsCount( + YGNodeRef node, + uint32_t count); +YG_EXPORT void YGNodeStyleSetGridAutoRow( + YGNodeRef node, + uint32_t index, + YGGridTrackType type, + float value); +YG_EXPORT void YGNodeStyleSetGridAutoRowMinMax( YGNodeRef node, - YGGridTrackListRef trackList); + uint32_t index, + YGGridTrackType minType, + float minValue, + YGGridTrackType maxType, + float maxValue); YG_EXTERN_C_END diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 25b7a8e83c..97f05ed3ea 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -13,7 +13,6 @@ #include // IWYU pragma: export #include // IWYU pragma: export -#include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export diff --git a/yoga/style/GridLine.h b/yoga/style/GridLine.h index a330fe1b02..702170134b 100644 --- a/yoga/style/GridLine.h +++ b/yoga/style/GridLine.h @@ -25,37 +25,31 @@ struct GridLine { // Line position (1, 2, -1, -2, etc) int32_t integer; - static GridLine auto_() { + constexpr static GridLine auto_() { return GridLine{GridLineType::Auto, 0}; } - static GridLine fromInteger(int32_t value) { + constexpr static GridLine fromInteger(int32_t value) { return GridLine{GridLineType::Integer, value}; } - static GridLine span(int32_t value) { + constexpr static GridLine span(int32_t value) { return GridLine{GridLineType::Span, value}; } - bool isAuto() const { + constexpr bool isAuto() const { return type == GridLineType::Auto; } - bool isInteger() const { + constexpr bool isInteger() const { return type == GridLineType::Integer; } - bool isSpan() const { + constexpr bool isSpan() const { return type == GridLineType::Span; } - bool operator==(const GridLine& other) const { - return type == other.type && integer == other.integer; - } - - bool operator!=(const GridLine& other) const { - return !(*this == other); - } + bool operator==(const GridLine& other) const = default; }; } // namespace facebook::yoga diff --git a/yoga/style/GridTrack.h b/yoga/style/GridTrack.h index 4b4c1c1a19..c292391dbd 100644 --- a/yoga/style/GridTrack.h +++ b/yoga/style/GridTrack.h @@ -24,39 +24,32 @@ struct GridTrackSize { bool infinitelyGrowable = false; // Static factory methods for common cases - static GridTrackSize auto_() { + constexpr static GridTrackSize auto_() { return GridTrackSize{StyleSizeLength::ofAuto(), StyleSizeLength::ofAuto()}; } - static GridTrackSize length(float points) { + constexpr static GridTrackSize length(float points) { auto len = StyleSizeLength::points(points); return GridTrackSize{len, len}; } - static GridTrackSize fr(float fraction) { + constexpr static GridTrackSize fr(float fraction) { // Flex sizing function is always a max sizing function return GridTrackSize{ StyleSizeLength::ofAuto(), StyleSizeLength::stretch(fraction)}; } - static GridTrackSize percent(float percentage) { + constexpr static GridTrackSize percent(float percentage) { return GridTrackSize{ StyleSizeLength::percent(percentage), StyleSizeLength::percent(percentage)}; } - static GridTrackSize minmax(StyleSizeLength min, StyleSizeLength max) { + constexpr static GridTrackSize minmax(StyleSizeLength min, StyleSizeLength max) { return GridTrackSize{min, max}; } - bool operator==(const GridTrackSize& other) const { - return minSizingFunction == other.minSizingFunction && - maxSizingFunction == other.maxSizingFunction; - } - - bool operator!=(const GridTrackSize& other) const { - return !(*this == other); - } + bool operator==(const GridTrackSize& other) const = default; }; // Grid track list for grid-template-rows/columns properties diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 728cc283b2..33fd7c43b0 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -214,6 +214,12 @@ class YG_EXPORT Style { void setGridTemplateColumns(GridTrackList value) { gridTemplateColumns_ = std::move(value); } + void resizeGridTemplateColumns(uint32_t count) { + gridTemplateColumns_.resize(count); + } + void setGridTemplateColumnAt(uint32_t index, GridTrackSize value) { + gridTemplateColumns_[index] = value; + } const GridTrackList& gridTemplateRows() const { return gridTemplateRows_; @@ -221,6 +227,12 @@ class YG_EXPORT Style { void setGridTemplateRows(GridTrackList value) { gridTemplateRows_ = std::move(value); } + void resizeGridTemplateRows(uint32_t count) { + gridTemplateRows_.resize(count); + } + void setGridTemplateRowAt(uint32_t index, GridTrackSize value) { + gridTemplateRows_[index] = value; + } const GridTrackList& gridAutoColumns() const { return gridAutoColumns_; @@ -228,6 +240,12 @@ class YG_EXPORT Style { void setGridAutoColumns(GridTrackList value) { gridAutoColumns_ = std::move(value); } + void resizeGridAutoColumns(uint32_t count) { + gridAutoColumns_.resize(count); + } + void setGridAutoColumnAt(uint32_t index, GridTrackSize value) { + gridAutoColumns_[index] = value; + } const GridTrackList& gridAutoRows() const { return gridAutoRows_; @@ -235,6 +253,12 @@ class YG_EXPORT Style { void setGridAutoRows(GridTrackList value) { gridAutoRows_ = std::move(value); } + void resizeGridAutoRows(uint32_t count) { + gridAutoRows_.resize(count); + } + void setGridAutoRowAt(uint32_t index, GridTrackSize value) { + gridAutoRows_[index] = value; + } // Grid Item Properties const GridLine& gridColumnStart() const { From c457221c059acbae9cd11379b41640da500020d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nishan=20=28o=5E=E2=96=BD=5Eo=29?= Date: Sat, 28 Feb 2026 14:42:17 +0530 Subject: [PATCH 4/4] use size_t in public track apis --- yoga/YGNodeStyle.cpp | 24 ++++++++++++------------ yoga/YGNodeStyle.h | 25 ++++++++++++------------- yoga/style/Style.h | 16 ++++++++-------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/yoga/YGNodeStyle.cpp b/yoga/YGNodeStyle.cpp index 7f5303ee44..31f095a213 100644 --- a/yoga/YGNodeStyle.cpp +++ b/yoga/YGNodeStyle.cpp @@ -647,14 +647,14 @@ StyleSizeLength styleSizeLengthFromTypeAndValue( void YGNodeStyleSetGridTemplateColumnsCount( YGNodeRef node, - uint32_t count) { + size_t count) { resolveRef(node)->style().resizeGridTemplateColumns(count); resolveRef(node)->markDirtyAndPropagate(); } void YGNodeStyleSetGridTemplateColumn( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value) { resolveRef(node)->style().setGridTemplateColumnAt( @@ -664,7 +664,7 @@ void YGNodeStyleSetGridTemplateColumn( void YGNodeStyleSetGridTemplateColumnMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, @@ -679,14 +679,14 @@ void YGNodeStyleSetGridTemplateColumnMinMax( // GridTemplateRows -void YGNodeStyleSetGridTemplateRowsCount(YGNodeRef node, uint32_t count) { +void YGNodeStyleSetGridTemplateRowsCount(YGNodeRef node, size_t count) { resolveRef(node)->style().resizeGridTemplateRows(count); resolveRef(node)->markDirtyAndPropagate(); } void YGNodeStyleSetGridTemplateRow( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value) { resolveRef(node)->style().setGridTemplateRowAt( @@ -696,7 +696,7 @@ void YGNodeStyleSetGridTemplateRow( void YGNodeStyleSetGridTemplateRowMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, @@ -711,14 +711,14 @@ void YGNodeStyleSetGridTemplateRowMinMax( // GridAutoColumns -void YGNodeStyleSetGridAutoColumnsCount(YGNodeRef node, uint32_t count) { +void YGNodeStyleSetGridAutoColumnsCount(YGNodeRef node, size_t count) { resolveRef(node)->style().resizeGridAutoColumns(count); resolveRef(node)->markDirtyAndPropagate(); } void YGNodeStyleSetGridAutoColumn( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value) { resolveRef(node)->style().setGridAutoColumnAt( @@ -728,7 +728,7 @@ void YGNodeStyleSetGridAutoColumn( void YGNodeStyleSetGridAutoColumnMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, @@ -743,14 +743,14 @@ void YGNodeStyleSetGridAutoColumnMinMax( // GridAutoRows -void YGNodeStyleSetGridAutoRowsCount(YGNodeRef node, uint32_t count) { +void YGNodeStyleSetGridAutoRowsCount(YGNodeRef node, size_t count) { resolveRef(node)->style().resizeGridAutoRows(count); resolveRef(node)->markDirtyAndPropagate(); } void YGNodeStyleSetGridAutoRow( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value) { resolveRef(node)->style().setGridAutoRowAt( @@ -760,7 +760,7 @@ void YGNodeStyleSetGridAutoRow( void YGNodeStyleSetGridAutoRowMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, diff --git a/yoga/YGNodeStyle.h b/yoga/YGNodeStyle.h index 3f29d7a81d..4aca2c738e 100644 --- a/yoga/YGNodeStyle.h +++ b/yoga/YGNodeStyle.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include @@ -183,15 +182,15 @@ YG_EXPORT int YGNodeStyleGetGridRowEnd(YGNodeConstRef node); // Grid Container Properties YG_EXPORT void YGNodeStyleSetGridTemplateColumnsCount( YGNodeRef node, - uint32_t count); + size_t count); YG_EXPORT void YGNodeStyleSetGridTemplateColumn( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value); YG_EXPORT void YGNodeStyleSetGridTemplateColumnMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, @@ -199,15 +198,15 @@ YG_EXPORT void YGNodeStyleSetGridTemplateColumnMinMax( YG_EXPORT void YGNodeStyleSetGridTemplateRowsCount( YGNodeRef node, - uint32_t count); + size_t count); YG_EXPORT void YGNodeStyleSetGridTemplateRow( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value); YG_EXPORT void YGNodeStyleSetGridTemplateRowMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, @@ -215,15 +214,15 @@ YG_EXPORT void YGNodeStyleSetGridTemplateRowMinMax( YG_EXPORT void YGNodeStyleSetGridAutoColumnsCount( YGNodeRef node, - uint32_t count); + size_t count); YG_EXPORT void YGNodeStyleSetGridAutoColumn( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value); YG_EXPORT void YGNodeStyleSetGridAutoColumnMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, @@ -231,15 +230,15 @@ YG_EXPORT void YGNodeStyleSetGridAutoColumnMinMax( YG_EXPORT void YGNodeStyleSetGridAutoRowsCount( YGNodeRef node, - uint32_t count); + size_t count); YG_EXPORT void YGNodeStyleSetGridAutoRow( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType type, float value); YG_EXPORT void YGNodeStyleSetGridAutoRowMinMax( YGNodeRef node, - uint32_t index, + size_t index, YGGridTrackType minType, float minValue, YGGridTrackType maxType, diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 33fd7c43b0..c6c762fec4 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -214,10 +214,10 @@ class YG_EXPORT Style { void setGridTemplateColumns(GridTrackList value) { gridTemplateColumns_ = std::move(value); } - void resizeGridTemplateColumns(uint32_t count) { + void resizeGridTemplateColumns(size_t count) { gridTemplateColumns_.resize(count); } - void setGridTemplateColumnAt(uint32_t index, GridTrackSize value) { + void setGridTemplateColumnAt(size_t index, GridTrackSize value) { gridTemplateColumns_[index] = value; } @@ -227,10 +227,10 @@ class YG_EXPORT Style { void setGridTemplateRows(GridTrackList value) { gridTemplateRows_ = std::move(value); } - void resizeGridTemplateRows(uint32_t count) { + void resizeGridTemplateRows(size_t count) { gridTemplateRows_.resize(count); } - void setGridTemplateRowAt(uint32_t index, GridTrackSize value) { + void setGridTemplateRowAt(size_t index, GridTrackSize value) { gridTemplateRows_[index] = value; } @@ -240,10 +240,10 @@ class YG_EXPORT Style { void setGridAutoColumns(GridTrackList value) { gridAutoColumns_ = std::move(value); } - void resizeGridAutoColumns(uint32_t count) { + void resizeGridAutoColumns(size_t count) { gridAutoColumns_.resize(count); } - void setGridAutoColumnAt(uint32_t index, GridTrackSize value) { + void setGridAutoColumnAt(size_t index, GridTrackSize value) { gridAutoColumns_[index] = value; } @@ -253,10 +253,10 @@ class YG_EXPORT Style { void setGridAutoRows(GridTrackList value) { gridAutoRows_ = std::move(value); } - void resizeGridAutoRows(uint32_t count) { + void resizeGridAutoRows(size_t count) { gridAutoRows_.resize(count); } - void setGridAutoRowAt(uint32_t index, GridTrackSize value) { + void setGridAutoRowAt(size_t index, GridTrackSize value) { gridAutoRows_[index] = value; }