Reviewed By: majak

Differential Revision: D3579423

fbshipit-source-id: 040ecab2f20216aa136ccb8a9e7e15ffa882b313
This commit is contained in:
Emil Sjolander 2016-07-20 08:46:00 -07:00 коммит произвёл Facebook Github Bot 6
Родитель 12ec213c0d
Коммит 1af9270e45
9 изменённых файлов: 510 добавлений и 288 удалений

Просмотреть файл

@ -28,10 +28,10 @@
{ {
[super setUp]; [super setUp];
self.parentView = [self _shadowViewWithStyle:^(CSSStyle *style) { self.parentView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flexDirection = CSSFlexDirectionColumn; CSSNodeStyleSetFlexDirection(node, CSSFlexDirectionColumn);
style->dimensions[0] = 440; CSSNodeStyleSetWidth(node, 440);
style->dimensions[1] = 440; CSSNodeStyleSetHeight(node, 440);
}]; }];
self.parentView.reactTag = @1; // must be valid rootView tag self.parentView.reactTag = @1; // must be valid rootView tag
} }
@ -50,43 +50,43 @@
// //
- (void)testApplyingLayoutRecursivelyToShadowView - (void)testApplyingLayoutRecursivelyToShadowView
{ {
RCTShadowView *leftView = [self _shadowViewWithStyle:^(CSSStyle *style) { RCTShadowView *leftView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flex = 1; CSSNodeStyleSetFlex(node, 1);
}]; }];
RCTShadowView *centerView = [self _shadowViewWithStyle:^(CSSStyle *style) { RCTShadowView *centerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flex = 2; CSSNodeStyleSetFlex(node, 2);
style->margin[0] = 10; CSSNodeStyleSetMarginLeft(node, 10);
style->margin[2] = 10; CSSNodeStyleSetMarginRight(node, 10);
}]; }];
RCTShadowView *rightView = [self _shadowViewWithStyle:^(CSSStyle *style) { RCTShadowView *rightView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flex = 1; CSSNodeStyleSetFlex(node, 1);
}]; }];
RCTShadowView *mainView = [self _shadowViewWithStyle:^(CSSStyle *style) { RCTShadowView *mainView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flexDirection = CSSFlexDirectionRow; CSSNodeStyleSetFlexDirection(node, CSSFlexDirectionRow);
style->flex = 2; CSSNodeStyleSetFlex(node, 2);
style->margin[1] = 10; CSSNodeStyleSetMarginTop(node, 10);
style->margin[3] = 10; CSSNodeStyleSetMarginBottom(node, 10);
}]; }];
[mainView insertReactSubview:leftView atIndex:0]; [mainView insertReactSubview:leftView atIndex:0];
[mainView insertReactSubview:centerView atIndex:1]; [mainView insertReactSubview:centerView atIndex:1];
[mainView insertReactSubview:rightView atIndex:2]; [mainView insertReactSubview:rightView atIndex:2];
RCTShadowView *headerView = [self _shadowViewWithStyle:^(CSSStyle *style) { RCTShadowView *headerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flex = 1; CSSNodeStyleSetFlex(node, 1);
}]; }];
RCTShadowView *footerView = [self _shadowViewWithStyle:^(CSSStyle *style) { RCTShadowView *footerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
style->flex = 1; CSSNodeStyleSetFlex(node, 1);
}]; }];
self.parentView.cssNode->style.padding[0] = 10; CSSNodeStyleSetPaddingLeft(self.parentView.cssNode, 10);
self.parentView.cssNode->style.padding[1] = 10; CSSNodeStyleSetPaddingTop(self.parentView.cssNode, 10);
self.parentView.cssNode->style.padding[2] = 10; CSSNodeStyleSetPaddingRight(self.parentView.cssNode, 10);
self.parentView.cssNode->style.padding[3] = 10; CSSNodeStyleSetPaddingBottom(self.parentView.cssNode, 10);
[self.parentView insertReactSubview:headerView atIndex:0]; [self.parentView insertReactSubview:headerView atIndex:0];
[self.parentView insertReactSubview:mainView atIndex:1]; [self.parentView insertReactSubview:mainView atIndex:1];
@ -108,10 +108,10 @@
- (void)testAssignsSuggestedWidthDimension - (void)testAssignsSuggestedWidthDimension
{ {
[self _withShadowViewWithStyle:^(CSSStyle *style) { [self _withShadowViewWithStyle:^(CSSNodeRef node) {
style->position[CSSPositionLeft] = 0; CSSNodeStyleSetPositionLeft(node, 0);
style->position[CSSPositionTop] = 0; CSSNodeStyleSetPositionTop(node, 0);
style->dimensions[CSSDimensionHeight] = 10; CSSNodeStyleSetHeight(node, 10);
} }
assertRelativeLayout:CGRectMake(0, 0, 3, 10) assertRelativeLayout:CGRectMake(0, 0, 3, 10)
withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)]; withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)];
@ -119,10 +119,10 @@
- (void)testAssignsSuggestedHeightDimension - (void)testAssignsSuggestedHeightDimension
{ {
[self _withShadowViewWithStyle:^(CSSStyle *style) { [self _withShadowViewWithStyle:^(CSSNodeRef node) {
style->position[CSSPositionLeft] = 0; CSSNodeStyleSetPositionLeft(node, 0);
style->position[CSSPositionTop] = 0; CSSNodeStyleSetPositionTop(node, 0);
style->dimensions[CSSDimensionWidth] = 10; CSSNodeStyleSetWidth(node, 10);
} }
assertRelativeLayout:CGRectMake(0, 0, 10, 4) assertRelativeLayout:CGRectMake(0, 0, 10, 4)
withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)]; withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)];
@ -130,11 +130,11 @@
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions - (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
{ {
[self _withShadowViewWithStyle:^(CSSStyle *style) { [self _withShadowViewWithStyle:^(CSSNodeRef node) {
style->position[CSSPositionLeft] = 0; CSSNodeStyleSetPositionLeft(node, 0);
style->position[CSSPositionTop] = 0; CSSNodeStyleSetPositionTop(node, 0);
style->dimensions[CSSDimensionWidth] = 10; CSSNodeStyleSetWidth(node, 10);
style->dimensions[CSSDimensionHeight] = 10; CSSNodeStyleSetHeight(node, 10);
} }
assertRelativeLayout:CGRectMake(0, 0, 10, 10) assertRelativeLayout:CGRectMake(0, 0, 10, 10)
withIntrinsicContentSize:CGSizeMake(3, 4)]; withIntrinsicContentSize:CGSizeMake(3, 4)];
@ -142,20 +142,20 @@
- (void)testDoesNotAssignSuggestedDimensionsWhenStyledWithFlexAttribute - (void)testDoesNotAssignSuggestedDimensionsWhenStyledWithFlexAttribute
{ {
float parentWidth = self.parentView.cssNode->style.dimensions[CSSDimensionWidth]; float parentWidth = CSSNodeStyleGetWidth(self.parentView.cssNode);
float parentHeight = self.parentView.cssNode->style.dimensions[CSSDimensionHeight]; float parentHeight = CSSNodeStyleGetHeight(self.parentView.cssNode);
[self _withShadowViewWithStyle:^(CSSStyle *style) { [self _withShadowViewWithStyle:^(CSSNodeRef node) {
style->flex = 1; CSSNodeStyleSetFlex(node, 1);
} }
assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight) assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight)
withIntrinsicContentSize:CGSizeMake(3, 4)]; withIntrinsicContentSize:CGSizeMake(3, 4)];
} }
- (void)_withShadowViewWithStyle:(void(^)(CSSStyle *style))styleBlock - (void)_withShadowViewWithStyle:(void(^)(CSSNodeRef node))configBlock
assertRelativeLayout:(CGRect)expectedRect assertRelativeLayout:(CGRect)expectedRect
withIntrinsicContentSize:(CGSize)contentSize withIntrinsicContentSize:(CGSize)contentSize
{ {
RCTShadowView *view = [self _shadowViewWithStyle:styleBlock]; RCTShadowView *view = [self _shadowViewWithConfig:configBlock];
[self.parentView insertReactSubview:view atIndex:0]; [self.parentView insertReactSubview:view atIndex:0];
view.intrinsicContentSize = contentSize; view.intrinsicContentSize = contentSize;
[self.parentView collectViewsWithUpdatedFrames]; [self.parentView collectViewsWithUpdatedFrames];
@ -166,14 +166,10 @@
NSStringFromCGRect(actualRect)); NSStringFromCGRect(actualRect));
} }
- (RCTRootShadowView *)_shadowViewWithStyle:(void(^)(CSSStyle *style))styleBlock - (RCTRootShadowView *)_shadowViewWithConfig:(void(^)(CSSNodeRef node))configBlock
{ {
RCTRootShadowView *shadowView = [RCTRootShadowView new]; RCTRootShadowView *shadowView = [RCTRootShadowView new];
configBlock(shadowView.cssNode);
CSSStyle style = shadowView.cssNode->style;
styleBlock(&style);
shadowView.cssNode->style = style;
return shadowView; return shadowView;
} }

