/src/yoga/yoga/style/Style.h
Line | Count | Source |
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 <array> |
11 | | #include <cstdint> |
12 | | #include <type_traits> |
13 | | |
14 | | #include <yoga/Yoga.h> |
15 | | |
16 | | #include <yoga/algorithm/FlexDirection.h> |
17 | | #include <yoga/enums/Align.h> |
18 | | #include <yoga/enums/BoxSizing.h> |
19 | | #include <yoga/enums/Dimension.h> |
20 | | #include <yoga/enums/Direction.h> |
21 | | #include <yoga/enums/Display.h> |
22 | | #include <yoga/enums/Edge.h> |
23 | | #include <yoga/enums/FlexDirection.h> |
24 | | #include <yoga/enums/Gutter.h> |
25 | | #include <yoga/enums/Justify.h> |
26 | | #include <yoga/enums/Overflow.h> |
27 | | #include <yoga/enums/PhysicalEdge.h> |
28 | | #include <yoga/enums/PositionType.h> |
29 | | #include <yoga/enums/Unit.h> |
30 | | #include <yoga/enums/Wrap.h> |
31 | | #include <yoga/numeric/FloatOptional.h> |
32 | | #include <yoga/style/StyleLength.h> |
33 | | #include <yoga/style/StyleSizeLength.h> |
34 | | #include <yoga/style/StyleValuePool.h> |
35 | | |
36 | | namespace facebook::yoga { |
37 | | |
38 | | class YG_EXPORT Style { |
39 | | public: |
40 | | using Length = StyleLength; |
41 | | using SizeLength = StyleSizeLength; |
42 | | |
43 | | static constexpr float DefaultFlexGrow = 0.0f; |
44 | | static constexpr float DefaultFlexShrink = 0.0f; |
45 | | static constexpr float WebDefaultFlexShrink = 1.0f; |
46 | | |
47 | 29.2M | Direction direction() const { |
48 | 29.2M | return direction_; |
49 | 29.2M | } |
50 | 0 | void setDirection(Direction value) { |
51 | 0 | direction_ = value; |
52 | 0 | } |
53 | | |
54 | 30.4M | FlexDirection flexDirection() const { |
55 | 30.4M | return flexDirection_; |
56 | 30.4M | } |
57 | 1.56M | void setFlexDirection(FlexDirection value) { |
58 | 1.56M | flexDirection_ = value; |
59 | 1.56M | } |
60 | | |
61 | 1.64M | Justify justifyContent() const { |
62 | 1.64M | return justifyContent_; |
63 | 1.64M | } |
64 | 0 | void setJustifyContent(Justify value) { |
65 | 0 | justifyContent_ = value; |
66 | 0 | } |
67 | | |
68 | 2.40M | Align alignContent() const { |
69 | 2.40M | return alignContent_; |
70 | 2.40M | } |
71 | 0 | void setAlignContent(Align value) { |
72 | 0 | alignContent_ = value; |
73 | 0 | } |
74 | | |
75 | 48.5M | Align alignItems() const { |
76 | 48.5M | return alignItems_; |
77 | 48.5M | } |
78 | 0 | void setAlignItems(Align value) { |
79 | 0 | alignItems_ = value; |
80 | 0 | } |
81 | | |
82 | 60.6M | Align alignSelf() const { |
83 | 60.6M | return alignSelf_; |
84 | 60.6M | } |
85 | 0 | void setAlignSelf(Align value) { |
86 | 0 | alignSelf_ = value; |
87 | 0 | } |
88 | | |
89 | 90.3M | PositionType positionType() const { |
90 | 90.3M | return positionType_; |
91 | 90.3M | } |
92 | 0 | void setPositionType(PositionType value) { |
93 | 0 | positionType_ = value; |
94 | 0 | } |
95 | | |
96 | 4.94M | Wrap flexWrap() const { |
97 | 4.94M | return flexWrap_; |
98 | 4.94M | } |
99 | 0 | void setFlexWrap(Wrap value) { |
100 | 0 | flexWrap_ = value; |
101 | 0 | } |
102 | | |
103 | 47.0M | Overflow overflow() const { |
104 | 47.0M | return overflow_; |
105 | 47.0M | } |
106 | 0 | void setOverflow(Overflow value) { |
107 | 0 | overflow_ = value; |
108 | 0 | } |
109 | | |
110 | 108M | Display display() const { |
111 | 108M | return display_; |
112 | 108M | } |
113 | 0 | void setDisplay(Display value) { |
114 | 0 | display_ = value; |
115 | 0 | } |
116 | | |
117 | 78.0M | FloatOptional flex() const { |
118 | 78.0M | return pool_.getNumber(flex_); |
119 | 78.0M | } |
120 | 0 | void setFlex(FloatOptional value) { |
121 | 0 | pool_.store(flex_, value); |
122 | 0 | } |
123 | | |
124 | 26.4M | FloatOptional flexGrow() const { |
125 | 26.4M | return pool_.getNumber(flexGrow_); |
126 | 26.4M | } |
127 | 0 | void setFlexGrow(FloatOptional value) { |
128 | 0 | pool_.store(flexGrow_, value); |
129 | 0 | } |
130 | | |
131 | 34.0M | FloatOptional flexShrink() const { |
132 | 34.0M | return pool_.getNumber(flexShrink_); |
133 | 34.0M | } |
134 | 0 | void setFlexShrink(FloatOptional value) { |
135 | 0 | pool_.store(flexShrink_, value); |
136 | 0 | } |
137 | | |
138 | 17.4M | Style::SizeLength flexBasis() const { |
139 | 17.4M | return pool_.getSize(flexBasis_); |
140 | 17.4M | } |
141 | 0 | void setFlexBasis(Style::SizeLength value) { |
142 | 0 | pool_.store(flexBasis_, value); |
143 | 0 | } |
144 | | |
145 | 0 | Style::Length margin(Edge edge) const { |
146 | 0 | return pool_.getLength(margin_[yoga::to_underlying(edge)]); |
147 | 0 | } |
148 | 0 | void setMargin(Edge edge, Style::Length value) { |
149 | 0 | pool_.store(margin_[yoga::to_underlying(edge)], value); |
150 | 0 | } |
151 | | |
152 | 0 | Style::Length position(Edge edge) const { |
153 | 0 | return pool_.getLength(position_[yoga::to_underlying(edge)]); |
154 | 0 | } |
155 | 0 | void setPosition(Edge edge, Style::Length value) { |
156 | 0 | pool_.store(position_[yoga::to_underlying(edge)], value); |
157 | 0 | } |
158 | | |
159 | 0 | Style::Length padding(Edge edge) const { |
160 | 0 | return pool_.getLength(padding_[yoga::to_underlying(edge)]); |
161 | 0 | } |
162 | 0 | void setPadding(Edge edge, Style::Length value) { |
163 | 0 | pool_.store(padding_[yoga::to_underlying(edge)], value); |
164 | 0 | } |
165 | | |
166 | 0 | Style::Length border(Edge edge) const { |
167 | 0 | return pool_.getLength(border_[yoga::to_underlying(edge)]); |
168 | 0 | } |
169 | 0 | void setBorder(Edge edge, Style::Length value) { |
170 | 0 | pool_.store(border_[yoga::to_underlying(edge)], value); |
171 | 0 | } |
172 | | |
173 | 3.82M | Style::Length gap(Gutter gutter) const { |
174 | 3.82M | return pool_.getLength(gap_[yoga::to_underlying(gutter)]); |
175 | 3.82M | } |
176 | 3.82M | void setGap(Gutter gutter, Style::Length value) { |
177 | 3.82M | pool_.store(gap_[yoga::to_underlying(gutter)], value); |
178 | 3.82M | } |
179 | | |
180 | 42.6M | Style::SizeLength dimension(Dimension axis) const { |
181 | 42.6M | return pool_.getSize(dimensions_[yoga::to_underlying(axis)]); |
182 | 42.6M | } |
183 | 7.64M | void setDimension(Dimension axis, Style::SizeLength value) { |
184 | 7.64M | pool_.store(dimensions_[yoga::to_underlying(axis)], value); |
185 | 7.64M | } |
186 | | |
187 | 101M | Style::SizeLength minDimension(Dimension axis) const { |
188 | 101M | return pool_.getSize(minDimensions_[yoga::to_underlying(axis)]); |
189 | 101M | } |
190 | 0 | void setMinDimension(Dimension axis, Style::SizeLength value) { |
191 | 0 | pool_.store(minDimensions_[yoga::to_underlying(axis)], value); |
192 | 0 | } |
193 | | |
194 | | FloatOptional resolvedMinDimension( |
195 | | Direction direction, |
196 | | Dimension axis, |
197 | | float referenceLength, |
198 | 101M | float ownerWidth) const { |
199 | 101M | FloatOptional value = minDimension(axis).resolve(referenceLength); |
200 | 101M | if (boxSizing() == BoxSizing::BorderBox) { |
201 | 101M | return value; |
202 | 101M | } |
203 | | |
204 | 0 | FloatOptional dimensionPaddingAndBorder = FloatOptional{ |
205 | 0 | computePaddingAndBorderForDimension(direction, axis, ownerWidth)}; |
206 | |
|
207 | 0 | return value + |
208 | 0 | (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder |
209 | 0 | : FloatOptional{0.0}); |
210 | 101M | } |
211 | | |
212 | 198M | Style::SizeLength maxDimension(Dimension axis) const { |
213 | 198M | return pool_.getSize(maxDimensions_[yoga::to_underlying(axis)]); |
214 | 198M | } |
215 | 0 | void setMaxDimension(Dimension axis, Style::SizeLength value) { |
216 | 0 | pool_.store(maxDimensions_[yoga::to_underlying(axis)], value); |
217 | 0 | } |
218 | | |
219 | | FloatOptional resolvedMaxDimension( |
220 | | Direction direction, |
221 | | Dimension axis, |
222 | | float referenceLength, |
223 | 163M | float ownerWidth) const { |
224 | 163M | FloatOptional value = maxDimension(axis).resolve(referenceLength); |
225 | 163M | if (boxSizing() == BoxSizing::BorderBox) { |
226 | 163M | return value; |
227 | 163M | } |
228 | | |
229 | 0 | FloatOptional dimensionPaddingAndBorder = FloatOptional{ |
230 | 0 | computePaddingAndBorderForDimension(direction, axis, ownerWidth)}; |
231 | |
|
232 | 0 | return value + |
233 | 0 | (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder |
234 | 0 | : FloatOptional{0.0}); |
235 | 163M | } |
236 | | |
237 | 35.5M | FloatOptional aspectRatio() const { |
238 | 35.5M | return pool_.getNumber(aspectRatio_); |
239 | 35.5M | } |
240 | 0 | void setAspectRatio(FloatOptional value) { |
241 | | // degenerate aspect ratios act as auto. |
242 | | // see https://drafts.csswg.org/css-sizing-4/#valdef-aspect-ratio-ratio |
243 | 0 | pool_.store( |
244 | 0 | aspectRatio_, |
245 | 0 | value == 0.0f || std::isinf(value.unwrap()) ? FloatOptional{} : value); |
246 | 0 | } |
247 | | |
248 | 288M | BoxSizing boxSizing() const { |
249 | 288M | return boxSizing_; |
250 | 288M | } |
251 | 0 | void setBoxSizing(BoxSizing value) { |
252 | 0 | boxSizing_ = value; |
253 | 0 | } |
254 | | |
255 | 0 | bool horizontalInsetsDefined() const { |
256 | 0 | return position_[yoga::to_underlying(Edge::Left)].isDefined() || |
257 | 0 | position_[yoga::to_underlying(Edge::Right)].isDefined() || |
258 | 0 | position_[yoga::to_underlying(Edge::All)].isDefined() || |
259 | 0 | position_[yoga::to_underlying(Edge::Horizontal)].isDefined() || |
260 | 0 | position_[yoga::to_underlying(Edge::Start)].isDefined() || |
261 | 0 | position_[yoga::to_underlying(Edge::End)].isDefined(); |
262 | 0 | } |
263 | | |
264 | 0 | bool verticalInsetsDefined() const { |
265 | 0 | return position_[yoga::to_underlying(Edge::Top)].isDefined() || |
266 | 0 | position_[yoga::to_underlying(Edge::Bottom)].isDefined() || |
267 | 0 | position_[yoga::to_underlying(Edge::All)].isDefined() || |
268 | 0 | position_[yoga::to_underlying(Edge::Vertical)].isDefined(); |
269 | 0 | } |
270 | | |
271 | | bool isFlexStartPositionDefined(FlexDirection axis, Direction direction) |
272 | 0 | const { |
273 | 0 | return computePosition(flexStartEdge(axis), direction).isDefined(); |
274 | 0 | } |
275 | | |
276 | 0 | bool isFlexStartPositionAuto(FlexDirection axis, Direction direction) const { |
277 | 0 | return computePosition(flexStartEdge(axis), direction).isAuto(); |
278 | 0 | } |
279 | | |
280 | | bool isInlineStartPositionDefined(FlexDirection axis, Direction direction) |
281 | 7.64M | const { |
282 | 7.64M | return computePosition(inlineStartEdge(axis, direction), direction) |
283 | 7.64M | .isDefined(); |
284 | 7.64M | } |
285 | | |
286 | | bool isInlineStartPositionAuto(FlexDirection axis, Direction direction) |
287 | 0 | const { |
288 | 0 | return computePosition(inlineStartEdge(axis, direction), direction) |
289 | 0 | .isAuto(); |
290 | 0 | } |
291 | | |
292 | 0 | bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const { |
293 | 0 | return computePosition(flexEndEdge(axis), direction).isDefined(); |
294 | 0 | } |
295 | | |
296 | 0 | bool isFlexEndPositionAuto(FlexDirection axis, Direction direction) const { |
297 | 0 | return computePosition(flexEndEdge(axis), direction).isAuto(); |
298 | 0 | } |
299 | | |
300 | | bool isInlineEndPositionDefined(FlexDirection axis, Direction direction) |
301 | 0 | const { |
302 | 0 | return computePosition(inlineEndEdge(axis, direction), direction) |
303 | 0 | .isDefined(); |
304 | 0 | } |
305 | | |
306 | 0 | bool isInlineEndPositionAuto(FlexDirection axis, Direction direction) const { |
307 | 0 | return computePosition(inlineEndEdge(axis, direction), direction).isAuto(); |
308 | 0 | } |
309 | | |
310 | | float computeFlexStartPosition( |
311 | | FlexDirection axis, |
312 | | Direction direction, |
313 | 0 | float axisSize) const { |
314 | 0 | return computePosition(flexStartEdge(axis), direction) |
315 | 0 | .resolve(axisSize) |
316 | 0 | .unwrapOrDefault(0.0f); |
317 | 0 | } |
318 | | |
319 | | float computeInlineStartPosition( |
320 | | FlexDirection axis, |
321 | | Direction direction, |
322 | 0 | float axisSize) const { |
323 | 0 | return computePosition(inlineStartEdge(axis, direction), direction) |
324 | 0 | .resolve(axisSize) |
325 | 0 | .unwrapOrDefault(0.0f); |
326 | 0 | } |
327 | | |
328 | | float computeFlexEndPosition( |
329 | | FlexDirection axis, |
330 | | Direction direction, |
331 | 0 | float axisSize) const { |
332 | 0 | return computePosition(flexEndEdge(axis), direction) |
333 | 0 | .resolve(axisSize) |
334 | 0 | .unwrapOrDefault(0.0f); |
335 | 0 | } |
336 | | |
337 | | float computeInlineEndPosition( |
338 | | FlexDirection axis, |
339 | | Direction direction, |
340 | 7.64M | float axisSize) const { |
341 | 7.64M | return computePosition(inlineEndEdge(axis, direction), direction) |
342 | 7.64M | .resolve(axisSize) |
343 | 7.64M | .unwrapOrDefault(0.0f); |
344 | 7.64M | } |
345 | | |
346 | | float computeFlexStartMargin( |
347 | | FlexDirection axis, |
348 | | Direction direction, |
349 | 0 | float widthSize) const { |
350 | 0 | return computeMargin(flexStartEdge(axis), direction) |
351 | 0 | .resolve(widthSize) |
352 | 0 | .unwrapOrDefault(0.0f); |
353 | 0 | } |
354 | | |
355 | | float computeInlineStartMargin( |
356 | | FlexDirection axis, |
357 | | Direction direction, |
358 | 242M | float widthSize) const { |
359 | 242M | return computeMargin(inlineStartEdge(axis, direction), direction) |
360 | 242M | .resolve(widthSize) |
361 | 242M | .unwrapOrDefault(0.0f); |
362 | 242M | } |
363 | | |
364 | | float computeFlexEndMargin( |
365 | | FlexDirection axis, |
366 | | Direction direction, |
367 | 0 | float widthSize) const { |
368 | 0 | return computeMargin(flexEndEdge(axis), direction) |
369 | 0 | .resolve(widthSize) |
370 | 0 | .unwrapOrDefault(0.0f); |
371 | 0 | } |
372 | | |
373 | | float computeInlineEndMargin( |
374 | | FlexDirection axis, |
375 | | Direction direction, |
376 | 242M | float widthSize) const { |
377 | 242M | return computeMargin(inlineEndEdge(axis, direction), direction) |
378 | 242M | .resolve(widthSize) |
379 | 242M | .unwrapOrDefault(0.0f); |
380 | 242M | } |
381 | | |
382 | 3.29M | float computeFlexStartBorder(FlexDirection axis, Direction direction) const { |
383 | 3.29M | return maxOrDefined( |
384 | 3.29M | computeBorder(flexStartEdge(axis), direction).resolve(0.0f).unwrap(), |
385 | 3.29M | 0.0f); |
386 | 3.29M | } |
387 | | |
388 | | float computeInlineStartBorder(FlexDirection axis, Direction direction) |
389 | 120M | const { |
390 | 120M | return maxOrDefined( |
391 | 120M | computeBorder(inlineStartEdge(axis, direction), direction) |
392 | 120M | .resolve(0.0f) |
393 | 120M | .unwrap(), |
394 | 120M | 0.0f); |
395 | 120M | } |
396 | | |
397 | 1.64M | float computeFlexEndBorder(FlexDirection axis, Direction direction) const { |
398 | 1.64M | return maxOrDefined( |
399 | 1.64M | computeBorder(flexEndEdge(axis), direction).resolve(0.0f).unwrap(), |
400 | 1.64M | 0.0f); |
401 | 1.64M | } |
402 | | |
403 | 120M | float computeInlineEndBorder(FlexDirection axis, Direction direction) const { |
404 | 120M | return maxOrDefined( |
405 | 120M | computeBorder(inlineEndEdge(axis, direction), direction) |
406 | 120M | .resolve(0.0f) |
407 | 120M | .unwrap(), |
408 | 120M | 0.0f); |
409 | 120M | } |
410 | | |
411 | | float computeFlexStartPadding( |
412 | | FlexDirection axis, |
413 | | Direction direction, |
414 | 3.29M | float widthSize) const { |
415 | 3.29M | return maxOrDefined( |
416 | 3.29M | computePadding(flexStartEdge(axis), direction) |
417 | 3.29M | .resolve(widthSize) |
418 | 3.29M | .unwrap(), |
419 | 3.29M | 0.0f); |
420 | 3.29M | } |
421 | | |
422 | | float computeInlineStartPadding( |
423 | | FlexDirection axis, |
424 | | Direction direction, |
425 | 120M | float widthSize) const { |
426 | 120M | return maxOrDefined( |
427 | 120M | computePadding(inlineStartEdge(axis, direction), direction) |
428 | 120M | .resolve(widthSize) |
429 | 120M | .unwrap(), |
430 | 120M | 0.0f); |
431 | 120M | } |
432 | | |
433 | | float computeFlexEndPadding( |
434 | | FlexDirection axis, |
435 | | Direction direction, |
436 | 1.64M | float widthSize) const { |
437 | 1.64M | return maxOrDefined( |
438 | 1.64M | computePadding(flexEndEdge(axis), direction) |
439 | 1.64M | .resolve(widthSize) |
440 | 1.64M | .unwrap(), |
441 | 1.64M | 0.0f); |
442 | 1.64M | } |
443 | | |
444 | | float computeInlineEndPadding( |
445 | | FlexDirection axis, |
446 | | Direction direction, |
447 | 120M | float widthSize) const { |
448 | 120M | return maxOrDefined( |
449 | 120M | computePadding(inlineEndEdge(axis, direction), direction) |
450 | 120M | .resolve(widthSize) |
451 | 120M | .unwrap(), |
452 | 120M | 0.0f); |
453 | 120M | } |
454 | | |
455 | | float computeInlineStartPaddingAndBorder( |
456 | | FlexDirection axis, |
457 | | Direction direction, |
458 | 72.7M | float widthSize) const { |
459 | 72.7M | return computeInlineStartPadding(axis, direction, widthSize) + |
460 | 72.7M | computeInlineStartBorder(axis, direction); |
461 | 72.7M | } |
462 | | |
463 | | float computeFlexStartPaddingAndBorder( |
464 | | FlexDirection axis, |
465 | | Direction direction, |
466 | 3.29M | float widthSize) const { |
467 | 3.29M | return computeFlexStartPadding(axis, direction, widthSize) + |
468 | 3.29M | computeFlexStartBorder(axis, direction); |
469 | 3.29M | } |
470 | | |
471 | | float computeInlineEndPaddingAndBorder( |
472 | | FlexDirection axis, |
473 | | Direction direction, |
474 | 72.7M | float widthSize) const { |
475 | 72.7M | return computeInlineEndPadding(axis, direction, widthSize) + |
476 | 72.7M | computeInlineEndBorder(axis, direction); |
477 | 72.7M | } |
478 | | |
479 | | float computeFlexEndPaddingAndBorder( |
480 | | FlexDirection axis, |
481 | | Direction direction, |
482 | 1.64M | float widthSize) const { |
483 | 1.64M | return computeFlexEndPadding(axis, direction, widthSize) + |
484 | 1.64M | computeFlexEndBorder(axis, direction); |
485 | 1.64M | } |
486 | | |
487 | | float computePaddingAndBorderForDimension( |
488 | | Direction direction, |
489 | | Dimension dimension, |
490 | 0 | float widthSize) const { |
491 | 0 | FlexDirection flexDirectionForDimension = dimension == Dimension::Width |
492 | 0 | ? FlexDirection::Row |
493 | 0 | : FlexDirection::Column; |
494 | |
|
495 | 0 | return computeFlexStartPaddingAndBorder( |
496 | 0 | flexDirectionForDimension, direction, widthSize) + |
497 | 0 | computeFlexEndPaddingAndBorder( |
498 | 0 | flexDirectionForDimension, direction, widthSize); |
499 | 0 | } |
500 | | |
501 | 0 | float computeBorderForAxis(FlexDirection axis) const { |
502 | 0 | return computeInlineStartBorder(axis, Direction::LTR) + |
503 | 0 | computeInlineEndBorder(axis, Direction::LTR); |
504 | 0 | } |
505 | | |
506 | 187M | float computeMarginForAxis(FlexDirection axis, float widthSize) const { |
507 | | // The total margin for a given axis does not depend on the direction |
508 | | // so hardcoding LTR here to avoid piping direction to this function |
509 | 187M | return computeInlineStartMargin(axis, Direction::LTR, widthSize) + |
510 | 187M | computeInlineEndMargin(axis, Direction::LTR, widthSize); |
511 | 187M | } |
512 | | |
513 | 6.44M | float computeGapForAxis(FlexDirection axis, float ownerSize) const { |
514 | 6.44M | auto gap = isRow(axis) ? computeColumnGap() : computeRowGap(); |
515 | 6.44M | return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f); |
516 | 6.44M | } |
517 | | |
518 | 52.7M | bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const { |
519 | 52.7M | return computeMargin(flexStartEdge(axis), direction).isAuto(); |
520 | 52.7M | } |
521 | | |
522 | 52.7M | bool flexEndMarginIsAuto(FlexDirection axis, Direction direction) const { |
523 | 52.7M | return computeMargin(flexEndEdge(axis), direction).isAuto(); |
524 | 52.7M | } |
525 | | |
526 | 0 | bool operator==(const Style& other) const { |
527 | 0 | return direction_ == other.direction_ && |
528 | 0 | flexDirection_ == other.flexDirection_ && |
529 | 0 | justifyContent_ == other.justifyContent_ && |
530 | 0 | alignContent_ == other.alignContent_ && |
531 | 0 | alignItems_ == other.alignItems_ && alignSelf_ == other.alignSelf_ && |
532 | 0 | positionType_ == other.positionType_ && flexWrap_ == other.flexWrap_ && |
533 | 0 | overflow_ == other.overflow_ && display_ == other.display_ && |
534 | 0 | numbersEqual(flex_, pool_, other.flex_, other.pool_) && |
535 | 0 | numbersEqual(flexGrow_, pool_, other.flexGrow_, other.pool_) && |
536 | 0 | numbersEqual(flexShrink_, pool_, other.flexShrink_, other.pool_) && |
537 | 0 | lengthsEqual(flexBasis_, pool_, other.flexBasis_, other.pool_) && |
538 | 0 | lengthsEqual(margin_, pool_, other.margin_, other.pool_) && |
539 | 0 | lengthsEqual(position_, pool_, other.position_, other.pool_) && |
540 | 0 | lengthsEqual(padding_, pool_, other.padding_, other.pool_) && |
541 | 0 | lengthsEqual(border_, pool_, other.border_, other.pool_) && |
542 | 0 | lengthsEqual(gap_, pool_, other.gap_, other.pool_) && |
543 | 0 | lengthsEqual(dimensions_, pool_, other.dimensions_, other.pool_) && |
544 | 0 | lengthsEqual( |
545 | 0 | minDimensions_, pool_, other.minDimensions_, other.pool_) && |
546 | 0 | lengthsEqual( |
547 | 0 | maxDimensions_, pool_, other.maxDimensions_, other.pool_) && |
548 | 0 | numbersEqual(aspectRatio_, pool_, other.aspectRatio_, other.pool_); |
549 | 0 | } |
550 | | |
551 | 0 | bool operator!=(const Style& other) const { |
552 | 0 | return !(*this == other); |
553 | 0 | } |
554 | | |
555 | | private: |
556 | | using Dimensions = std::array<StyleValueHandle, ordinalCount<Dimension>()>; |
557 | | using Edges = std::array<StyleValueHandle, ordinalCount<Edge>()>; |
558 | | using Gutters = std::array<StyleValueHandle, ordinalCount<Gutter>()>; |
559 | | |
560 | | static inline bool numbersEqual( |
561 | | const StyleValueHandle& lhsHandle, |
562 | | const StyleValuePool& lhsPool, |
563 | | const StyleValueHandle& rhsHandle, |
564 | 0 | const StyleValuePool& rhsPool) { |
565 | 0 | return (lhsHandle.isUndefined() && rhsHandle.isUndefined()) || |
566 | 0 | (lhsPool.getNumber(lhsHandle) == rhsPool.getNumber(rhsHandle)); |
567 | 0 | } |
568 | | |
569 | | static inline bool lengthsEqual( |
570 | | const StyleValueHandle& lhsHandle, |
571 | | const StyleValuePool& lhsPool, |
572 | | const StyleValueHandle& rhsHandle, |
573 | 0 | const StyleValuePool& rhsPool) { |
574 | 0 | return (lhsHandle.isUndefined() && rhsHandle.isUndefined()) || |
575 | 0 | (lhsPool.getLength(lhsHandle) == rhsPool.getLength(rhsHandle)); |
576 | 0 | } |
577 | | |
578 | | template <size_t N> |
579 | | static inline bool lengthsEqual( |
580 | | const std::array<StyleValueHandle, N>& lhs, |
581 | | const StyleValuePool& lhsPool, |
582 | | const std::array<StyleValueHandle, N>& rhs, |
583 | 0 | const StyleValuePool& rhsPool) { |
584 | 0 | return std::equal( |
585 | 0 | lhs.begin(), |
586 | 0 | lhs.end(), |
587 | 0 | rhs.begin(), |
588 | 0 | rhs.end(), |
589 | 0 | [&](const auto& lhs, const auto& rhs) { |
590 | 0 | return lengthsEqual(lhs, lhsPool, rhs, rhsPool); |
591 | 0 | }); Unexecuted instantiation: auto facebook::yoga::Style::lengthsEqual<9ul>(std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<facebook::yoga::StyleValueHandle, facebook::yoga::StyleValueHandle>(facebook::yoga::StyleValueHandle const&, facebook::yoga::StyleValueHandle const&) const Unexecuted instantiation: auto facebook::yoga::Style::lengthsEqual<3ul>(std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<facebook::yoga::StyleValueHandle, facebook::yoga::StyleValueHandle>(facebook::yoga::StyleValueHandle const&, facebook::yoga::StyleValueHandle const&) const Unexecuted instantiation: auto facebook::yoga::Style::lengthsEqual<2ul>(std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<facebook::yoga::StyleValueHandle, facebook::yoga::StyleValueHandle>(facebook::yoga::StyleValueHandle const&, facebook::yoga::StyleValueHandle const&) const |
592 | 0 | } Unexecuted instantiation: bool facebook::yoga::Style::lengthsEqual<9ul>(std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&) Unexecuted instantiation: bool facebook::yoga::Style::lengthsEqual<3ul>(std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&) Unexecuted instantiation: bool facebook::yoga::Style::lengthsEqual<2ul>(std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&) |
593 | | |
594 | 3.72M | Style::Length computeColumnGap() const { |
595 | 3.72M | if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { |
596 | 0 | return pool_.getLength(gap_[yoga::to_underlying(Gutter::Column)]); |
597 | 3.72M | } else { |
598 | 3.72M | return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]); |
599 | 3.72M | } |
600 | 3.72M | } |
601 | | |
602 | 2.72M | Style::Length computeRowGap() const { |
603 | 2.72M | if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { |
604 | 0 | return pool_.getLength(gap_[yoga::to_underlying(Gutter::Row)]); |
605 | 2.72M | } else { |
606 | 2.72M | return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]); |
607 | 2.72M | } |
608 | 2.72M | } |
609 | | |
610 | | Style::Length computeLeftEdge(const Edges& edges, Direction layoutDirection) |
611 | 289M | const { |
612 | 289M | if (layoutDirection == Direction::LTR && |
613 | 289M | edges[yoga::to_underlying(Edge::Start)].isDefined()) { |
614 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]); |
615 | 289M | } else if ( |
616 | 289M | layoutDirection == Direction::RTL && |
617 | 0 | edges[yoga::to_underlying(Edge::End)].isDefined()) { |
618 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::End)]); |
619 | 289M | } else if (edges[yoga::to_underlying(Edge::Left)].isDefined()) { |
620 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Left)]); |
621 | 289M | } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { |
622 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]); |
623 | 289M | } else { |
624 | 289M | return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); |
625 | 289M | } |
626 | 289M | } |
627 | | |
628 | 260M | Style::Length computeTopEdge(const Edges& edges) const { |
629 | 260M | if (edges[yoga::to_underlying(Edge::Top)].isDefined()) { |
630 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Top)]); |
631 | 260M | } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { |
632 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]); |
633 | 260M | } else { |
634 | 260M | return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); |
635 | 260M | } |
636 | 260M | } |
637 | | |
638 | | Style::Length computeRightEdge(const Edges& edges, Direction layoutDirection) |
639 | 288M | const { |
640 | 288M | if (layoutDirection == Direction::LTR && |
641 | 288M | edges[yoga::to_underlying(Edge::End)].isDefined()) { |
642 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::End)]); |
643 | 288M | } else if ( |
644 | 288M | layoutDirection == Direction::RTL && |
645 | 0 | edges[yoga::to_underlying(Edge::Start)].isDefined()) { |
646 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]); |
647 | 288M | } else if (edges[yoga::to_underlying(Edge::Right)].isDefined()) { |
648 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Right)]); |
649 | 288M | } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { |
650 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]); |
651 | 288M | } else { |
652 | 288M | return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); |
653 | 288M | } |
654 | 288M | } |
655 | | |
656 | 258M | Style::Length computeBottomEdge(const Edges& edges) const { |
657 | 258M | if (edges[yoga::to_underlying(Edge::Bottom)].isDefined()) { |
658 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Bottom)]); |
659 | 258M | } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { |
660 | 0 | return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]); |
661 | 258M | } else { |
662 | 258M | return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); |
663 | 258M | } |
664 | 258M | } |
665 | | |
666 | 15.2M | Style::Length computePosition(PhysicalEdge edge, Direction direction) const { |
667 | 15.2M | switch (edge) { |
668 | 3.82M | case PhysicalEdge::Left: |
669 | 3.82M | return computeLeftEdge(position_, direction); |
670 | 3.82M | case PhysicalEdge::Top: |
671 | 3.82M | return computeTopEdge(position_); |
672 | 3.82M | case PhysicalEdge::Right: |
673 | 3.82M | return computeRightEdge(position_, direction); |
674 | 3.82M | case PhysicalEdge::Bottom: |
675 | 3.82M | return computeBottomEdge(position_); |
676 | 15.2M | } |
677 | | |
678 | 0 | fatalWithMessage("Invalid physical edge"); |
679 | 0 | } |
680 | | |
681 | 590M | Style::Length computeMargin(PhysicalEdge edge, Direction direction) const { |
682 | 590M | switch (edge) { |
683 | 157M | case PhysicalEdge::Left: |
684 | 157M | return computeLeftEdge(margin_, direction); |
685 | 138M | case PhysicalEdge::Top: |
686 | 138M | return computeTopEdge(margin_); |
687 | 157M | case PhysicalEdge::Right: |
688 | 157M | return computeRightEdge(margin_, direction); |
689 | 138M | case PhysicalEdge::Bottom: |
690 | 138M | return computeBottomEdge(margin_); |
691 | 590M | } |
692 | | |
693 | 0 | fatalWithMessage("Invalid physical edge"); |
694 | 0 | } |
695 | | |
696 | 245M | Style::Length computePadding(PhysicalEdge edge, Direction direction) const { |
697 | 245M | switch (edge) { |
698 | 64.0M | case PhysicalEdge::Left: |
699 | 64.0M | return computeLeftEdge(padding_, direction); |
700 | 59.4M | case PhysicalEdge::Top: |
701 | 59.4M | return computeTopEdge(padding_); |
702 | 63.5M | case PhysicalEdge::Right: |
703 | 63.5M | return computeRightEdge(padding_, direction); |
704 | 58.3M | case PhysicalEdge::Bottom: |
705 | 58.3M | return computeBottomEdge(padding_); |
706 | 245M | } |
707 | | |
708 | 0 | fatalWithMessage("Invalid physical edge"); |
709 | 0 | } |
710 | | |
711 | 245M | Style::Length computeBorder(PhysicalEdge edge, Direction direction) const { |
712 | 245M | switch (edge) { |
713 | 64.0M | case PhysicalEdge::Left: |
714 | 64.0M | return computeLeftEdge(border_, direction); |
715 | 59.4M | case PhysicalEdge::Top: |
716 | 59.4M | return computeTopEdge(border_); |
717 | 63.5M | case PhysicalEdge::Right: |
718 | 63.5M | return computeRightEdge(border_, direction); |
719 | 58.3M | case PhysicalEdge::Bottom: |
720 | 58.3M | return computeBottomEdge(border_); |
721 | 245M | } |
722 | | |
723 | 0 | fatalWithMessage("Invalid physical edge"); |
724 | 0 | } |
725 | | |
726 | | Direction direction_ : bitCount<Direction>() = Direction::Inherit; |
727 | | FlexDirection flexDirection_ |
728 | | : bitCount<FlexDirection>() = FlexDirection::Column; |
729 | | Justify justifyContent_ : bitCount<Justify>() = Justify::FlexStart; |
730 | | Align alignContent_ : bitCount<Align>() = Align::FlexStart; |
731 | | Align alignItems_ : bitCount<Align>() = Align::Stretch; |
732 | | Align alignSelf_ : bitCount<Align>() = Align::Auto; |
733 | | PositionType positionType_ |
734 | | : bitCount<PositionType>() = PositionType::Relative; |
735 | | Wrap flexWrap_ : bitCount<Wrap>() = Wrap::NoWrap; |
736 | | Overflow overflow_ : bitCount<Overflow>() = Overflow::Visible; |
737 | | Display display_ : bitCount<Display>() = Display::Flex; |
738 | | BoxSizing boxSizing_ : bitCount<BoxSizing>() = BoxSizing::BorderBox; |
739 | | |
740 | | StyleValueHandle flex_{}; |
741 | | StyleValueHandle flexGrow_{}; |
742 | | StyleValueHandle flexShrink_{}; |
743 | | StyleValueHandle flexBasis_{StyleValueHandle::ofAuto()}; |
744 | | Edges margin_{}; |
745 | | Edges position_{}; |
746 | | Edges padding_{}; |
747 | | Edges border_{}; |
748 | | Gutters gap_{}; |
749 | | Dimensions dimensions_{ |
750 | | StyleValueHandle::ofAuto(), |
751 | | StyleValueHandle::ofAuto()}; |
752 | | Dimensions minDimensions_{}; |
753 | | Dimensions maxDimensions_{}; |
754 | | StyleValueHandle aspectRatio_{}; |
755 | | |
756 | | StyleValuePool pool_; |
757 | | }; |
758 | | |
759 | | } // namespace facebook::yoga |