Skip to content

Commit c248146

Browse files
committed
feat: calc layout calculations
1 parent 985ad38 commit c248146

25 files changed

Lines changed: 1326 additions & 299 deletions

enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"MaxContent",
1717
"FitContent",
1818
"Stretch",
19+
"Calc",
1920
],
2021
"FlexDirection": ["Column", "ColumnReverse", "Row", "RowReverse"],
2122
"Justify": [

yoga/YGCalc.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <yoga/YGMacros.h>
11+
12+
YG_EXTERN_C_BEGIN
13+
14+
/**
15+
* Structure used to represent a calc() expression with mixed units.
16+
*/
17+
typedef struct YGCalc {
18+
float px;
19+
float percent;
20+
float vw;
21+
float vh;
22+
} YGCalc;
23+
24+
YG_EXTERN_C_END

yoga/YGConfig.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,36 @@ float YGConfigGetPointScaleFactor(const YGConfigConstRef config) {
4747
return resolveRef(config)->getPointScaleFactor();
4848
}
4949

50+
void YGConfigSetViewportWidth(
51+
const YGConfigRef config,
52+
const float viewportWidth) {
53+
yoga::assertFatalWithConfig(
54+
resolveRef(config),
55+
viewportWidth >= 0.0f,
56+
"Viewport width should not be less than zero");
57+
58+
resolveRef(config)->setViewportWidth(viewportWidth);
59+
}
60+
61+
float YGConfigGetViewportWidth(const YGConfigConstRef config) {
62+
return resolveRef(config)->getViewportWidth();
63+
}
64+
65+
void YGConfigSetViewportHeight(
66+
const YGConfigRef config,
67+
const float viewportHeight) {
68+
yoga::assertFatalWithConfig(
69+
resolveRef(config),
70+
viewportHeight >= 0.0f,
71+
"Viewport height should not be less than zero");
72+
73+
resolveRef(config)->setViewportHeight(viewportHeight);
74+
}
75+
76+
float YGConfigGetViewportHeight(const YGConfigConstRef config) {
77+
return resolveRef(config)->getViewportHeight();
78+
}
79+
5080
void YGConfigSetErrata(YGConfigRef config, YGErrata errata) {
5181
resolveRef(config)->setErrata(scopedEnum(errata));
5282
}

yoga/YGConfig.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,30 @@ YG_EXPORT void YGConfigSetPointScaleFactor(
7575
*/
7676
YG_EXPORT float YGConfigGetPointScaleFactor(YGConfigConstRef config);
7777

78+
/**
79+
* Sets the viewport width used for resolving CSS calc() expressions with
80+
* viewport units (vw). This should be the width of the root viewport in points.
81+
*/
82+
YG_EXPORT void YGConfigSetViewportWidth(YGConfigRef config, float viewportWidth);
83+
84+
/**
85+
* Gets the currently set viewport width.
86+
*/
87+
YG_EXPORT float YGConfigGetViewportWidth(YGConfigConstRef config);
88+
89+
/**
90+
* Sets the viewport height used for resolving CSS calc() expressions with
91+
* viewport units (vh). This should be the height of the root viewport in points.
92+
*/
93+
YG_EXPORT void YGConfigSetViewportHeight(
94+
YGConfigRef config,
95+
float viewportHeight);
96+
97+
/**
98+
* Gets the currently set viewport height.
99+
*/
100+
YG_EXPORT float YGConfigGetViewportHeight(YGConfigConstRef config);
101+
78102
/**
79103
* Configures how Yoga balances W3C conformance vs compatibility with layouts
80104
* created against earlier versions of Yoga.

yoga/YGEnums.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ const char* YGUnitToString(const YGUnit value) {
251251
return "fit-content";
252252
case YGUnitStretch:
253253
return "stretch";
254+
case YGUnitCalc:
255+
return "calc";
254256
}
255257
return "unknown";
256258
}

yoga/YGEnums.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ YG_ENUM_DECL(
134134
YGUnitAuto,
135135
YGUnitMaxContent,
136136
YGUnitFitContent,
137-
YGUnitStretch)
137+
YGUnitStretch,
138+
YGUnitCalc)
138139

139140
YG_ENUM_DECL(
140141
YGWrap,

yoga/YGNodeStyle.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@
88
#include <yoga/Yoga.h>
99
#include <yoga/debug/AssertFatal.h>
1010
#include <yoga/node/Node.h>
11+
#include <yoga/style/StyleCalcLength.h>
1112

1213
using namespace facebook;
1314
using namespace facebook::yoga;
1415

1516
namespace {
1617

18+
inline StyleCalcLength YGCalcToStyleCalcLength(YGCalc calc) {
19+
return {
20+
FloatOptional{calc.px},
21+
FloatOptional{calc.percent},
22+
FloatOptional{calc.vw},
23+
FloatOptional{calc.vh}};
24+
}
25+
1726
template <auto GetterT, auto SetterT, typename ValueT>
1827
void updateStyle(YGNodeRef node, ValueT value) {
1928
auto& style = resolveRef(node)->style();
@@ -207,6 +216,11 @@ void YGNodeStyleSetFlexBasisStretch(const YGNodeRef node) {
207216
node, StyleSizeLength::ofStretch());
208217
}
209218

219+
void YGNodeStyleSetFlexBasisCalc(const YGNodeRef node, const YGCalc calc) {
220+
updateStyle<&Style::flexBasis, &Style::setFlexBasis>(
221+
node, StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
222+
}
223+
210224
YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) {
211225
return (YGValue)resolveRef(node)->style().flexBasis();
212226
}
@@ -226,6 +240,11 @@ void YGNodeStyleSetPositionAuto(YGNodeRef node, YGEdge edge) {
226240
node, scopedEnum(edge), StyleLength::ofAuto());
227241
}
228242

243+
void YGNodeStyleSetPositionCalc(YGNodeRef node, YGEdge edge, YGCalc calc) {
244+
updateStyle<&Style::position, &Style::setPosition>(
245+
node, scopedEnum(edge), StyleLength::calc(YGCalcToStyleCalcLength(calc)));
246+
}
247+
229248
YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) {
230249
return (YGValue)resolveRef(node)->style().position(scopedEnum(edge));
231250
}
@@ -245,6 +264,11 @@ void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) {
245264
node, scopedEnum(edge), StyleLength::ofAuto());
246265
}
247266

267+
void YGNodeStyleSetMarginCalc(YGNodeRef node, YGEdge edge, YGCalc calc) {
268+
updateStyle<&Style::margin, &Style::setMargin>(
269+
node, scopedEnum(edge), StyleLength::calc(YGCalcToStyleCalcLength(calc)));
270+
}
271+
248272
YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) {
249273
return (YGValue)resolveRef(node)->style().margin(scopedEnum(edge));
250274
}
@@ -259,6 +283,11 @@ void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) {
259283
node, scopedEnum(edge), StyleLength::percent(percent));
260284
}
261285

286+
void YGNodeStyleSetPaddingCalc(YGNodeRef node, YGEdge edge, YGCalc calc) {
287+
updateStyle<&Style::padding, &Style::setPadding>(
288+
node, scopedEnum(edge), StyleLength::calc(YGCalcToStyleCalcLength(calc)));
289+
}
290+
262291
YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) {
263292
return (YGValue)resolveRef(node)->style().padding(scopedEnum(edge));
264293
}
@@ -271,6 +300,14 @@ void YGNodeStyleSetBorder(
271300
node, scopedEnum(edge), StyleLength::points(border));
272301
}
273302

303+
void YGNodeStyleSetBorderCalc(
304+
const YGNodeRef node,
305+
const YGEdge edge,
306+
const YGCalc calc) {
307+
updateStyle<&Style::border, &Style::setBorder>(
308+
node, scopedEnum(edge), StyleLength::calc(YGCalcToStyleCalcLength(calc)));
309+
}
310+
274311
float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) {
275312
auto border = resolveRef(node)->style().border(scopedEnum(edge));
276313
if (border.isUndefined() || border.isAuto()) {
@@ -293,6 +330,13 @@ void YGNodeStyleSetGapPercent(YGNodeRef node, YGGutter gutter, float percent) {
293330
node, scopedEnum(gutter), StyleLength::percent(percent));
294331
}
295332

333+
void YGNodeStyleSetGapCalc(YGNodeRef node, YGGutter gutter, YGCalc calc) {
334+
updateStyle<&Style::gap, &Style::setGap>(
335+
node,
336+
scopedEnum(gutter),
337+
StyleLength::calc(YGCalcToStyleCalcLength(calc)));
338+
}
339+
296340
YGValue YGNodeStyleGetGap(const YGNodeConstRef node, const YGGutter gutter) {
297341
return (YGValue)resolveRef(node)->style().gap(scopedEnum(gutter));
298342
}
@@ -346,6 +390,13 @@ void YGNodeStyleSetWidthStretch(YGNodeRef node) {
346390
node, Dimension::Width, StyleSizeLength::ofStretch());
347391
}
348392

393+
void YGNodeStyleSetWidthCalc(YGNodeRef node, YGCalc calc) {
394+
updateStyle<&Style::dimension, &Style::setDimension>(
395+
node,
396+
Dimension::Width,
397+
StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
398+
}
399+
349400
YGValue YGNodeStyleGetWidth(YGNodeConstRef node) {
350401
return (YGValue)resolveRef(node)->style().dimension(Dimension::Width);
351402
}
@@ -380,6 +431,13 @@ void YGNodeStyleSetHeightStretch(YGNodeRef node) {
380431
node, Dimension::Height, StyleSizeLength::ofStretch());
381432
}
382433

434+
void YGNodeStyleSetHeightCalc(YGNodeRef node, YGCalc calc) {
435+
updateStyle<&Style::dimension, &Style::setDimension>(
436+
node,
437+
Dimension::Height,
438+
StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
439+
}
440+
383441
YGValue YGNodeStyleGetHeight(YGNodeConstRef node) {
384442
return (YGValue)resolveRef(node)->style().dimension(Dimension::Height);
385443
}
@@ -409,6 +467,13 @@ void YGNodeStyleSetMinWidthStretch(const YGNodeRef node) {
409467
node, Dimension::Width, StyleSizeLength::ofStretch());
410468
}
411469

470+
void YGNodeStyleSetMinWidthCalc(const YGNodeRef node, const YGCalc calc) {
471+
updateStyle<&Style::minDimension, &Style::setMinDimension>(
472+
node,
473+
Dimension::Width,
474+
StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
475+
}
476+
412477
YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) {
413478
return (YGValue)resolveRef(node)->style().minDimension(Dimension::Width);
414479
}
@@ -440,6 +505,13 @@ void YGNodeStyleSetMinHeightStretch(const YGNodeRef node) {
440505
node, Dimension::Height, StyleSizeLength::ofStretch());
441506
}
442507

508+
void YGNodeStyleSetMinHeightCalc(const YGNodeRef node, const YGCalc calc) {
509+
updateStyle<&Style::minDimension, &Style::setMinDimension>(
510+
node,
511+
Dimension::Height,
512+
StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
513+
}
514+
443515
YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) {
444516
return (YGValue)resolveRef(node)->style().minDimension(Dimension::Height);
445517
}
@@ -469,6 +541,13 @@ void YGNodeStyleSetMaxWidthStretch(const YGNodeRef node) {
469541
node, Dimension::Width, StyleSizeLength::ofStretch());
470542
}
471543

544+
void YGNodeStyleSetMaxWidthCalc(const YGNodeRef node, const YGCalc calc) {
545+
updateStyle<&Style::maxDimension, &Style::setMaxDimension>(
546+
node,
547+
Dimension::Width,
548+
StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
549+
}
550+
472551
YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) {
473552
return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Width);
474553
}
@@ -500,6 +579,13 @@ void YGNodeStyleSetMaxHeightStretch(const YGNodeRef node) {
500579
node, Dimension::Height, StyleSizeLength::ofStretch());
501580
}
502581

582+
void YGNodeStyleSetMaxHeightCalc(const YGNodeRef node, const YGCalc calc) {
583+
updateStyle<&Style::maxDimension, &Style::setMaxDimension>(
584+
node,
585+
Dimension::Height,
586+
StyleSizeLength::calc(YGCalcToStyleCalcLength(calc)));
587+
}
588+
503589
YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) {
504590
return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Height);
505591
}

0 commit comments

Comments
 (0)