Просмотреть файл

@ -33,7 +33,7 @@ NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName";
CGFloat _effectiveLetterSpacing; CGFloat _effectiveLetterSpacing;
} }
static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) static CSSSize RCTMeasure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
{ {
RCTShadowText *shadowText = (__bridge RCTShadowText *)context; RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode]; NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode];
@ -41,12 +41,12 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
NSTextContainer *textContainer = layoutManager.textContainers.firstObject; NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size; CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
CSSMeasureResult result; CSSSize result;
result.dimensions[CSSDimensionWidth] = RCTCeilPixelValue(computedSize.width); result.width = RCTCeilPixelValue(computedSize.width);
if (shadowText->_effectiveLetterSpacing < 0) { if (shadowText->_effectiveLetterSpacing < 0) {
result.dimensions[CSSDimensionWidth] -= shadowText->_effectiveLetterSpacing; result.width -= shadowText->_effectiveLetterSpacing;
} }
result.dimensions[CSSDimensionHeight] = RCTCeilPixelValue(computedSize.height); result.height = RCTCeilPixelValue(computedSize.height);
return result; return result;
} }
@ -61,7 +61,7 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
_cachedTextStorageWidth = -1; _cachedTextStorageWidth = -1;
_cachedTextStorageWidthMode = -1; _cachedTextStorageWidthMode = -1;
_fontSizeMultiplier = 1.0; _fontSizeMultiplier = 1.0;
self.cssNode->measure = RCTMeasure; CSSNodeSetMeasureFunc(self.cssNode, RCTMeasure);
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentSizeMultiplierDidChange:) selector:@selector(contentSizeMultiplierDidChange:)
name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification
@ -128,7 +128,7 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
return parentProperties; return parentProperties;
} }
- (void)applyLayoutNode:(CSSNode *)node - (void)applyLayoutNode:(CSSNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition absolutePosition:(CGPoint)absolutePosition
{ {
@ -136,7 +136,7 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
[self dirtyPropagation]; [self dirtyPropagation];
} }
- (void)applyLayoutToChildren:(CSSNode *)node - (void)applyLayoutToChildren:(CSSNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition absolutePosition:(CGPoint)absolutePosition
{ {
@ -148,9 +148,9 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL]; NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
[layoutManager.textStorage enumerateAttribute:RCTShadowViewAttributeName inRange:characterRange options:0 usingBlock:^(RCTShadowView *child, NSRange range, BOOL *_) { [layoutManager.textStorage enumerateAttribute:RCTShadowViewAttributeName inRange:characterRange options:0 usingBlock:^(RCTShadowView *child, NSRange range, BOOL *_) {
if (child) { if (child) {
CSSNode *childNode = child.cssNode; CSSNodeRef childNode = child.cssNode;
float width = childNode->style.dimensions[CSSDimensionWidth]; float width = CSSNodeStyleGetWidth(childNode);
float height = childNode->style.dimensions[CSSDimensionHeight]; float height = CSSNodeStyleGetHeight(childNode);
if (isUndefined(width) || isUndefined(height)) { if (isUndefined(width) || isUndefined(height)) {
RCTLogError(@"Views nested within a <Text> must have a width and height"); RCTLogError(@"Views nested within a <Text> must have a width and height");
} }
@ -291,8 +291,8 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]]; [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
[child setTextComputed]; [child setTextComputed];
} else { } else {
float width = child.cssNode->style.dimensions[CSSDimensionWidth]; float width = CSSNodeStyleGetWidth(child.cssNode);
float height = child.cssNode->style.dimensions[CSSDimensionHeight]; float height = CSSNodeStyleGetHeight(child.cssNode);
if (isUndefined(width) || isUndefined(height)) { if (isUndefined(width) || isUndefined(height)) {
RCTLogError(@"Views nested within a <Text> must have a width and height"); RCTLogError(@"Views nested within a <Text> must have a width and height");
} }
@ -384,10 +384,10 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
// We will climb up to the first node which style has been setted as non-inherit // We will climb up to the first node which style has been setted as non-inherit
if (newTextAlign == NSTextAlignmentRight || newTextAlign == NSTextAlignmentLeft) { if (newTextAlign == NSTextAlignmentRight || newTextAlign == NSTextAlignmentLeft) {
RCTShadowView *view = self; RCTShadowView *view = self;
while (view != nil && view.cssNode->style.direction == CSSDirectionInherit) { while (view != nil && CSSNodeStyleGetDirection(view.cssNode) == CSSDirectionInherit) {
view = [view reactSuperview]; view = [view reactSuperview];
} }
if (view != nil && view.cssNode->style.direction == CSSDirectionRTL) { if (view != nil && CSSNodeStyleGetDirection(view.cssNode) == CSSDirectionRTL) {
if (newTextAlign == NSTextAlignmentRight) { if (newTextAlign == NSTextAlignmentRight) {
newTextAlign = NSTextAlignmentLeft; newTextAlign = NSTextAlignmentLeft;
} else if (newTextAlign == NSTextAlignmentLeft) { } else if (newTextAlign == NSTextAlignmentLeft) {

Просмотреть файл

@ -0,0 +1,104 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef __CSS_LAYOUT_INTERNAL_H
#define __CSS_LAYOUT_INTERNAL_H
#include <stdio.h>
#include <stdlib.h>
#include "CSSLayout.h"
CSS_EXTERN_C_BEGIN
typedef struct CSSCachedMeasurement {
float availableWidth;
float availableHeight;
CSSMeasureMode widthMeasureMode;
CSSMeasureMode heightMeasureMode;
float computedWidth;
float computedHeight;
} CSSCachedMeasurement;
// This value was chosen based on empiracle data. Even the most complicated
// layouts should not require more than 16 entries to fit within the cache.
enum {
CSS_MAX_CACHED_RESULT_COUNT = 16
};
typedef struct CSSLayout {
float position[4];
float dimensions[2];
CSSDirection direction;
float flexBasis;
// Instead of recomputing the entire layout every single time, we
// cache some information to break early when nothing changed
int generationCount;
CSSDirection lastParentDirection;
int nextCachedMeasurementsIndex;
CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT];
float measuredDimensions[2];
CSSCachedMeasurement cached_layout;
} CSSLayout;
typedef struct CSSStyle {
CSSDirection direction;
CSSFlexDirection flexDirection;
CSSJustify justifyContent;
CSSAlign alignContent;
CSSAlign alignItems;
CSSAlign alignSelf;
CSSPositionType positionType;
CSSWrapType flexWrap;
CSSOverflow overflow;
float flex;
float margin[6];
float position[4];
/**
* You should skip all the rules that contain negative values for the
* following attributes. For example:
* {padding: 10, paddingLeft: -5}
* should output:
* {left: 10 ...}
* the following two are incorrect:
* {left: -5 ...}
* {left: 0 ...}
*/
float padding[6];
float border[6];
float dimensions[2];
float minDimensions[2];
float maxDimensions[2];
} CSSStyle;
typedef struct CSSNode {
CSSStyle style;
CSSLayout layout;
int childCount;
int lineIndex;
bool shouldUpdate;
struct CSSNode* nextChild;
CSSSize (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
struct CSSNode* (*getChild)(void *context, int i);
bool (*isDirty)(void *context);
bool (*isTextNode)(void *context);
void (*print)(void *context);
void *context;
} CSSNode;
CSS_EXTERN_C_END
#endif

Просмотреть файл

@ -13,7 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "CSSLayout.h" #include "CSSLayout-internal.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#include <float.h> #include <float.h>
@ -29,23 +29,17 @@ __forceinline const float fmaxf(const float a, const float b) {
#define POSITIVE_FLEX_IS_AUTO 0 #define POSITIVE_FLEX_IS_AUTO 0
int gCurrentGenerationCount = 0; CSSNodeRef CSSNodeNew() {
CSSNode* node = (CSSNode*)calloc(1, sizeof(*node));
bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection, CSSNodeInit(node);
CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason); return node;
bool isUndefined(float value) {
return isnan(value);
} }
static bool eq(float a, float b) { void CSSNodeFree(CSSNodeRef node) {
if (isUndefined(a)) { free(node);
return isUndefined(b);
}
return fabs(a - b) < 0.0001;
} }
void CSSNodeInit(CSSNode* node) { void CSSNodeInit(CSSNodeRef node) {
node->style.alignItems = CSSAlignStretch; node->style.alignItems = CSSAlignStretch;
node->style.alignContent = CSSAlignFlexStart; node->style.alignContent = CSSAlignFlexStart;
@ -81,7 +75,7 @@ void CSSNodeInit(CSSNode* node) {
// Such that the comparison is always going to be false // Such that the comparison is always going to be false
node->layout.lastParentDirection = (CSSDirection)-1; node->layout.lastParentDirection = (CSSDirection)-1;
node->layout.shouldUpdate = true; node->shouldUpdate = true;
node->layout.nextCachedMeasurementsIndex = 0; node->layout.nextCachedMeasurementsIndex = 0;
node->layout.measuredDimensions[CSSDimensionWidth] = CSSUndefined; node->layout.measuredDimensions[CSSDimensionWidth] = CSSUndefined;
@ -90,14 +84,103 @@ void CSSNodeInit(CSSNode* node) {
node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode)-1; node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode)-1;
} }
CSSNode* CSSNodeNew() { #define CSS_NODE_PROPERTY_IMPL(type, name, paramName, instanceName) \
CSSNode* node = (CSSNode*)calloc(1, sizeof(*node)); void CSSNodeSet##name(CSSNodeRef node, type paramName) { \
CSSNodeInit(node); node->instanceName = paramName;\
return node; } \
\
type CSSNodeGet##name(CSSNodeRef node) { \
return node->instanceName;\
} \
#define CSS_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \
void CSSNodeStyleSet##name(CSSNodeRef node, type paramName) { \
node->style.instanceName = paramName;\
} \
\
type CSSNodeStyleGet##name(CSSNodeRef node) { \
return node->style.instanceName;\
} \
#define CSS_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \
type CSSNodeLayoutGet##name(CSSNodeRef node) { \
return node->layout.instanceName;\
} \
CSS_NODE_PROPERTY_IMPL(void*, Context, context, context);
CSS_NODE_PROPERTY_IMPL(int, ChildCount, childCount, childCount);
CSS_NODE_PROPERTY_IMPL(CSSMeasureFunc, MeasureFunc, measureFunc, measure);
CSS_NODE_PROPERTY_IMPL(CSSChildFunc, ChildFunc, childFunc, getChild);
CSS_NODE_PROPERTY_IMPL(CSSIsDirtyFunc, IsDirtyFunc, isDirtyFunc, isDirty);
CSS_NODE_PROPERTY_IMPL(CSSIsTextFunc, IsTextFunc, isTextFunc, isTextNode);
CSS_NODE_PROPERTY_IMPL(CSSPrintFunc, PrintFunc, printFunc, print);
CSS_NODE_PROPERTY_IMPL(bool, ShouldUpdate, shouldUpdate, shouldUpdate);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSDirection, Direction, direction, direction);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSFlexDirection, FlexDirection, flexDirection, flexDirection);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSJustify, JustifyContent, justifyContent, justifyContent);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignContent, alignContent, alignContent);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignItems, alignItems, alignItems);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignSelf, alignSelf, alignSelf);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSPositionType, PositionType, positionType, positionType);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSWrapType, FlexWrap, flexWrap, flexWrap);
CSS_NODE_STYLE_PROPERTY_IMPL(CSSOverflow, Overflow, overflow, overflow);
CSS_NODE_STYLE_PROPERTY_IMPL(float, Flex, flex, flex);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionLeft, positionLeft, position[CSSPositionLeft]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionTop, positionTop, position[CSSPositionTop]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionRight, positionRight, position[CSSPositionRight]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionBottom, positionBottom, position[CSSPositionBottom]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginLeft, marginLeft, margin[CSSPositionLeft]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginTop, marginTop, margin[CSSPositionTop]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginRight, marginRight, margin[CSSPositionRight]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginBottom, marginBottom, margin[CSSPositionBottom]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginStart, marginStart, margin[CSSPositionStart]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginEnd, marginEnd, margin[CSSPositionEnd]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingLeft, paddingLeft, padding[CSSPositionLeft]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingTop, paddingTop, padding[CSSPositionTop]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingRight, paddingRight, padding[CSSPositionRight]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingBottom, paddingBottom, padding[CSSPositionBottom]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingStart, paddingStart, padding[CSSPositionStart]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingEnd, paddingEnd, padding[CSSPositionEnd]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderLeft, borderLeft, border[CSSPositionLeft]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderTop, borderTop, border[CSSPositionTop]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderRight, borderRight, border[CSSPositionRight]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderBottom, borderBottom, border[CSSPositionBottom]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderStart, borderStart, border[CSSPositionStart]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderEnd, BorderEnd, border[CSSPositionEnd]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, Width, width, dimensions[CSSDimensionWidth]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, Height, height, dimensions[CSSDimensionHeight]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MinWidth, minWidth, minDimensions[CSSDimensionWidth]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MinHeight, minHeight, minDimensions[CSSDimensionHeight]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxWidth, maxWidth, maxDimensions[CSSDimensionWidth]);
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxHeight, maxHeight, maxDimensions[CSSDimensionHeight]);
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[CSSPositionLeft]);
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[CSSPositionTop]);
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSPositionRight]);
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Bottom, position[CSSPositionBottom]);
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Width, dimensions[CSSDimensionWidth]);
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[CSSDimensionHeight]);
int gCurrentGenerationCount = 0;
bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection,
CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason);
bool isUndefined(float value) {
return isnan(value);
} }
void CSSNodeFree(CSSNode* node) { static bool eq(float a, float b) {
free(node); if (isUndefined(a)) {
return isUndefined(b);
}
return fabs(a - b) < 0.0001;
} }
static void indent(int n) { static void indent(int n) {
@ -682,7 +765,7 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
} else { } else {
// Measure the text under the current constraints. // Measure the text under the current constraints.
CSSMeasureResult measureDim = node->measure( CSSSize measuredSize = node->measure(
node->context, node->context,
innerWidth, innerWidth,
@ -693,11 +776,11 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow,
(widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ? (widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ?
measureDim.dimensions[CSSDimensionWidth] + paddingAndBorderAxisRow : measuredSize.width + paddingAndBorderAxisRow :
availableWidth - marginAxisRow); availableWidth - marginAxisRow);
node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn,
(heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ? (heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ?
measureDim.dimensions[CSSDimensionHeight] + paddingAndBorderAxisColumn : measuredSize.height + paddingAndBorderAxisColumn :
availableHeight - marginAxisColumn); availableHeight - marginAxisColumn);
} }
@ -1764,7 +1847,7 @@ bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeig
if (performLayout) { if (performLayout) {
node->layout.dimensions[CSSDimensionWidth] = node->layout.measuredDimensions[CSSDimensionWidth]; node->layout.dimensions[CSSDimensionWidth] = node->layout.measuredDimensions[CSSDimensionWidth];
node->layout.dimensions[CSSDimensionHeight] = node->layout.measuredDimensions[CSSDimensionHeight]; node->layout.dimensions[CSSDimensionHeight] = node->layout.measuredDimensions[CSSDimensionHeight];
layout->shouldUpdate = true; node->shouldUpdate = true;
} }
gDepth--; gDepth--;
@ -1772,7 +1855,7 @@ bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeig
return (needToVisitNode || cachedResults == NULL); return (needToVisitNode || cachedResults == NULL);
} }
void layoutNode(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection) { void CSSNodeCalculateLayout(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection) {
// Increment the generation count. This will force the recursive routine to visit // Increment the generation count. This will force the recursive routine to visit
// all dirty nodes at least once. Subsequent visits will be skipped if the input // all dirty nodes at least once. Subsequent visits will be skipped if the input
// parameters don't change. // parameters don't change.

Просмотреть файл

@ -7,8 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
#ifndef __LAYOUT_H #ifndef __CSS_LAYOUT_H
#define __LAYOUT_H #define __CSS_LAYOUT_H
#include <math.h> #include <math.h>
#ifndef __cplusplus #ifndef __cplusplus
@ -97,110 +97,110 @@ typedef enum CSSDimension {
CSSDimensionHeight, CSSDimensionHeight,
} CSSDimension; } CSSDimension;
typedef struct CSSCachedMeasurement {
float availableWidth;
float availableHeight;
CSSMeasureMode widthMeasureMode;
CSSMeasureMode heightMeasureMode;
float computedWidth;
float computedHeight;
} CSSCachedMeasurement;
// This value was chosen based on empiracle data. Even the most complicated
// layouts should not require more than 16 entries to fit within the cache.
enum {
CSS_MAX_CACHED_RESULT_COUNT = 16
};
typedef struct CSSLayout {
float position[4];
float dimensions[2];
CSSDirection direction;
float flexBasis;
// Instead of recomputing the entire layout every single time, we
// cache some information to break early when nothing changed
bool shouldUpdate;
int generationCount;
CSSDirection lastParentDirection;
int nextCachedMeasurementsIndex;
CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT];
float measuredDimensions[2];
CSSCachedMeasurement cached_layout;
} CSSLayout;
typedef struct CSSMeasureResult {
float dimensions[2];
} CSSMeasureResult;
typedef struct CSSStyle {
CSSDirection direction;
CSSFlexDirection flexDirection;
CSSJustify justifyContent;
CSSAlign alignContent;
CSSAlign alignItems;
CSSAlign alignSelf;
CSSPositionType positionType;
CSSWrapType flexWrap;
CSSOverflow overflow;
float flex;
float margin[6];
float position[4];
/**
* You should skip all the rules that contain negative values for the
* following attributes. For example:
* {padding: 10, paddingLeft: -5}
* should output:
* {left: 10 ...}
* the following two are incorrect:
* {left: -5 ...}
* {left: 0 ...}
*/
float padding[6];
float border[6];
float dimensions[2];
float minDimensions[2];
float maxDimensions[2];
} CSSStyle;
typedef struct CSSNode {
CSSStyle style;
CSSLayout layout;
int childCount;
int lineIndex;
struct CSSNode* nextChild;
CSSMeasureResult (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
void (*print)(void *context);
struct CSSNode* (*getChild)(void *context, int i);
bool (*isDirty)(void *context);
bool (*isTextNode)(void *context);
void *context;
} CSSNode;
// Lifecycle of nodes and children
CSSNode *CSSNodeNew();
void CSSNodeInit(CSSNode *node);
void CSSNodeFree(CSSNode *node);
// Print utilities
typedef enum CSSPrintOptions { typedef enum CSSPrintOptions {
CSSPrintOptionsLayout = 1, CSSPrintOptionsLayout = 1,
CSSPrintOptionsStyle = 2, CSSPrintOptionsStyle = 2,
CSSPrintOptionsChildren = 4, CSSPrintOptionsChildren = 4,
} CSSPrintOptions; } CSSPrintOptions;
void CSSNodePrint(CSSNode *node, CSSPrintOptions options); typedef struct CSSSize {
float width;
float height;
} CSSSize;
typedef struct CSSNode * CSSNodeRef;
typedef CSSSize (*CSSMeasureFunc)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
typedef CSSNodeRef (*CSSChildFunc)(void *context, int i);
typedef bool (*CSSIsDirtyFunc)(void *context);
typedef bool (*CSSIsTextFunc)(void *context);
typedef void (*CSSPrintFunc)(void *context);
// CSSNode
CSSNodeRef CSSNodeNew();
void CSSNodeInit(CSSNodeRef node);
void CSSNodeFree(CSSNodeRef node);
void CSSNodeCalculateLayout(
CSSNodeRef node,
float availableWidth,
float availableHeight,
CSSDirection parentDirection);
void CSSNodePrint(CSSNodeRef node, CSSPrintOptions options);
// Function that computes the layout!
void layoutNode(CSSNode *node, float availableWidth, float availableHeight, CSSDirection parentDirection);
bool isUndefined(float value); bool isUndefined(float value);
#define CSS_NODE_PROPERTY(type, name, paramName) \
void CSSNodeSet##name(CSSNodeRef node, type paramName); \
type CSSNodeGet##name(CSSNodeRef node);
#define CSS_NODE_STYLE_PROPERTY(type, name, paramName) \
void CSSNodeStyleSet##name(CSSNodeRef node, type paramName); \
type CSSNodeStyleGet##name(CSSNodeRef node);
#define CSS_NODE_LAYOUT_PROPERTY(type, name) \
type CSSNodeLayoutGet##name(CSSNodeRef node);
CSS_NODE_PROPERTY(void*, Context, context);
CSS_NODE_PROPERTY(int, ChildCount, childCount);
CSS_NODE_PROPERTY(CSSMeasureFunc, MeasureFunc, measureFunc);
CSS_NODE_PROPERTY(CSSChildFunc, ChildFunc, childFunc);
CSS_NODE_PROPERTY(CSSIsDirtyFunc, IsDirtyFunc, isDirtyFunc);
CSS_NODE_PROPERTY(CSSIsTextFunc, IsTextFunc, isTextFunc);
CSS_NODE_PROPERTY(CSSPrintFunc, PrintFunc, printFunc);
CSS_NODE_PROPERTY(bool, ShouldUpdate, shouldUpdate);
CSS_NODE_STYLE_PROPERTY(CSSDirection, Direction, direction);
CSS_NODE_STYLE_PROPERTY(CSSFlexDirection, FlexDirection, flexDirection);
CSS_NODE_STYLE_PROPERTY(CSSJustify, JustifyContent, justifyContent);
CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignContent, alignContent);
CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignItems, alignItems);
CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignSelf, alignSelf);
CSS_NODE_STYLE_PROPERTY(CSSPositionType, PositionType, positionType);
CSS_NODE_STYLE_PROPERTY(CSSWrapType, FlexWrap, flexWrap);
CSS_NODE_STYLE_PROPERTY(CSSOverflow, Overflow, overflow);
CSS_NODE_STYLE_PROPERTY(float, Flex, flex);
CSS_NODE_STYLE_PROPERTY(float, PositionLeft, positionLeft);
CSS_NODE_STYLE_PROPERTY(float, PositionTop, positionTop);
CSS_NODE_STYLE_PROPERTY(float, PositionRight, positionRight);
CSS_NODE_STYLE_PROPERTY(float, PositionBottom, positionBottom);
CSS_NODE_STYLE_PROPERTY(float, MarginLeft, marginLeft);
CSS_NODE_STYLE_PROPERTY(float, MarginTop, marginTop);
CSS_NODE_STYLE_PROPERTY(float, MarginRight, marginRight);
CSS_NODE_STYLE_PROPERTY(float, MarginBottom, marginBottom);
CSS_NODE_STYLE_PROPERTY(float, MarginStart, marginStart);
CSS_NODE_STYLE_PROPERTY(float, MarginEnd, marginEnd);
CSS_NODE_STYLE_PROPERTY(float, PaddingLeft, paddingLeft);
CSS_NODE_STYLE_PROPERTY(float, PaddingTop, paddingTop);
CSS_NODE_STYLE_PROPERTY(float, PaddingRight, paddingRight);
CSS_NODE_STYLE_PROPERTY(float, PaddingBottom, paddingBottom);
CSS_NODE_STYLE_PROPERTY(float, PaddingStart, paddingStart);
CSS_NODE_STYLE_PROPERTY(float, PaddingEnd, paddingEnd);
CSS_NODE_STYLE_PROPERTY(float, BorderLeft, borderLeft);
CSS_NODE_STYLE_PROPERTY(float, BorderTop, borderTop);
CSS_NODE_STYLE_PROPERTY(float, BorderRight, borderRight);
CSS_NODE_STYLE_PROPERTY(float, BorderBottom, borderBottom);
CSS_NODE_STYLE_PROPERTY(float, BorderStart, borderStart);
CSS_NODE_STYLE_PROPERTY(float, BorderEnd, borderEnd);
CSS_NODE_STYLE_PROPERTY(float, Width, width);
CSS_NODE_STYLE_PROPERTY(float, Height, height);
CSS_NODE_STYLE_PROPERTY(float, MinWidth, minWidth);
CSS_NODE_STYLE_PROPERTY(float, MinHeight, minHeight);
CSS_NODE_STYLE_PROPERTY(float, MaxWidth, maxWidth);
CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
CSS_NODE_LAYOUT_PROPERTY(float, Left);
CSS_NODE_LAYOUT_PROPERTY(float, Top);
CSS_NODE_LAYOUT_PROPERTY(float, Right);
CSS_NODE_LAYOUT_PROPERTY(float, Bottom);
CSS_NODE_LAYOUT_PROPERTY(float, Width);
CSS_NODE_LAYOUT_PROPERTY(float, Height);
CSS_EXTERN_C_END CSS_EXTERN_C_END
#endif #endif

Просмотреть файл

@ -121,6 +121,7 @@
000E6CEA1AB0E980000CDF4D /* RCTSourceCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSourceCode.m; sourceTree = "<group>"; }; 000E6CEA1AB0E980000CDF4D /* RCTSourceCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSourceCode.m; sourceTree = "<group>"; };
008341F41D1DB34400876D9A /* RCTJSStackFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSStackFrame.m; sourceTree = "<group>"; }; 008341F41D1DB34400876D9A /* RCTJSStackFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSStackFrame.m; sourceTree = "<group>"; };
008341F51D1DB34400876D9A /* RCTJSStackFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSStackFrame.h; sourceTree = "<group>"; }; 008341F51D1DB34400876D9A /* RCTJSStackFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSStackFrame.h; sourceTree = "<group>"; };
131541CF1D3E4893006A0E08 /* CSSLayout-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSSLayout-internal.h"; sourceTree = "<group>"; };
131B6AF01AF1093D00FFC3E0 /* RCTSegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControl.h; sourceTree = "<group>"; }; 131B6AF01AF1093D00FFC3E0 /* RCTSegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControl.h; sourceTree = "<group>"; };
131B6AF11AF1093D00FFC3E0 /* RCTSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSegmentedControl.m; sourceTree = "<group>"; }; 131B6AF11AF1093D00FFC3E0 /* RCTSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSegmentedControl.m; sourceTree = "<group>"; };
131B6AF21AF1093D00FFC3E0 /* RCTSegmentedControlManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControlManager.h; sourceTree = "<group>"; }; 131B6AF21AF1093D00FFC3E0 /* RCTSegmentedControlManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControlManager.h; sourceTree = "<group>"; };
@ -342,6 +343,7 @@
133683431D37ACA10077D0C3 /* CSSLayout */ = { 133683431D37ACA10077D0C3 /* CSSLayout */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
131541CF1D3E4893006A0E08 /* CSSLayout-internal.h */,
133683441D37ACA10077D0C3 /* CSSLayout.c */, 133683441D37ACA10077D0C3 /* CSSLayout.c */,
133683451D37ACA10077D0C3 /* CSSLayout.h */, 133683451D37ACA10077D0C3 /* CSSLayout.h */,
133683481D37ACA10077D0C3 /* CSSMacros.h */, 133683481D37ACA10077D0C3 /* CSSMacros.h */,

Просмотреть файл

@ -21,7 +21,7 @@
self = [super init]; self = [super init];
if (self) { if (self) {
if ([[RCTI18nUtil sharedInstance] isRTL]) { if ([[RCTI18nUtil sharedInstance] isRTL]) {
self.cssNode->style.direction = CSSDirectionRTL; CSSNodeStyleSetDirection(self.cssNode, CSSDirectionRTL);
} }
} }
return self; return self;
@ -33,14 +33,14 @@
case RCTRootViewSizeFlexibilityNone: case RCTRootViewSizeFlexibilityNone:
break; break;
case RCTRootViewSizeFlexibilityWidth: case RCTRootViewSizeFlexibilityWidth:
self.cssNode->style.dimensions[CSSDimensionWidth] = CSSUndefined; CSSNodeStyleSetWidth(self.cssNode, CSSUndefined);
break; break;
case RCTRootViewSizeFlexibilityHeight: case RCTRootViewSizeFlexibilityHeight:
self.cssNode->style.dimensions[CSSDimensionHeight] = CSSUndefined; CSSNodeStyleSetHeight(self.cssNode, CSSUndefined);
break; break;
case RCTRootViewSizeFlexibilityWidthAndHeight: case RCTRootViewSizeFlexibilityWidthAndHeight:
self.cssNode->style.dimensions[CSSDimensionWidth] = CSSUndefined; CSSNodeStyleSetWidth(self.cssNode, CSSUndefined);
self.cssNode->style.dimensions[CSSDimensionHeight] = CSSUndefined; CSSNodeStyleSetHeight(self.cssNode, CSSUndefined);
break; break;
} }
} }
@ -49,7 +49,7 @@
{ {
[self applySizeConstraints]; [self applySizeConstraints];
layoutNode(self.cssNode, CSSUndefined, CSSUndefined, CSSDirectionInherit); CSSNodeCalculateLayout(self.cssNode, CSSUndefined, CSSUndefined, CSSDirectionInherit);
NSMutableSet<RCTShadowView *> *viewsWithNewFrame = [NSMutableSet set]; NSMutableSet<RCTShadowView *> *viewsWithNewFrame = [NSMutableSet set];
[self applyLayoutNode:self.cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero]; [self applyLayoutNode:self.cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero];

Просмотреть файл

@ -44,7 +44,7 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
- (void)removeReactSubview:(RCTShadowView *)subview NS_REQUIRES_SUPER; - (void)removeReactSubview:(RCTShadowView *)subview NS_REQUIRES_SUPER;
@property (nonatomic, weak, readonly) RCTShadowView *superview; @property (nonatomic, weak, readonly) RCTShadowView *superview;
@property (nonatomic, assign, readonly) CSSNode *cssNode; @property (nonatomic, assign, readonly) CSSNodeRef cssNode;
@property (nonatomic, copy) NSString *viewName; @property (nonatomic, copy) NSString *viewName;
@property (nonatomic, strong) UIColor *backgroundColor; // Used to propagate to children @property (nonatomic, strong) UIColor *backgroundColor; // Used to propagate to children
@property (nonatomic, assign) RCTUpdateLifecycle layoutLifecycle; @property (nonatomic, assign) RCTUpdateLifecycle layoutLifecycle;
@ -172,14 +172,14 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
* is split into two methods so subclasses can override `applyLayoutToChildren:` * is split into two methods so subclasses can override `applyLayoutToChildren:`
* while using default implementation of `applyLayoutNode:`. * while using default implementation of `applyLayoutNode:`.
*/ */
- (void)applyLayoutNode:(CSSNode *)node - (void)applyLayoutNode:(CSSNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER; absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER;
/** /**
* Enumerate the child nodes and tell them to apply layout. * Enumerate the child nodes and tell them to apply layout.
*/ */
- (void)applyLayoutToChildren:(CSSNode *)node - (void)applyLayoutToChildren:(CSSNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition; absolutePosition:(CGPoint)absolutePosition;

Просмотреть файл

@ -56,7 +56,7 @@ static void RCTPrint(void *context)
printf("%s(%zd), ", shadowView.viewName.UTF8String, shadowView.reactTag.integerValue); printf("%s(%zd), ", shadowView.viewName.UTF8String, shadowView.reactTag.integerValue);
} }
static CSSNode *RCTGetChild(void *context, int i) static CSSNodeRef RCTGetChild(void *context, int i)
{ {
RCTShadowView *shadowView = (__bridge RCTShadowView *)context; RCTShadowView *shadowView = (__bridge RCTShadowView *)context;
RCTShadowView *child = [shadowView reactSubviews][i]; RCTShadowView *child = [shadowView reactSubviews][i];
@ -70,25 +70,53 @@ static bool RCTIsDirty(void *context)
} }
// Enforces precedence rules, e.g. marginLeft > marginHorizontal > margin. // Enforces precedence rules, e.g. marginLeft > marginHorizontal > margin.
static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float style[CSSPositionCount]) { #define DEFINE_PROCESS_META_PROPS(type) \
style[CSSPositionLeft] = !isUndefined(metaProps[META_PROP_LEFT]) ? metaProps[META_PROP_LEFT] static void RCTProcessMetaProps##type(const float metaProps[META_PROP_COUNT], CSSNodeRef node) { \
: !isUndefined(metaProps[META_PROP_HORIZONTAL]) ? metaProps[META_PROP_HORIZONTAL] if (!isUndefined(metaProps[META_PROP_LEFT])) { \
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL] CSSNodeStyleSet##type##Left(node, metaProps[META_PROP_LEFT]); \
: 0; } else if (!isUndefined(metaProps[META_PROP_HORIZONTAL])) { \
style[CSSPositionRight] = !isUndefined(metaProps[META_PROP_RIGHT]) ? metaProps[META_PROP_RIGHT] CSSNodeStyleSet##type##Left(node, metaProps[META_PROP_HORIZONTAL]); \
: !isUndefined(metaProps[META_PROP_HORIZONTAL]) ? metaProps[META_PROP_HORIZONTAL] } else if (!isUndefined(metaProps[META_PROP_ALL])) { \
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL] CSSNodeStyleSet##type##Left(node, metaProps[META_PROP_ALL]); \
: 0; } else { \
style[CSSPositionTop] = !isUndefined(metaProps[META_PROP_TOP]) ? metaProps[META_PROP_TOP] CSSNodeStyleSet##type##Left(node, 0); \
: !isUndefined(metaProps[META_PROP_VERTICAL]) ? metaProps[META_PROP_VERTICAL] } \
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL] \
: 0; if (!isUndefined(metaProps[META_PROP_RIGHT])) { \
style[CSSPositionBottom] = !isUndefined(metaProps[META_PROP_BOTTOM]) ? metaProps[META_PROP_BOTTOM] CSSNodeStyleSet##type##Right(node, metaProps[META_PROP_RIGHT]); \
: !isUndefined(metaProps[META_PROP_VERTICAL]) ? metaProps[META_PROP_VERTICAL] } else if (!isUndefined(metaProps[META_PROP_HORIZONTAL])) { \
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL] CSSNodeStyleSet##type##Right(node, metaProps[META_PROP_HORIZONTAL]); \
: 0; } else if (!isUndefined(metaProps[META_PROP_ALL])) { \
CSSNodeStyleSet##type##Right(node, metaProps[META_PROP_ALL]); \
} else { \
CSSNodeStyleSet##type##Right(node, 0); \
} \
\
if (!isUndefined(metaProps[META_PROP_TOP])) { \
CSSNodeStyleSet##type##Top(node, metaProps[META_PROP_TOP]); \
} else if (!isUndefined(metaProps[META_PROP_VERTICAL])) { \
CSSNodeStyleSet##type##Top(node, metaProps[META_PROP_VERTICAL]); \
} else if (!isUndefined(metaProps[META_PROP_ALL])) { \
CSSNodeStyleSet##type##Top(node, metaProps[META_PROP_ALL]); \
} else { \
CSSNodeStyleSet##type##Top(node, 0); \
} \
\
if (!isUndefined(metaProps[META_PROP_BOTTOM])) { \
CSSNodeStyleSet##type##Bottom(node, metaProps[META_PROP_BOTTOM]); \
} else if (!isUndefined(metaProps[META_PROP_VERTICAL])) { \
CSSNodeStyleSet##type##Bottom(node, metaProps[META_PROP_VERTICAL]); \
} else if (!isUndefined(metaProps[META_PROP_ALL])) { \
CSSNodeStyleSet##type##Bottom(node, metaProps[META_PROP_ALL]); \
} else { \
CSSNodeStyleSet##type##Bottom(node, 0); \
} \
} }
DEFINE_PROCESS_META_PROPS(Padding);
DEFINE_PROCESS_META_PROPS(Margin);
DEFINE_PROCESS_META_PROPS(Border);
// The absolute stuff is so that we can take into account our absolute position when rounding in order to // The absolute stuff is so that we can take into account our absolute position when rounding in order to
// snap to the pixel grid. For example, say you have the following structure: // snap to the pixel grid. For example, say you have the following structure:
// //
@ -118,29 +146,29 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
// width = 213.5 - 106.5 = 107 // width = 213.5 - 106.5 = 107
// You'll notice that this is the same width we calculated for the parent view because we've taken its position into account. // You'll notice that this is the same width we calculated for the parent view because we've taken its position into account.
- (void)applyLayoutNode:(CSSNode *)node - (void)applyLayoutNode:(CSSNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition absolutePosition:(CGPoint)absolutePosition
{ {
if (!node->layout.shouldUpdate) { if (!CSSNodeGetShouldUpdate(node)) {
return; return;
} }
node->layout.shouldUpdate = false; CSSNodeSetShouldUpdate(node, false);
_layoutLifecycle = RCTUpdateLifecycleComputed; _layoutLifecycle = RCTUpdateLifecycleComputed;
CGPoint absoluteTopLeft = { CGPoint absoluteTopLeft = {
absolutePosition.x + node->layout.position[CSSPositionLeft], absolutePosition.x + CSSNodeLayoutGetLeft(node),
absolutePosition.y + node->layout.position[CSSPositionTop] absolutePosition.y + CSSNodeLayoutGetTop(node)
}; };
CGPoint absoluteBottomRight = { CGPoint absoluteBottomRight = {
absolutePosition.x + node->layout.position[CSSPositionLeft] + node->layout.dimensions[CSSDimensionWidth], absolutePosition.x + CSSNodeLayoutGetLeft(node) + CSSNodeLayoutGetWidth(node),
absolutePosition.y + node->layout.position[CSSPositionTop] + node->layout.dimensions[CSSDimensionHeight] absolutePosition.y + CSSNodeLayoutGetTop(node) + CSSNodeLayoutGetHeight(node)
}; };
CGRect frame = {{ CGRect frame = {{
RCTRoundPixelValue(node->layout.position[CSSPositionLeft]), RCTRoundPixelValue(CSSNodeLayoutGetLeft(node)),
RCTRoundPixelValue(node->layout.position[CSSPositionTop]), RCTRoundPixelValue(CSSNodeLayoutGetTop(node)),
}, { }, {
RCTRoundPixelValue(absoluteBottomRight.x - absoluteTopLeft.x), RCTRoundPixelValue(absoluteBottomRight.x - absoluteTopLeft.x),
RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y) RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y)
@ -151,19 +179,19 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
[viewsWithNewFrame addObject:self]; [viewsWithNewFrame addObject:self];
} }
absolutePosition.x += node->layout.position[CSSPositionLeft]; absolutePosition.x += CSSNodeLayoutGetLeft(node);
absolutePosition.y += node->layout.position[CSSPositionTop]; absolutePosition.y += CSSNodeLayoutGetTop(node);
[self applyLayoutToChildren:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition]; [self applyLayoutToChildren:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];
} }
- (void)applyLayoutToChildren:(CSSNode *)node - (void)applyLayoutToChildren:(CSSNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition absolutePosition:(CGPoint)absolutePosition
{ {
for (int i = 0; i < node->childCount; ++i) { for (int i = 0; i < CSSNodeGetChildCount(node); ++i) {
RCTShadowView *child = (RCTShadowView *)_reactSubviews[i]; RCTShadowView *child = (RCTShadowView *)_reactSubviews[i];
[child applyLayoutNode:node->getChild(node->context, i) [child applyLayoutNode:RCTGetChild(CSSNodeGetContext(node), i)
viewsWithNewFrame:viewsWithNewFrame viewsWithNewFrame:viewsWithNewFrame
absolutePosition:absolutePosition]; absolutePosition:absolutePosition];
} }
@ -237,18 +265,19 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
} }
if (!CGRectEqualToRect(frame, _frame)) { if (!CGRectEqualToRect(frame, _frame)) {
_cssNode->style.positionType = CSSPositionTypeAbsolute; CSSNodeStyleSetPositionType(_cssNode, CSSPositionTypeAbsolute);
_cssNode->style.dimensions[CSSDimensionWidth] = frame.size.width; CSSNodeStyleSetWidth(_cssNode, frame.size.width);
_cssNode->style.dimensions[CSSDimensionHeight] = frame.size.height; CSSNodeStyleSetHeight(_cssNode, frame.size.height);
_cssNode->style.position[CSSPositionLeft] = frame.origin.x; CSSNodeStyleSetPositionLeft(_cssNode, frame.origin.x);
_cssNode->style.position[CSSPositionTop] = frame.origin.y; CSSNodeStyleSetPositionTop(_cssNode, frame.origin.y);
// Our parent has asked us to change our cssNode->styles. Dirty the layout // Our parent has asked us to change our cssNode->styles. Dirty the layout
// so that we can rerun layout on this node. The request came from our parent // so that we can rerun layout on this node. The request came from our parent
// so there's no need to dirty our ancestors by calling dirtyLayout. // so there's no need to dirty our ancestors by calling dirtyLayout.
_layoutLifecycle = RCTUpdateLifecycleDirtied; _layoutLifecycle = RCTUpdateLifecycleDirtied;
} }
layoutNode(_cssNode, frame.size.width, frame.size.height, CSSDirectionInherit); CSSNodeCalculateLayout(_cssNode, frame.size.width, frame.size.height, CSSDirectionInherit);
[self applyLayoutNode:_cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition]; [self applyLayoutNode:_cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];
} }
@ -289,10 +318,10 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
_reactSubviews = [NSMutableArray array]; _reactSubviews = [NSMutableArray array];
_cssNode = CSSNodeNew(); _cssNode = CSSNodeNew();
_cssNode->context = (__bridge void *)self; CSSNodeSetContext(_cssNode, (__bridge void *)self);
_cssNode->print = RCTPrint; CSSNodeSetChildFunc(_cssNode, RCTGetChild);
_cssNode->getChild = RCTGetChild; CSSNodeSetPrintFunc(_cssNode, RCTPrint);
_cssNode->isDirty = RCTIsDirty; CSSNodeSetIsDirtyFunc(_cssNode, RCTIsDirty);
} }
return self; return self;
} }
@ -359,7 +388,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
{ {
[_reactSubviews insertObject:subview atIndex:atIndex]; [_reactSubviews insertObject:subview atIndex:atIndex];
_cssNode->childCount = [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count; CSSNodeSetChildCount(_cssNode, [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count);
subview->_superview = self; subview->_superview = self;
_didUpdateSubviews = YES; _didUpdateSubviews = YES;
[self dirtyText]; [self dirtyText];
@ -375,7 +404,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
_didUpdateSubviews = YES; _didUpdateSubviews = YES;
subview->_superview = nil; subview->_superview = nil;
[_reactSubviews removeObject:subview]; [_reactSubviews removeObject:subview];
_cssNode->childCount = [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count; CSSNodeSetChildCount(_cssNode, [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count);
} }
- (NSArray<RCTShadowView *> *)reactSubviews - (NSArray<RCTShadowView *> *)reactSubviews
@ -475,10 +504,10 @@ RCT_PADDING_PROPERTY(Right, RIGHT)
- (UIEdgeInsets)paddingAsInsets - (UIEdgeInsets)paddingAsInsets
{ {
return (UIEdgeInsets){ return (UIEdgeInsets){
_cssNode->style.padding[CSSPositionTop], CSSNodeStyleGetPaddingTop(_cssNode),
_cssNode->style.padding[CSSPositionLeft], CSSNodeStyleGetPaddingLeft(_cssNode),
_cssNode->style.padding[CSSPositionBottom], CSSNodeStyleGetPaddingBottom(_cssNode),
_cssNode->style.padding[CSSPositionRight] CSSNodeStyleGetPaddingRight(_cssNode)
}; };
} }
@ -504,58 +533,66 @@ RCT_BORDER_PROPERTY(Right, RIGHT)
// Dimensions // Dimensions
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp, category) \ #define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
- (void)set##setProp:(CGFloat)value \ - (void)set##setProp:(CGFloat)value \
{ \ { \
_cssNode->style.category[CSS##cssProp] = value; \ CSSNodeStyleSet##cssProp(_cssNode, value); \
[self dirtyLayout]; \ [self dirtyLayout]; \
[self dirtyText]; \ [self dirtyText]; \
} \ } \
- (CGFloat)getProp \ - (CGFloat)getProp \
{ \ { \
return _cssNode->style.category[CSS##cssProp]; \ return CSSNodeStyleGet##cssProp(_cssNode); \
} }
RCT_DIMENSION_PROPERTY(Width, width, DimensionWidth, dimensions) RCT_DIMENSION_PROPERTY(Width, width, Width)
RCT_DIMENSION_PROPERTY(Height, height, DimensionHeight, dimensions) RCT_DIMENSION_PROPERTY(Height, height, Height)
RCT_DIMENSION_PROPERTY(MinWidth, minWidth, MinWidth)
RCT_DIMENSION_PROPERTY(MinWidth, minWidth, DimensionWidth, minDimensions) RCT_DIMENSION_PROPERTY(MinHeight, minHeight, MinHeight)
RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, DimensionWidth, maxDimensions) RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, MaxWidth)
RCT_DIMENSION_PROPERTY(MinHeight, minHeight, DimensionHeight, minDimensions) RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, MaxHeight)
RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, DimensionHeight, maxDimensions)
// Position // Position
#define RCT_POSITION_PROPERTY(setProp, getProp, cssProp) \ RCT_DIMENSION_PROPERTY(Top, top, PositionTop)
RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp, position) RCT_DIMENSION_PROPERTY(Right, right, PositionRight)
RCT_DIMENSION_PROPERTY(Bottom, bottom, PositionBottom)
RCT_POSITION_PROPERTY(Top, top, PositionTop) RCT_DIMENSION_PROPERTY(Left, left, PositionLeft)
RCT_POSITION_PROPERTY(Right, right, PositionRight)
RCT_POSITION_PROPERTY(Bottom, bottom, PositionBottom)
RCT_POSITION_PROPERTY(Left, left, PositionLeft)
- (void)setFrame:(CGRect)frame - (void)setFrame:(CGRect)frame
{ {
_cssNode->style.position[CSSPositionLeft] = CGRectGetMinX(frame); CSSNodeStyleSetPositionLeft(_cssNode, CGRectGetMinX(frame));
_cssNode->style.position[CSSPositionTop] = CGRectGetMinY(frame); CSSNodeStyleSetPositionTop(_cssNode, CGRectGetMinY(frame));
_cssNode->style.dimensions[CSSDimensionWidth] = CGRectGetWidth(frame); CSSNodeStyleSetWidth(_cssNode, CGRectGetWidth(frame));
_cssNode->style.dimensions[CSSDimensionHeight] = CGRectGetHeight(frame); CSSNodeStyleSetHeight(_cssNode, CGRectGetHeight(frame));
[self dirtyLayout]; [self dirtyLayout];
} }
static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension, CGFloat amount) static inline BOOL RCTAssignSuggestedDimension(CSSNodeRef cssNode, CSSDimension dimension, CGFloat amount)
{ {
if (amount != UIViewNoIntrinsicMetric if (amount != UIViewNoIntrinsicMetric) {
&& isnan(cssNode->style.dimensions[dimension])) { switch (dimension) {
cssNode->style.dimensions[dimension] = amount; case CSSDimensionWidth:
return YES; if (isnan(CSSNodeStyleGetWidth(cssNode))) {
CSSNodeStyleSetWidth(cssNode, amount);
return YES;
}
break;
case CSSDimensionHeight:
if (isnan(CSSNodeStyleGetHeight(cssNode))) {
CSSNodeStyleSetHeight(cssNode, amount);
return YES;
}
break;
}
} }
return NO; return NO;
} }
- (void)setIntrinsicContentSize:(CGSize)size - (void)setIntrinsicContentSize:(CGSize)size
{ {
if (_cssNode->style.flex == 0) { if (CSSNodeStyleGetFlex(_cssNode) == 0) {
BOOL dirty = NO; BOOL dirty = NO;
dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionHeight, size.height); dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionHeight, size.height);
dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionWidth, size.width); dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionWidth, size.width);
@ -567,15 +604,15 @@ static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension,
- (void)setTopLeft:(CGPoint)topLeft - (void)setTopLeft:(CGPoint)topLeft
{ {
_cssNode->style.position[CSSPositionLeft] = topLeft.x; CSSNodeStyleSetPositionLeft(_cssNode, topLeft.x);
_cssNode->style.position[CSSPositionTop] = topLeft.y; CSSNodeStyleSetPositionTop(_cssNode, topLeft.y);
[self dirtyLayout]; [self dirtyLayout];
} }
- (void)setSize:(CGSize)size - (void)setSize:(CGSize)size
{ {
_cssNode->style.dimensions[CSSDimensionWidth] = size.width; CSSNodeStyleSetWidth(_cssNode, size.width);
_cssNode->style.dimensions[CSSDimensionHeight] = size.height; CSSNodeStyleSetHeight(_cssNode, size.height);
[self dirtyLayout]; [self dirtyLayout];
} }
@ -584,21 +621,21 @@ static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension,
#define RCT_STYLE_PROPERTY(setProp, getProp, cssProp, type) \ #define RCT_STYLE_PROPERTY(setProp, getProp, cssProp, type) \
- (void)set##setProp:(type)value \ - (void)set##setProp:(type)value \
{ \ { \
_cssNode->style.cssProp = value; \ CSSNodeStyleSet##cssProp(_cssNode, value); \
[self dirtyLayout]; \ [self dirtyLayout]; \
} \ } \
- (type)getProp \ - (type)getProp \
{ \ { \
return _cssNode->style.cssProp; \ return CSSNodeStyleGet##cssProp(_cssNode); \
} }
RCT_STYLE_PROPERTY(Flex, flex, flex, CGFloat) RCT_STYLE_PROPERTY(Flex, flex, Flex, CGFloat)
RCT_STYLE_PROPERTY(FlexDirection, flexDirection, flexDirection, CSSFlexDirection) RCT_STYLE_PROPERTY(FlexDirection, flexDirection, FlexDirection, CSSFlexDirection)
RCT_STYLE_PROPERTY(JustifyContent, justifyContent, justifyContent, CSSJustify) RCT_STYLE_PROPERTY(JustifyContent, justifyContent, JustifyContent, CSSJustify)
RCT_STYLE_PROPERTY(AlignSelf, alignSelf, alignSelf, CSSAlign) RCT_STYLE_PROPERTY(AlignSelf, alignSelf, AlignSelf, CSSAlign)
RCT_STYLE_PROPERTY(AlignItems, alignItems, alignItems, CSSAlign) RCT_STYLE_PROPERTY(AlignItems, alignItems, AlignItems, CSSAlign)
RCT_STYLE_PROPERTY(Position, position, positionType, CSSPositionType) RCT_STYLE_PROPERTY(Position, position, PositionType, CSSPositionType)
RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flexWrap, CSSWrapType) RCT_STYLE_PROPERTY(FlexWrap, flexWrap, FlexWrap, CSSWrapType)
- (void)setBackgroundColor:(UIColor *)color - (void)setBackgroundColor:(UIColor *)color
{ {
@ -624,13 +661,13 @@ RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flexWrap, CSSWrapType)
- (void)didSetProps:(__unused NSArray<NSString *> *)changedProps - (void)didSetProps:(__unused NSArray<NSString *> *)changedProps
{ {
if (_recomputePadding) { if (_recomputePadding) {
RCTProcessMetaProps(_paddingMetaProps, _cssNode->style.padding); RCTProcessMetaPropsPadding(_paddingMetaProps, _cssNode);
} }
if (_recomputeMargin) { if (_recomputeMargin) {
RCTProcessMetaProps(_marginMetaProps, _cssNode->style.margin); RCTProcessMetaPropsMargin(_marginMetaProps, _cssNode);
} }
if (_recomputeBorder) { if (_recomputeBorder) {
RCTProcessMetaProps(_borderMetaProps, _cssNode->style.border); RCTProcessMetaPropsBorder(_borderMetaProps, _cssNode);
} }
if (_recomputePadding || _recomputeMargin || _recomputeBorder) { if (_recomputePadding || _recomputeMargin || _recomputeBorder) {
[self dirtyLayout]; [self dirtyLayout];