diff --git a/Yoga.podspec b/Yoga.podspec index 7d4553e8..a13fb02f 100644 --- a/Yoga.podspec +++ b/Yoga.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'Yoga' - spec.version = '1.8.1' + spec.version = '1.9.0' spec.license = { :type => 'MIT', :file => "LICENSE" } spec.homepage = 'https://yogalayout.com/' spec.documentation_url = 'https://yogalayout.com/docs' @@ -11,11 +11,14 @@ Pod::Spec.new do |spec| spec.authors = 'Facebook' spec.source = { :git => 'https://github.com/facebook/yoga.git', - :tag => '1.8.0', + :tag => spec.version.to_s, } spec.platforms = { :ios => "8.0", :tvos => "10.0" } spec.module_name = 'yoga' spec.requires_arc = false + spec.pod_target_xcconfig = { + 'DEFINES_MODULE' => 'YES' + } spec.compiler_flags = [ '-fno-omit-frame-pointer', '-fexceptions', diff --git a/YogaKit.podspec b/YogaKit.podspec index e21f6808..59af6974 100644 --- a/YogaKit.podspec +++ b/YogaKit.podspec @@ -1,6 +1,6 @@ podspec = Pod::Spec.new do |spec| spec.name = 'YogaKit' - spec.version = '1.8.1' + spec.version = '1.9.0' spec.license = { :type => 'MIT', :file => "LICENSE" } spec.homepage = 'https://facebook.github.io/yoga/' spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/yogakit/' @@ -11,14 +11,14 @@ podspec = Pod::Spec.new do |spec| spec.authors = 'Facebook' spec.source = { :git => 'https://github.com/facebook/yoga.git', - :tag => '1.7.0', + :tag => spec.version.to_s, } spec.platform = :ios spec.ios.deployment_target = '8.0' spec.ios.frameworks = 'UIKit' - spec.dependency 'Yoga', '~> 1.8.1' + spec.dependency 'Yoga', '~> 1.9' spec.source_files = 'YogaKit/Source/*.{h,m,swift}' spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h' spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h' diff --git a/benchmark/YGBenchmark.c b/benchmark/YGBenchmark.c index 1c5521ae..c06ca276 100644 --- a/benchmark/YGBenchmark.c +++ b/benchmark/YGBenchmark.c @@ -5,10 +5,72 @@ * LICENSE file in the root directory of this source tree. */ -#include "YGBenchmark.h" +#include +#include +#include +#include +#include #include +#define NUM_REPETITIONS 1000 + +#define YGBENCHMARKS(BLOCK) \ + int main(int argc, char const *argv[]) { \ + clock_t __start; \ + clock_t __endTimes[NUM_REPETITIONS]; \ + { BLOCK } \ + return 0; \ + } + +#define YGBENCHMARK(NAME, BLOCK) \ + __start = clock(); \ + for (uint32_t __i = 0; __i < NUM_REPETITIONS; __i++) { \ + { BLOCK } \ + __endTimes[__i] = clock(); \ + } \ + __printBenchmarkResult(NAME, __start, __endTimes); + +static int __compareDoubles(const void *a, const void *b) { + double arg1 = *(const double *) a; + double arg2 = *(const double *) b; + + if (arg1 < arg2) { + return -1; + } + + if (arg1 > arg2) { + return 1; + } + + return 0; +} + +static void __printBenchmarkResult(char *name, clock_t start, clock_t *endTimes) { + double timesInMs[NUM_REPETITIONS]; + double mean = 0; + clock_t lastEnd = start; + for (uint32_t i = 0; i < NUM_REPETITIONS; i++) { + timesInMs[i] = (endTimes[i] - lastEnd) / (double) CLOCKS_PER_SEC * 1000; + lastEnd = endTimes[i]; + mean += timesInMs[i]; + } + mean /= NUM_REPETITIONS; + + qsort(timesInMs, NUM_REPETITIONS, sizeof(double), __compareDoubles); + double median = timesInMs[NUM_REPETITIONS / 2]; + + double variance = 0; + for (uint32_t i = 0; i < NUM_REPETITIONS; i++) { + variance += pow(timesInMs[i] - mean, 2); + } + variance /= NUM_REPETITIONS; + double stddev = sqrt(variance); + + printf("%s: median: %lf ms, stddev: %lf ms\n", name, median, stddev); +} + + static YGSize _measure(YGNodeRef node, float width, YGMeasureMode widthMode, @@ -97,7 +159,7 @@ YGBENCHMARKS({ YGNodeStyleSetHeight(grandGrandChild, 10); YGNodeInsertChild(grandChild, grandGrandChild, 0); - for (uint32_t iii = 0; iii < 10; iii++) { + for (uint32_t iiii = 0; iiii < 10; iiii++) { const YGNodeRef grandGrandGrandChild = YGNodeNew(); YGNodeStyleSetFlexDirection(grandGrandGrandChild, YGFlexDirectionRow); YGNodeStyleSetFlexGrow(grandGrandGrandChild, 1); diff --git a/benchmark/YGBenchmark.h b/benchmark/YGBenchmark.h deleted file mode 100644 index 54a625b7..00000000 --- a/benchmark/YGBenchmark.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include -#include - -#define NUM_REPETITIONS 1000 - -#define YGBENCHMARKS(BLOCK) \ - int main(int argc, char const *argv[]) { \ - clock_t __start; \ - clock_t __endTimes[NUM_REPETITIONS]; \ - { BLOCK } \ - return 0; \ - } - -#define YGBENCHMARK(NAME, BLOCK) \ - __start = clock(); \ - for (uint32_t __i = 0; __i < NUM_REPETITIONS; __i++) { \ - { BLOCK } \ - __endTimes[__i] = clock(); \ - } \ - __printBenchmarkResult(NAME, __start, __endTimes); - -int __compareDoubles(const void *a, const void *b) { - double arg1 = *(const double *) a; - double arg2 = *(const double *) b; - - if (arg1 < arg2) { - return -1; - } - - if (arg1 > arg2) { - return 1; - } - - return 0; -} - -void __printBenchmarkResult(char *name, clock_t start, clock_t *endTimes) { - double timesInMs[NUM_REPETITIONS]; - double mean = 0; - clock_t lastEnd = start; - for (uint32_t i = 0; i < NUM_REPETITIONS; i++) { - timesInMs[i] = (endTimes[i] - lastEnd) / (double) CLOCKS_PER_SEC * 1000; - lastEnd = endTimes[i]; - mean += timesInMs[i]; - } - mean /= NUM_REPETITIONS; - - qsort(timesInMs, NUM_REPETITIONS, sizeof(double), __compareDoubles); - double median = timesInMs[NUM_REPETITIONS / 2]; - - double variance = 0; - for (uint32_t i = 0; i < NUM_REPETITIONS; i++) { - variance += pow(timesInMs[i] - mean, 2); - } - variance /= NUM_REPETITIONS; - double stddev = sqrt(variance); - - printf("%s: median: %lf ms, stddev: %lf ms\n", name, median, stddev); -} diff --git a/csharp/BUCK b/csharp/BUCK index d29f35a3..e679803a 100644 --- a/csharp/BUCK +++ b/csharp/BUCK @@ -3,7 +3,14 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//:yoga_defs.bzl", "BASE_COMPILER_FLAGS", "is_apple_platform", "yoga_cxx_library", "yoga_dep") +load( + "//:yoga_defs.bzl", + "BASE_COMPILER_FLAGS", + "is_apple_platform", + "yoga_cxx_library", + "yoga_dep", + "yoga_apple_binary", +) COMPILER_FLAGS = BASE_COMPILER_FLAGS + ["-std=c++11"] @@ -32,41 +39,4 @@ yoga_cxx_library( deps = [yoga_dep(":yoga")], ) -if is_apple_platform(): - yoganet_ios_srcs = [] - for arch in [ - "iphonesimulator-x86_64", - "iphoneos-arm64", - ]: - name = "yoganet-" + arch - yoganet_ios_srcs.append(":" + name) - genrule( - name = name, - srcs = [ - yoga_dep(":yogaApple#%s,static" % arch), - yoga_dep("YogaKit:YogaKitApple#%s,static" % arch), - yoga_dep("csharp:yoganetApple#%s,static" % arch), - ], - out = "libyoga-%s.a" % arch, - cmd = "libtool -static -o $OUT $SRCS", - visibility = [yoga_dep("csharp:yoganet-ios")], - ) - - genrule( - name = "yoganet-ios", - srcs = yoganet_ios_srcs, - out = "libyoga.a", - cmd = "lipo $SRCS -create -output $OUT", - visibility = ["PUBLIC"], - ) - - yoganet_macosx_target = "csharp:yoganetAppleMac#macosx-%s,dynamic" - genrule( - name = "yoganet-macosx", - srcs = [ - yoga_dep(yoganet_macosx_target % "x86_64"), - ], - out = "libyoga.dylib", - cmd = "lipo $SRCS -create -output $OUT", - visibility = ["PUBLIC"], - ) +yoga_apple_binary() diff --git a/gradle.properties b/gradle.properties index 85411523..51ca14c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1536M -VERSION_NAME=1.8.1-SNAPSHOT +VERSION_NAME=1.9.1-SNAPSHOT POM_URL=https://github.com/facebook/yoga POM_SCM_URL=https://github.com/facebook/yoga.git POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git diff --git a/java/build.gradle b/java/build.gradle index da30fe9b..21034e42 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -52,7 +52,7 @@ android { dependencies { compileOnly 'com.google.code.findbugs:jsr305:3.0.1' compileOnly project(':yoga:proguard-annotations') - implementation 'com.facebook.soloader:soloader:0.2.0' + implementation 'com.facebook.soloader:soloader:0.5.1' testImplementation 'junit:junit:4.12' } diff --git a/java/com/facebook/yoga/YogaAlign.java b/java/com/facebook/yoga/YogaAlign.java index bea5aebd..5687ab9d 100644 --- a/java/com/facebook/yoga/YogaAlign.java +++ b/java/com/facebook/yoga/YogaAlign.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaBaselineFunction.java b/java/com/facebook/yoga/YogaBaselineFunction.java index 9ec41e7e..20feae33 100644 --- a/java/com/facebook/yoga/YogaBaselineFunction.java +++ b/java/com/facebook/yoga/YogaBaselineFunction.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaConfig.java b/java/com/facebook/yoga/YogaConfig.java index 12aa0d8e..128f5328 100644 --- a/java/com/facebook/yoga/YogaConfig.java +++ b/java/com/facebook/yoga/YogaConfig.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaConstants.java b/java/com/facebook/yoga/YogaConstants.java index 4e081ce4..68c5c982 100644 --- a/java/com/facebook/yoga/YogaConstants.java +++ b/java/com/facebook/yoga/YogaConstants.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; public class YogaConstants { diff --git a/java/com/facebook/yoga/YogaDimension.java b/java/com/facebook/yoga/YogaDimension.java index b0d89226..3a950e01 100644 --- a/java/com/facebook/yoga/YogaDimension.java +++ b/java/com/facebook/yoga/YogaDimension.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaDirection.java b/java/com/facebook/yoga/YogaDirection.java index dd6444e1..ccd46e84 100644 --- a/java/com/facebook/yoga/YogaDirection.java +++ b/java/com/facebook/yoga/YogaDirection.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaDisplay.java b/java/com/facebook/yoga/YogaDisplay.java index e6e52aad..75c2b687 100644 --- a/java/com/facebook/yoga/YogaDisplay.java +++ b/java/com/facebook/yoga/YogaDisplay.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaEdge.java b/java/com/facebook/yoga/YogaEdge.java index 053490da..36a893f6 100644 --- a/java/com/facebook/yoga/YogaEdge.java +++ b/java/com/facebook/yoga/YogaEdge.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaExperimentalFeature.java b/java/com/facebook/yoga/YogaExperimentalFeature.java index a8a4be14..790bd056 100644 --- a/java/com/facebook/yoga/YogaExperimentalFeature.java +++ b/java/com/facebook/yoga/YogaExperimentalFeature.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaFlexDirection.java b/java/com/facebook/yoga/YogaFlexDirection.java index cf192d6c..5c66d92f 100644 --- a/java/com/facebook/yoga/YogaFlexDirection.java +++ b/java/com/facebook/yoga/YogaFlexDirection.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaJustify.java b/java/com/facebook/yoga/YogaJustify.java index 9e15dc4a..13d3a001 100644 --- a/java/com/facebook/yoga/YogaJustify.java +++ b/java/com/facebook/yoga/YogaJustify.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaLogLevel.java b/java/com/facebook/yoga/YogaLogLevel.java index 458e1b95..0cf7f70c 100644 --- a/java/com/facebook/yoga/YogaLogLevel.java +++ b/java/com/facebook/yoga/YogaLogLevel.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaLogger.java b/java/com/facebook/yoga/YogaLogger.java index 66f62c89..6d1a6a1e 100644 --- a/java/com/facebook/yoga/YogaLogger.java +++ b/java/com/facebook/yoga/YogaLogger.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaMeasureFunction.java b/java/com/facebook/yoga/YogaMeasureFunction.java index 2d2b304d..cc54caec 100644 --- a/java/com/facebook/yoga/YogaMeasureFunction.java +++ b/java/com/facebook/yoga/YogaMeasureFunction.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaMeasureMode.java b/java/com/facebook/yoga/YogaMeasureMode.java index 97193776..5cfc24a4 100644 --- a/java/com/facebook/yoga/YogaMeasureMode.java +++ b/java/com/facebook/yoga/YogaMeasureMode.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaMeasureOutput.java b/java/com/facebook/yoga/YogaMeasureOutput.java index 1d2141d1..e68af410 100644 --- a/java/com/facebook/yoga/YogaMeasureOutput.java +++ b/java/com/facebook/yoga/YogaMeasureOutput.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; /** diff --git a/java/com/facebook/yoga/YogaNodeCloneFunction.java b/java/com/facebook/yoga/YogaNodeCloneFunction.java index 0733776a..ccf7f5c5 100644 --- a/java/com/facebook/yoga/YogaNodeCloneFunction.java +++ b/java/com/facebook/yoga/YogaNodeCloneFunction.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2017-present, Facebook, Inc. + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaNodeProperties.java b/java/com/facebook/yoga/YogaNodeProperties.java new file mode 100644 index 00000000..fbad2ea2 --- /dev/null +++ b/java/com/facebook/yoga/YogaNodeProperties.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.yoga; + +public interface YogaNodeProperties { + + YogaNodeProperties clone(YogaNode node); + + long getNativePointer(); + + void onAfterCalculateLayout(); + + void reset(); + + boolean hasNewLayout(); + + boolean isDirty(); + + void markLayoutSeen(); + + YogaDirection getStyleDirection(); + + void setDirection(YogaDirection direction); + + YogaFlexDirection getFlexDirection(); + + void setFlexDirection(YogaFlexDirection flexDirection); + + YogaJustify getJustifyContent(); + + void setJustifyContent(YogaJustify justifyContent); + + YogaAlign getAlignItems(); + + void setAlignItems(YogaAlign alignItems); + + YogaAlign getAlignSelf(); + + void setAlignSelf(YogaAlign alignSelf); + + YogaAlign getAlignContent(); + + void setAlignContent(YogaAlign alignContent); + + YogaPositionType getPositionType(); + + void setPositionType(YogaPositionType positionType); + + void setWrap(YogaWrap flexWrap); + + YogaOverflow getOverflow(); + + void setOverflow(YogaOverflow overflow); + + YogaDisplay getDisplay(); + + void setDisplay(YogaDisplay display); + + void setFlex(float flex); + + float getFlexGrow(); + + void setFlexGrow(float flexGrow); + + float getFlexShrink(); + + void setFlexShrink(float flexShrink); + + YogaValue getFlexBasis(); + + void setFlexBasis(float flexBasis); + + void setFlexBasisPercent(float percent); + + void setFlexBasisAuto(); + + YogaValue getMargin(YogaEdge edge); + + void setMargin(YogaEdge edge, float margin); + + void setMarginPercent(YogaEdge edge, float percent); + + void setMarginAuto(YogaEdge edge); + + YogaValue getPadding(YogaEdge edge); + + void setPadding(YogaEdge edge, float padding); + + void setPaddingPercent(YogaEdge edge, float percent); + + float getBorder(YogaEdge edge); + + void setBorder(YogaEdge edge, float border); + + YogaValue getPosition(YogaEdge edge); + + void setPosition(YogaEdge edge, float position); + + void setPositionPercent(YogaEdge edge, float percent); + + YogaValue getWidth(); + + void setWidth(float width); + + void setWidthPercent(float percent); + + void setWidthAuto(); + + YogaValue getHeight(); + + void setHeight(float height); + + void setHeightPercent(float percent); + + void setHeightAuto(); + + YogaValue getMinWidth(); + + void setMinWidth(float minWidth); + + void setMinWidthPercent(float percent); + + YogaValue getMinHeight(); + + void setMinHeight(float minHeight); + + void setMinHeightPercent(float percent); + + YogaValue getMaxWidth(); + + void setMaxWidth(float maxWidth); + + void setMaxWidthPercent(float percent); + + YogaValue getMaxHeight(); + + void setMaxHeight(float maxheight); + + void setMaxHeightPercent(float percent); + + float getAspectRatio(); + + void setAspectRatio(float aspectRatio); + + float getLayoutX(); + + float getLayoutY(); + + float getLayoutWidth(); + + float getLayoutHeight(); + + boolean getDoesLegacyStretchFlagAffectsLayout(); + + float getLayoutMargin(YogaEdge edge); + + float getLayoutPadding(YogaEdge edge); + + float getLayoutBorder(YogaEdge edge); + + YogaDirection getLayoutDirection(); +} diff --git a/java/com/facebook/yoga/YogaNodeType.java b/java/com/facebook/yoga/YogaNodeType.java index fb767b05..7eb7246c 100644 --- a/java/com/facebook/yoga/YogaNodeType.java +++ b/java/com/facebook/yoga/YogaNodeType.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaOverflow.java b/java/com/facebook/yoga/YogaOverflow.java index 9563d303..85bc8b20 100644 --- a/java/com/facebook/yoga/YogaOverflow.java +++ b/java/com/facebook/yoga/YogaOverflow.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaPositionType.java b/java/com/facebook/yoga/YogaPositionType.java index be42a999..17073f47 100644 --- a/java/com/facebook/yoga/YogaPositionType.java +++ b/java/com/facebook/yoga/YogaPositionType.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaPrintOptions.java b/java/com/facebook/yoga/YogaPrintOptions.java index 5a804adf..3b59960d 100644 --- a/java/com/facebook/yoga/YogaPrintOptions.java +++ b/java/com/facebook/yoga/YogaPrintOptions.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaUnit.java b/java/com/facebook/yoga/YogaUnit.java index 8eb2b316..e4002dd0 100644 --- a/java/com/facebook/yoga/YogaUnit.java +++ b/java/com/facebook/yoga/YogaUnit.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaValue.java b/java/com/facebook/yoga/YogaValue.java index a99d5641..c0bb6e22 100644 --- a/java/com/facebook/yoga/YogaValue.java +++ b/java/com/facebook/yoga/YogaValue.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/com/facebook/yoga/YogaWrap.java b/java/com/facebook/yoga/YogaWrap.java index 1eaa9f7a..3c10dd3a 100644 --- a/java/com/facebook/yoga/YogaWrap.java +++ b/java/com/facebook/yoga/YogaWrap.java @@ -1,10 +1,10 @@ /* - * Copyright (c) 2014-present, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - package com.facebook.yoga; import com.facebook.proguard.annotations.DoNotStrip; diff --git a/java/jni/YGJNI.cpp b/java/jni/YGJNI.cpp index 5649ef7e..0b552055 100644 --- a/java/jni/YGJNI.cpp +++ b/java/jni/YGJNI.cpp @@ -33,94 +33,121 @@ struct YGConfigContext { } }; -static inline weak_ref *YGNodeJobject(YGNodeRef node) { +static inline weak_ref* YGNodeJobject(YGNodeRef node) { return reinterpret_cast*>(node->getContext()); } -static void YGTransferLayoutDirection(YGNodeRef node, alias_ref javaNode) { - static auto layoutDirectionField = javaNode->getClass()->getField("mLayoutDirection"); - javaNode->setFieldValue(layoutDirectionField, static_cast(YGNodeLayoutGetDirection(node))); +static void YGTransferLayoutDirection( + YGNodeRef node, + alias_ref javaNode) { + static auto layoutDirectionField = + javaNode->getClass()->getField("mLayoutDirection"); + javaNode->setFieldValue( + layoutDirectionField, static_cast(YGNodeLayoutGetDirection(node))); } static void YGTransferLayoutOutputsRecursive(YGNodeRef root) { - if (root->getHasNewLayout()) { - if (auto obj = YGNodeJobject(root)->lockLocal()) { - static auto widthField = obj->getClass()->getField("mWidth"); - static auto heightField = obj->getClass()->getField("mHeight"); - static auto leftField = obj->getClass()->getField("mLeft"); - static auto topField = obj->getClass()->getField("mTop"); + if (!root->getHasNewLayout()) { + return; + } + auto obj = YGNodeJobject(root)->lockLocal(); + if (!obj) { + YGLog( + root, + YGLogLevelError, + "Java YGNode was GCed during layout calculation\n"); + return; + } - static auto marginLeftField = obj->getClass()->getField("mMarginLeft"); - static auto marginTopField = obj->getClass()->getField("mMarginTop"); - static auto marginRightField = obj->getClass()->getField("mMarginRight"); - static auto marginBottomField = obj->getClass()->getField("mMarginBottom"); + static auto widthField = obj->getClass()->getField("mWidth"); + static auto heightField = obj->getClass()->getField("mHeight"); + static auto leftField = obj->getClass()->getField("mLeft"); + static auto topField = obj->getClass()->getField("mTop"); - static auto paddingLeftField = obj->getClass()->getField("mPaddingLeft"); - static auto paddingTopField = obj->getClass()->getField("mPaddingTop"); - static auto paddingRightField = obj->getClass()->getField("mPaddingRight"); - static auto paddingBottomField = obj->getClass()->getField("mPaddingBottom"); + static auto marginLeftField = + obj->getClass()->getField("mMarginLeft"); + static auto marginTopField = obj->getClass()->getField("mMarginTop"); + static auto marginRightField = + obj->getClass()->getField("mMarginRight"); + static auto marginBottomField = + obj->getClass()->getField("mMarginBottom"); - static auto borderLeftField = obj->getClass()->getField("mBorderLeft"); - static auto borderTopField = obj->getClass()->getField("mBorderTop"); - static auto borderRightField = obj->getClass()->getField("mBorderRight"); - static auto borderBottomField = obj->getClass()->getField("mBorderBottom"); + static auto paddingLeftField = + obj->getClass()->getField("mPaddingLeft"); + static auto paddingTopField = + obj->getClass()->getField("mPaddingTop"); + static auto paddingRightField = + obj->getClass()->getField("mPaddingRight"); + static auto paddingBottomField = + obj->getClass()->getField("mPaddingBottom"); - static auto edgeSetFlagField = obj->getClass()->getField("mEdgeSetFlag"); - static auto hasNewLayoutField = obj->getClass()->getField("mHasNewLayout"); - static auto doesLegacyStretchBehaviour = - obj->getClass()->getField( - "mDoesLegacyStretchFlagAffectsLayout"); + static auto borderLeftField = + obj->getClass()->getField("mBorderLeft"); + static auto borderTopField = obj->getClass()->getField("mBorderTop"); + static auto borderRightField = + obj->getClass()->getField("mBorderRight"); + static auto borderBottomField = + obj->getClass()->getField("mBorderBottom"); - /* Those flags needs be in sync with YogaNode.java */ - const int MARGIN = 1; - const int PADDING = 2; - const int BORDER = 4; + static auto edgeSetFlagField = + obj->getClass()->getField("mEdgeSetFlag"); + static auto hasNewLayoutField = + obj->getClass()->getField("mHasNewLayout"); + static auto doesLegacyStretchBehaviour = obj->getClass()->getField( + "mDoesLegacyStretchFlagAffectsLayout"); - int hasEdgeSetFlag = (int) obj->getFieldValue(edgeSetFlagField); + /* Those flags needs be in sync with YogaNode.java */ + const int MARGIN = 1; + const int PADDING = 2; + const int BORDER = 4; - obj->setFieldValue(widthField, YGNodeLayoutGetWidth(root)); - obj->setFieldValue(heightField, YGNodeLayoutGetHeight(root)); - obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root)); - obj->setFieldValue(topField, YGNodeLayoutGetTop(root)); - obj->setFieldValue( - doesLegacyStretchBehaviour, - YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(root)); + int hasEdgeSetFlag = (int)obj->getFieldValue(edgeSetFlagField); - if ((hasEdgeSetFlag & MARGIN) == MARGIN) { - obj->setFieldValue( - marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft)); - obj->setFieldValue( - marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop)); - obj->setFieldValue( - marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight)); - obj->setFieldValue( - marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom)); - } + obj->setFieldValue(widthField, YGNodeLayoutGetWidth(root)); + obj->setFieldValue(heightField, YGNodeLayoutGetHeight(root)); + obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root)); + obj->setFieldValue(topField, YGNodeLayoutGetTop(root)); + obj->setFieldValue( + doesLegacyStretchBehaviour, + YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(root)); - if ((hasEdgeSetFlag & PADDING) == PADDING) { - obj->setFieldValue(paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft)); - obj->setFieldValue(paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop)); - obj->setFieldValue(paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight)); - obj->setFieldValue(paddingBottomField, YGNodeLayoutGetPadding(root, YGEdgeBottom)); - } + if ((hasEdgeSetFlag & MARGIN) == MARGIN) { + obj->setFieldValue( + marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft)); + obj->setFieldValue(marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop)); + obj->setFieldValue( + marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight)); + obj->setFieldValue( + marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom)); + } - if ((hasEdgeSetFlag & BORDER) == BORDER) { - obj->setFieldValue(borderLeftField, YGNodeLayoutGetBorder(root, YGEdgeLeft)); - obj->setFieldValue(borderTopField, YGNodeLayoutGetBorder(root, YGEdgeTop)); - obj->setFieldValue(borderRightField, YGNodeLayoutGetBorder(root, YGEdgeRight)); - obj->setFieldValue(borderBottomField, YGNodeLayoutGetBorder(root, YGEdgeBottom)); - } + if ((hasEdgeSetFlag & PADDING) == PADDING) { + obj->setFieldValue( + paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft)); + obj->setFieldValue( + paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop)); + obj->setFieldValue( + paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight)); + obj->setFieldValue( + paddingBottomField, YGNodeLayoutGetPadding(root, YGEdgeBottom)); + } - obj->setFieldValue(hasNewLayoutField, true); - YGTransferLayoutDirection(root, obj); - root->setHasNewLayout(false); + if ((hasEdgeSetFlag & BORDER) == BORDER) { + obj->setFieldValue( + borderLeftField, YGNodeLayoutGetBorder(root, YGEdgeLeft)); + obj->setFieldValue(borderTopField, YGNodeLayoutGetBorder(root, YGEdgeTop)); + obj->setFieldValue( + borderRightField, YGNodeLayoutGetBorder(root, YGEdgeRight)); + obj->setFieldValue( + borderBottomField, YGNodeLayoutGetBorder(root, YGEdgeBottom)); + } - for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) { - YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i)); - } - } else { - YGLog(root, YGLogLevelError, "Java YGNode was GCed during layout calculation\n"); - } + obj->setFieldValue(hasNewLayoutField, true); + YGTransferLayoutDirection(root, obj); + root->setHasNewLayout(false); + + for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) { + YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i)); } } @@ -128,14 +155,18 @@ static void YGPrint(YGNodeRef node) { if (auto obj = YGNodeJobject(node)->lockLocal()) { cout << obj->toString() << endl; } else { - YGLog(node, YGLogLevelError, "Java YGNode was GCed during layout calculation\n"); + YGLog( + node, + YGLogLevelError, + "Java YGNode was GCed during layout calculation\n"); } } static float YGJNIBaselineFunc(YGNodeRef node, float width, float height) { if (auto obj = YGNodeJobject(node)->lockLocal()) { - static auto baselineFunc = findClassStatic("com/facebook/yoga/YogaNode") - ->getMethod("baseline"); + static auto baselineFunc = + findClassStatic("com/facebook/yoga/YogaNode") + ->getMethod("baseline"); return baselineFunc(obj, width, height); } else { return height; @@ -150,20 +181,17 @@ static inline YGConfigRef _jlong2YGConfigRef(jlong addr) { return reinterpret_cast(static_cast(addr)); } -static YGNodeRef YGJNIOnNodeClonedFunc( - YGNodeRef oldNode, - YGNodeRef owner, - int childIndex) { +static YGNodeRef +YGJNIOnNodeClonedFunc(YGNodeRef oldNode, YGNodeRef owner, int childIndex) { auto config = oldNode->getConfig(); if (!config) { return nullptr; } - static auto onNodeClonedFunc = findClassStatic("com/facebook/yoga/YogaConfig") - ->getMethod( - local_ref, - local_ref, - jint)>("cloneNode"); + static auto onNodeClonedFunc = + findClassStatic("com/facebook/yoga/YogaConfig") + ->getMethod( + local_ref, local_ref, jint)>("cloneNode"); auto context = reinterpret_cast(YGConfigGetContext(config)); auto javaConfig = context->config; @@ -174,15 +202,12 @@ static YGNodeRef YGJNIOnNodeClonedFunc( YGNodeJobject(owner)->lockLocal(), childIndex); - static auto replaceChild = findClassStatic("com/facebook/yoga/YogaNode") - ->getMethod, - jint)>("replaceChild"); + static auto replaceChild = + findClassStatic("com/facebook/yoga/YogaNode") + ->getMethod, jint)>("replaceChild"); - jlong newNodeNativePointer = replaceChild( - YGNodeJobject(owner)->lockLocal(), - newNode, - childIndex); + jlong newNodeNativePointer = + replaceChild(YGNodeJobject(owner)->lockLocal(), newNode, childIndex); return _jlong2YGNodeRef(newNodeNativePointer); } @@ -194,24 +219,30 @@ static YGSize YGJNIMeasureFunc( float height, YGMeasureMode heightMode) { if (auto obj = YGNodeJobject(node)->lockLocal()) { - static auto measureFunc = findClassStatic("com/facebook/yoga/YogaNode") - ->getMethod("measure"); + static auto measureFunc = + findClassStatic("com/facebook/yoga/YogaNode") + ->getMethod("measure"); YGTransferLayoutDirection(node, obj); - const auto measureResult = measureFunc(obj, width, widthMode, height, heightMode); + const auto measureResult = + measureFunc(obj, width, widthMode, height, heightMode); - static_assert(sizeof(measureResult) == 8, - "Expected measureResult to be 8 bytes, or two 32 bit ints"); + static_assert( + sizeof(measureResult) == 8, + "Expected measureResult to be 8 bytes, or two 32 bit ints"); int32_t wBits = 0xFFFFFFFF & (measureResult >> 32); int32_t hBits = 0xFFFFFFFF & measureResult; - const float *measuredWidth = reinterpret_cast(&wBits); - const float *measuredHeight = reinterpret_cast(&hBits); + const float* measuredWidth = reinterpret_cast(&wBits); + const float* measuredHeight = reinterpret_cast(&hBits); return YGSize{*measuredWidth, *measuredHeight}; } else { - YGLog(node, YGLogLevelError, "Java YGNode was GCed during layout calculation\n"); + YGLog( + node, + YGLogLevelError, + "Java YGNode was GCed during layout calculation\n"); return YGSize{ widthMode == YGMeasureModeUndefined ? 0 : width, heightMode == YGMeasureModeUndefined ? 0 : height, @@ -223,24 +254,28 @@ struct JYogaLogLevel : public JavaClass { static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaLogLevel;"; }; -static int YGJNILogFunc(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args) { +static int YGJNILogFunc( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args) { int result = vsnprintf(NULL, 0, format, args); std::vector buffer(1 + result); vsnprintf(buffer.data(), buffer.size(), format, args); static auto logFunc = findClassStatic("com/facebook/yoga/YogaLogger") - ->getMethod, local_ref, jstring)>("log"); + ->getMethod, local_ref, jstring)>("log"); static auto logLevelFromInt = - JYogaLogLevel::javaClassStatic()->getStaticMethod("fromInt"); + JYogaLogLevel::javaClassStatic() + ->getStaticMethod("fromInt"); if (auto obj = YGNodeJobject(node)->lockLocal()) { - auto jlogger = reinterpret_cast *>(YGConfigGetContext(config)); + auto jlogger = + reinterpret_cast*>(YGConfigGetContext(config)); logFunc( jlogger->get(), obj, @@ -309,13 +344,19 @@ void jni_YGNodeReset(alias_ref thiz, jlong nativePointer) { void jni_YGNodePrint(alias_ref thiz, jlong nativePointer) { const YGNodeRef node = _jlong2YGNodeRef(nativePointer); - YGNodePrint(node, - (YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout | - YGPrintOptionsChildren)); + YGNodePrint( + node, + (YGPrintOptions)( + YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren)); } -void jni_YGNodeInsertChild(alias_ref, jlong nativePointer, jlong childPointer, jint index) { - YGNodeInsertChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index); +void jni_YGNodeInsertChild( + alias_ref, + jlong nativePointer, + jlong childPointer, + jint index) { + YGNodeInsertChild( + _jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index); } void jni_YGNodeInsertSharedChild( @@ -327,19 +368,25 @@ void jni_YGNodeInsertSharedChild( _jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index); } -void jni_YGNodeRemoveChild(alias_ref, jlong nativePointer, jlong childPointer) { - YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer)); +void jni_YGNodeRemoveChild( + alias_ref, + jlong nativePointer, + jlong childPointer) { + YGNodeRemoveChild( + _jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer)); } -void jni_YGNodeCalculateLayout(alias_ref, - jlong nativePointer, - jfloat width, - jfloat height) { +void jni_YGNodeCalculateLayout( + alias_ref, + jlong nativePointer, + jfloat width, + jfloat height) { const YGNodeRef root = _jlong2YGNodeRef(nativePointer); - YGNodeCalculateLayout(root, - static_cast(width), - static_cast(height), - YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer))); + YGNodeCalculateLayout( + root, + static_cast(width), + static_cast(height), + YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer))); YGTransferLayoutOutputsRecursive(root); } @@ -357,20 +404,28 @@ jboolean jni_YGNodeIsDirty(alias_ref, jlong nativePointer) { return (jboolean)_jlong2YGNodeRef(nativePointer)->isDirty(); } -void jni_YGNodeSetHasMeasureFunc(alias_ref, jlong nativePointer, jboolean hasMeasureFunc) { +void jni_YGNodeSetHasMeasureFunc( + alias_ref, + jlong nativePointer, + jboolean hasMeasureFunc) { _jlong2YGNodeRef(nativePointer) ->setMeasureFunc(hasMeasureFunc ? YGJNIMeasureFunc : nullptr); } -void jni_YGNodeSetHasBaselineFunc(alias_ref, - jlong nativePointer, - jboolean hasBaselineFunc) { +void jni_YGNodeSetHasBaselineFunc( + alias_ref, + jlong nativePointer, + jboolean hasBaselineFunc) { _jlong2YGNodeRef(nativePointer) ->setBaseLineFunc(hasBaselineFunc ? YGJNIBaselineFunc : nullptr); } -void jni_YGNodeCopyStyle(alias_ref, jlong dstNativePointer, jlong srcNativePointer) { - YGNodeCopyStyle(_jlong2YGNodeRef(dstNativePointer), _jlong2YGNodeRef(srcNativePointer)); +void jni_YGNodeCopyStyle( + alias_ref, + jlong dstNativePointer, + jlong srcNativePointer) { + YGNodeCopyStyle( + _jlong2YGNodeRef(dstNativePointer), _jlong2YGNodeRef(srcNativePointer)); } struct JYogaValue : public JavaClass { @@ -392,67 +447,76 @@ struct JYogaValue : public JavaClass { _jlong2YGNodeRef(nativePointer), static_cast(value)); \ } -#define YG_NODE_JNI_STYLE_UNIT_PROP(name) \ - local_ref jni_YGNodeStyleGet##name(alias_ref, jlong nativePointer) { \ - return JYogaValue::create(YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer))); \ - } \ - \ - void jni_YGNodeStyleSet##name(alias_ref, jlong nativePointer, jfloat value) { \ - YGNodeStyleSet##name(_jlong2YGNodeRef(nativePointer), static_cast(value)); \ - } \ - \ - void jni_YGNodeStyleSet##name##Percent(alias_ref, jlong nativePointer, jfloat value) { \ - YGNodeStyleSet##name##Percent(_jlong2YGNodeRef(nativePointer), static_cast(value)); \ +#define YG_NODE_JNI_STYLE_UNIT_PROP(name) \ + local_ref jni_YGNodeStyleGet##name( \ + alias_ref, jlong nativePointer) { \ + return JYogaValue::create( \ + YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer))); \ + } \ + \ + void jni_YGNodeStyleSet##name( \ + alias_ref, jlong nativePointer, jfloat value) { \ + YGNodeStyleSet##name( \ + _jlong2YGNodeRef(nativePointer), static_cast(value)); \ + } \ + \ + void jni_YGNodeStyleSet##name##Percent( \ + alias_ref, jlong nativePointer, jfloat value) { \ + YGNodeStyleSet##name##Percent( \ + _jlong2YGNodeRef(nativePointer), static_cast(value)); \ } -#define YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(name) \ - YG_NODE_JNI_STYLE_UNIT_PROP(name) \ - void jni_YGNodeStyleSet##name##Auto(alias_ref, jlong nativePointer) { \ - YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer)); \ +#define YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(name) \ + YG_NODE_JNI_STYLE_UNIT_PROP(name) \ + void jni_YGNodeStyleSet##name##Auto( \ + alias_ref, jlong nativePointer) { \ + YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer)); \ } -#define YG_NODE_JNI_STYLE_EDGE_PROP(javatype, type, name) \ - javatype jni_YGNodeStyleGet##name(alias_ref, jlong nativePointer, jint edge) { \ - return (javatype) YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer), \ - static_cast(edge)); \ - } \ - \ - void jni_YGNodeStyleSet##name(alias_ref, \ - jlong nativePointer, \ - jint edge, \ - javatype value) { \ - YGNodeStyleSet##name(_jlong2YGNodeRef(nativePointer), \ - static_cast(edge), \ - static_cast(value)); \ +#define YG_NODE_JNI_STYLE_EDGE_PROP(javatype, type, name) \ + javatype jni_YGNodeStyleGet##name( \ + alias_ref, jlong nativePointer, jint edge) { \ + return (javatype)YGNodeStyleGet##name( \ + _jlong2YGNodeRef(nativePointer), static_cast(edge)); \ + } \ + \ + void jni_YGNodeStyleSet##name( \ + alias_ref, jlong nativePointer, jint edge, javatype value) { \ + YGNodeStyleSet##name( \ + _jlong2YGNodeRef(nativePointer), \ + static_cast(edge), \ + static_cast(value)); \ } -#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ - local_ref jni_YGNodeStyleGet##name(alias_ref, \ - jlong nativePointer, \ - jint edge) { \ - return JYogaValue::create( \ - YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer), static_cast(edge))); \ - } \ - \ - void jni_YGNodeStyleSet##name(alias_ref, jlong nativePointer, jint edge, jfloat value) { \ - YGNodeStyleSet##name(_jlong2YGNodeRef(nativePointer), \ - static_cast(edge), \ - static_cast(value)); \ - } \ - \ - void jni_YGNodeStyleSet##name##Percent(alias_ref, \ - jlong nativePointer, \ - jint edge, \ - jfloat value) { \ - YGNodeStyleSet##name##Percent(_jlong2YGNodeRef(nativePointer), \ - static_cast(edge), \ - static_cast(value)); \ +#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ + local_ref jni_YGNodeStyleGet##name( \ + alias_ref, jlong nativePointer, jint edge) { \ + return JYogaValue::create(YGNodeStyleGet##name( \ + _jlong2YGNodeRef(nativePointer), static_cast(edge))); \ + } \ + \ + void jni_YGNodeStyleSet##name( \ + alias_ref, jlong nativePointer, jint edge, jfloat value) { \ + YGNodeStyleSet##name( \ + _jlong2YGNodeRef(nativePointer), \ + static_cast(edge), \ + static_cast(value)); \ + } \ + \ + void jni_YGNodeStyleSet##name##Percent( \ + alias_ref, jlong nativePointer, jint edge, jfloat value) { \ + YGNodeStyleSet##name##Percent( \ + _jlong2YGNodeRef(nativePointer), \ + static_cast(edge), \ + static_cast(value)); \ } -#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(name) \ - YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ - void jni_YGNodeStyleSet##name##Auto(alias_ref, jlong nativePointer, jint edge) { \ - YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer), static_cast(edge)); \ +#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(name) \ + YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ + void jni_YGNodeStyleSet##name##Auto( \ + alias_ref, jlong nativePointer, jint edge) { \ + YGNodeStyleSet##name##Auto( \ + _jlong2YGNodeRef(nativePointer), static_cast(edge)); \ } YG_NODE_JNI_STYLE_PROP(jint, YGDirection, Direction); @@ -466,8 +530,12 @@ YG_NODE_JNI_STYLE_PROP(jint, YGWrap, FlexWrap); YG_NODE_JNI_STYLE_PROP(jint, YGOverflow, Overflow); YG_NODE_JNI_STYLE_PROP(jint, YGDisplay, Display); -void jni_YGNodeStyleSetFlex(alias_ref, jlong nativePointer, jfloat value) { - YGNodeStyleSetFlex(_jlong2YGNodeRef(nativePointer), static_cast(value)); +void jni_YGNodeStyleSetFlex( + alias_ref, + jlong nativePointer, + jfloat value) { + YGNodeStyleSetFlex( + _jlong2YGNodeRef(nativePointer), static_cast(value)); } YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexGrow); YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexShrink); @@ -501,14 +569,14 @@ void jni_YGConfigFree(alias_ref, jlong nativePointer) { YGConfigFree(config); } -void jni_YGConfigSetExperimentalFeatureEnabled(alias_ref, - jlong nativePointer, - jint feature, - jboolean enabled) { +void jni_YGConfigSetExperimentalFeatureEnabled( + alias_ref, + jlong nativePointer, + jint feature, + jboolean enabled) { const YGConfigRef config = _jlong2YGConfigRef(nativePointer); - YGConfigSetExperimentalFeatureEnabled(config, - static_cast(feature), - enabled); + YGConfigSetExperimentalFeatureEnabled( + config, static_cast(feature), enabled); } void jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( @@ -519,23 +587,26 @@ void jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(config, enabled); } -void jni_YGConfigSetUseWebDefaults(alias_ref, - jlong nativePointer, - jboolean useWebDefaults) { +void jni_YGConfigSetUseWebDefaults( + alias_ref, + jlong nativePointer, + jboolean useWebDefaults) { const YGConfigRef config = _jlong2YGConfigRef(nativePointer); YGConfigSetUseWebDefaults(config, useWebDefaults); } -void jni_YGConfigSetPointScaleFactor(alias_ref, - jlong nativePointer, - jfloat pixelsInPoint) { +void jni_YGConfigSetPointScaleFactor( + alias_ref, + jlong nativePointer, + jfloat pixelsInPoint) { const YGConfigRef config = _jlong2YGConfigRef(nativePointer); YGConfigSetPointScaleFactor(config, pixelsInPoint); } -void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref, - jlong nativePointer, - jboolean useLegacyStretchBehaviour) { +void jni_YGConfigSetUseLegacyStretchBehaviour( + alias_ref, + jlong nativePointer, + jboolean useLegacyStretchBehaviour) { const YGConfigRef config = _jlong2YGConfigRef(nativePointer); YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour); } @@ -592,7 +663,7 @@ jint jni_YGNodeGetInstanceCount(alias_ref clazz) { #define YGMakeNativeMethod(name) makeNativeMethod(#name, name) -jint JNI_OnLoad(JavaVM *vm, void *) { +jint JNI_OnLoad(JavaVM* vm, void*) { return initialize(vm, [] { registerNatives( "com/facebook/yoga/YogaNode", diff --git a/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java b/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java new file mode 100644 index 00000000..8efcdd13 --- /dev/null +++ b/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java @@ -0,0 +1,983 @@ +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.yoga; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class YogaNodeStylePropertiesTest { + + private static final float UNDEFINED = YogaValue.UNDEFINED.value; + + @Test + public void testDirectionDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(node.getStyleDirection(), YogaDirection.INHERIT); + assertEquals(node.getLayoutDirection(), YogaDirection.INHERIT); + } + + @Test + public void testDirectionAssignment() { + final YogaNode node = new YogaNode(); + node.setDirection(YogaDirection.LTR); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(YogaDirection.LTR, node.getStyleDirection()); + assertEquals(YogaDirection.LTR, node.getLayoutDirection()); + } + + @Test + public void testDirectionAffectsLayout() { + final YogaNode node = + style().direction(YogaDirection.RTL).width(200).children(style().widthPercent(40)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(120, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testFlexDirectionDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaFlexDirection.COLUMN, node.getFlexDirection()); + } + + @Test + public void testFlexDirectionAssignment() { + final YogaNode node = style().flexDirection(YogaFlexDirection.COLUMN_REVERSE).node(); + + assertEquals(YogaFlexDirection.COLUMN_REVERSE, node.getFlexDirection()); + } + + @Test + public void testFlexDirectionAffectsLayout() { + final YogaNode node = + style() + .flexDirection(YogaFlexDirection.ROW_REVERSE) + .width(200) + .children(style().widthPercent(40)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(120, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testJustifyContentDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaJustify.FLEX_START, node.getJustifyContent()); + } + + @Test + public void testJustifyContentAssignment() { + final YogaNode node = new YogaNode(); + node.setJustifyContent(YogaJustify.SPACE_EVENLY); + + assertEquals(YogaJustify.SPACE_EVENLY, node.getJustifyContent()); + } + + @Test + public void testJustifyContentAffectsLayout() { + final YogaNode node = + style() + .justifyContent(YogaJustify.CENTER) + .height(200) + .children(style().heightPercent(40)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(60, node.getChildAt(0).getLayoutY(), 0); + } + + @Test + public void testAlignItemsDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaAlign.STRETCH, node.getAlignItems()); + } + + @Test + public void testAlignItemsAssignment() { + final YogaNode node = new YogaNode(); + node.setAlignItems(YogaAlign.SPACE_AROUND); + + assertEquals(YogaAlign.SPACE_AROUND, node.getAlignItems()); + } + + @Test + public void testAlignItemsAffectsLayout() { + final YogaNode node = + style().alignItems(YogaAlign.CENTER).height(200).children(style().widthPercent(40)).node(); + node.calculateLayout(200, UNDEFINED); + + assertEquals(60, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testAlignSelfDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaAlign.AUTO, node.getAlignSelf()); + } + + @Test + public void testAlignSelfAssignment() { + final YogaNode node = new YogaNode(); + node.setAlignSelf(YogaAlign.FLEX_END); + + assertEquals(YogaAlign.FLEX_END, node.getAlignSelf()); + } + + @Test + public void testAlignSelfAffectsLayout() { + final YogaNode node = + style().height(200).children(style().alignSelf(YogaAlign.CENTER).widthPercent(40)).node(); + node.calculateLayout(200, UNDEFINED); + + assertEquals(60, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testAlignContentDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaAlign.FLEX_START, node.getAlignContent()); + } + + @Test + public void testAlignContentAssignment() { + final YogaNode node = new YogaNode(); + node.setAlignContent(YogaAlign.BASELINE); + + assertEquals(YogaAlign.BASELINE, node.getAlignContent()); + } + + @Test + public void testAlignContentAffectsLayout() { + final YogaNode node = + style() + .alignContent(YogaAlign.SPACE_AROUND) + .flexWrap(YogaWrap.WRAP) + .height(200) + .width(200) + .children( + style().widthPercent(20).heightPercent(60), + style().widthPercent(20).heightPercent(60)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(30, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testPositionTypeDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaPositionType.RELATIVE, node.getPositionType()); + } + + @Test + public void testPositionTypeAssignment() { + final YogaNode node = new YogaNode(); + node.setPositionType(YogaPositionType.ABSOLUTE); + + assertEquals(YogaPositionType.ABSOLUTE, node.getPositionType()); + } + + @Test + public void testPositionTypeAffectsLayout() { + final YogaNode node = + style() + .height(200) + .children( + style().height(100), style().height(100).positionType(YogaPositionType.ABSOLUTE)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(0, node.getChildAt(1).getLayoutY(), 0); + } + + @Test + public void testWrapAffectsLayout() { + final YogaNode node = + style() + .width(200) + .height(200) + .flexWrap(YogaWrap.WRAP_REVERSE) + .children(style().width(10).heightPercent(60), style().heightPercent(60)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(190, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testOverflowDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaOverflow.VISIBLE, node.getOverflow()); + } + + @Test + public void testOverflowAssignment() { + final YogaNode node = new YogaNode(); + node.setOverflow(YogaOverflow.SCROLL); + + assertEquals(YogaOverflow.SCROLL, node.getOverflow()); + } + + // TODO add testOverflowAffectsLayout() + + @Test + public void testDisplayDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaDisplay.FLEX, node.getDisplay()); + } + + @Test + public void testDisplayAssignment() { + final YogaNode node = new YogaNode(); + node.setDisplay(YogaDisplay.NONE); + + assertEquals(YogaDisplay.NONE, node.getDisplay()); + } + + @Test + public void testDisplayAffectsLayout() { + final YogaNode node = + style().children(style().flexGrow(1).display(YogaDisplay.NONE), style().flexGrow(1)).node(); + node.calculateLayout(200, 200); + + assertEquals(200, node.getChildAt(1).getLayoutHeight(), 0); + } + + @Test + public void testFlexAffectsLayoutGrowing() { + final YogaNode node = style().height(200).children(style().height(100).flex(1.25f)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(200, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testFlexAffectsLayoutShrinking() { + final YogaNode node = style().height(200).children(style().height(300).flex(1.25f)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(200, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testFlexGrowDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(0, node.getFlexGrow(), 0); + } + + @Test + public void testFlexGrowAssignment() { + final YogaNode node = new YogaNode(); + node.setFlexGrow(2.5f); + + assertEquals(2.5f, node.getFlexGrow(), 0); + } + + @Test + public void testFlexGrowAffectsLayout() { + final YogaNode node = + style().height(200).children(style().height(50).flexGrow(1), style().height(50)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(150, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testFlexShrinkDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(0, node.getFlexShrink(), 0); + } + + @Test + public void testFlexShrinkAssignment() { + final YogaNode node = new YogaNode(); + node.setFlexShrink(2.5f); + + assertEquals(2.5f, node.getFlexShrink(), 0); + } + + @Test + public void testFlexShrinkAffectsLayout() { + final YogaNode node = + style().height(200).children(style().height(150).flexShrink(1), style().height(150)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(50, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testFlexBasisDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.AUTO, node.getFlexBasis()); + } + + @Test + public void testFlexBasisAssignment() { + final YogaNode node = new YogaNode(); + node.setFlexBasis(50); + assertEquals(new YogaValue(50, YogaUnit.POINT), node.getFlexBasis()); + + node.setFlexBasisPercent(20); + assertEquals(new YogaValue(20, YogaUnit.PERCENT), node.getFlexBasis()); + + node.setFlexBasisAuto(); + assertEquals(YogaValue.AUTO, node.getFlexBasis()); + } + + @Test + public void testFlexBasisAffectsLayout() { + final YogaNode node = + style() + .height(200) + .children(style().flexBasis(150).flexShrink(1), style().flexBasis(150).flexShrink(1)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(100, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testFlexBasisPercentAffectsLayout() { + final YogaNode node = + style() + .height(200) + .children(style().flexBasisPercent(60), style().flexBasisPercent(40)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(80, node.getChildAt(1).getLayoutHeight(), 0); + } + + @Test + public void testMarginDefault() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + assertEquals(YogaValue.UNDEFINED, node.getMargin(edge)); + } + } + + @Test + public void testMarginAssignment() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + node.setMargin(edge, 25); + assertEquals(new YogaValue(25, YogaUnit.POINT), node.getMargin(edge)); + + node.setMarginPercent(edge, 5); + assertEquals(new YogaValue(5, YogaUnit.PERCENT), node.getMargin(edge)); + + node.setMarginAuto(edge); + assertEquals(YogaValue.AUTO, node.getMargin(edge)); + } + } + + @Test + public void testMarginPointAffectsLayout() { + final YogaNode node = style().margin(YogaEdge.TOP, 42).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(42, node.getLayoutY(), 0); + } + + @Test + public void testMarginPercentAffectsLayout() { + final YogaNode node = + style().height(200).children(style().flexGrow(1).marginPercent(YogaEdge.TOP, 20)).node(); + node.calculateLayout(200, 200); + + assertEquals(40, node.getChildAt(0).getLayoutY(), 0); + } + + @Test + public void testMarginAutoAffectsLayout() { + final YogaNode node = + style() + .width(200) + .flexDirection(YogaFlexDirection.ROW) + .children(style().marginAuto(YogaEdge.LEFT).marginAuto(YogaEdge.RIGHT).width(100)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(50, node.getChildAt(0).getLayoutX(), 0); + } + + @Test + public void testPaddingDefault() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + assertEquals(YogaValue.UNDEFINED, node.getPadding(edge)); + } + } + + @Test + public void testPaddingAssignment() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + node.setPadding(edge, 25); + assertEquals(new YogaValue(25, YogaUnit.POINT), node.getPadding(edge)); + + node.setPaddingPercent(edge, 5); + assertEquals(new YogaValue(5, YogaUnit.PERCENT), node.getPadding(edge)); + } + } + + @Test + public void testPaddingPointAffectsLayout() { + final YogaNode node = style().padding(YogaEdge.TOP, 42).children(style()).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(42, node.getChildAt(0).getLayoutY(), 0); + } + + @Test + public void testPaddingPercentAffectsLayout() { + final YogaNode node = + style().height(200).paddingPercent(YogaEdge.TOP, 20).children(style().flexGrow(1)).node(); + node.calculateLayout(200, 200); + + assertEquals(40, node.getChildAt(0).getLayoutY(), 0); + } + + @Test + public void testBorderDefault() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + assertEquals(UNDEFINED, node.getBorder(edge), 0); + } + } + + @Test + public void testBorderAssignment() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + node.setBorder(edge, 2.5f); + assertEquals(2.5f, node.getBorder(edge), 0); + } + } + + @Test + public void testBorderAffectsLayout() { + final YogaNode node = style().border(YogaEdge.TOP, 42).children(style()).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(42, node.getChildAt(0).getLayoutY(), 0); + } + + @Test + public void testPositionDefault() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + assertEquals(YogaValue.UNDEFINED, node.getPosition(edge)); + } + } + + @Test + public void testPositionAssignment() { + final YogaNode node = new YogaNode(); + for (YogaEdge edge : YogaEdge.values()) { + node.setPosition(edge, 25); + assertEquals(new YogaValue(25, YogaUnit.POINT), node.getPosition(edge)); + + node.setPositionPercent(edge, 5); + assertEquals(new YogaValue(5, YogaUnit.PERCENT), node.getPosition(edge)); + } + } + + @Test + public void testPositionAffectsLayout() { + final YogaNode node = + style() + .height(100) + .children( + style() + .positionType(YogaPositionType.ABSOLUTE) + .position(YogaEdge.TOP, 11) + .position(YogaEdge.BOTTOM, 22)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(67, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testPositionPercentAffectsLayout() { + final YogaNode node = + style() + .width(100) + .children( + style() + .positionType(YogaPositionType.ABSOLUTE) + .positionPercent(YogaEdge.LEFT, 11) + .positionPercent(YogaEdge.RIGHT, 22)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(67, node.getChildAt(0).getLayoutWidth(), 0); + } + + @Test + public void testWidthDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.AUTO, node.getWidth()); + } + + @Test + public void testWidthAssignment() { + final YogaNode node = new YogaNode(); + node.setWidth(123); + assertEquals(new YogaValue(123, YogaUnit.POINT), node.getWidth()); + + node.setWidthPercent(45); + assertEquals(new YogaValue(45, YogaUnit.PERCENT), node.getWidth()); + } + + @Test + public void testWidthAffectsLayout() { + final YogaNode node = style().width(123).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(123, node.getLayoutWidth(), 0); + } + + @Test + public void testWidthPercentAffectsLayout() { + final YogaNode node = style().widthPercent(75).node(); + node.calculateLayout(200, UNDEFINED); + + assertEquals(150, node.getLayoutWidth(), 0); + } + + // TODO: testWidthAutoAffectsLayout + + @Test + public void testHeightDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.AUTO, node.getHeight()); + } + + @Test + public void testHeightAssignment() { + final YogaNode node = new YogaNode(); + node.setHeight(123); + assertEquals(new YogaValue(123, YogaUnit.POINT), node.getHeight()); + + node.setHeightPercent(45); + assertEquals(new YogaValue(45, YogaUnit.PERCENT), node.getHeight()); + } + + @Test + public void testHeightAffectsLayout() { + final YogaNode node = style().height(123).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(123, node.getLayoutHeight(), 0); + } + + @Test + public void testHeightPercentAffectsLayout() { + final YogaNode node = style().heightPercent(75).node(); + node.calculateLayout(UNDEFINED, 200); + + assertEquals(150, node.getLayoutHeight(), 0); + } + + // TODO: testHeightAutoAffectsLayout + + @Test + public void testMinWidthDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.UNDEFINED, node.getMinWidth()); + } + + @Test + public void testMinWidthAssignment() { + final YogaNode node = new YogaNode(); + node.setMinWidth(123); + assertEquals(new YogaValue(123, YogaUnit.POINT), node.getMinWidth()); + + node.setMinWidthPercent(45); + assertEquals(new YogaValue(45, YogaUnit.PERCENT), node.getMinWidth()); + } + + @Test + public void testMinWidthAffectsLayout() { + final YogaNode node = style().minWidth(123).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(123, node.getLayoutWidth(), 0); + } + + @Test + public void testMinWidthPercentAffectsLayout() { + final YogaNode node = style().minWidthPercent(120).node(); + node.calculateLayout(200, UNDEFINED); + + assertEquals(240, node.getLayoutWidth(), 0); + } + + @Test + public void testMinHeightDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.UNDEFINED, node.getMinHeight()); + } + + @Test + public void testMinHeightAssignment() { + final YogaNode node = new YogaNode(); + node.setMinHeight(123); + assertEquals(new YogaValue(123, YogaUnit.POINT), node.getMinHeight()); + + node.setMinHeightPercent(45); + assertEquals(new YogaValue(45, YogaUnit.PERCENT), node.getMinHeight()); + } + + @Test + public void testMinHeightAffectsLayout() { + final YogaNode node = style().minHeight(123).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(123, node.getLayoutHeight(), 0); + } + + @Test + public void testMinHeightPercentAffectsLayout() { + final YogaNode node = style().minHeightPercent(120).node(); + node.calculateLayout(UNDEFINED, 200); + + assertEquals(240, node.getLayoutHeight(), 0); + } + + @Test + public void testMaxWidthDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.UNDEFINED, node.getMaxWidth()); + } + + @Test + public void testMaxWidthAssignment() { + final YogaNode node = new YogaNode(); + node.setMaxWidth(123); + assertEquals(new YogaValue(123, YogaUnit.POINT), node.getMaxWidth()); + + node.setMaxWidthPercent(45); + assertEquals(new YogaValue(45, YogaUnit.PERCENT), node.getMaxWidth()); + } + + @Test + public void testMaxWidthAffectsLayout() { + final YogaNode node = style().width(200).children(style().maxWidth(123)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(123, node.getChildAt(0).getLayoutWidth(), 0); + } + + @Test + public void testMaxWidthPercentAffectsLayout() { + final YogaNode node = style().width(200).children(style().maxWidthPercent(80)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(160, node.getChildAt(0).getLayoutWidth(), 0); + } + + @Test + public void testMaxHeightDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(YogaValue.UNDEFINED, node.getMaxHeight()); + } + + @Test + public void testMaxHeightAssignment() { + final YogaNode node = new YogaNode(); + node.setMaxHeight(123); + assertEquals(new YogaValue(123, YogaUnit.POINT), node.getMaxHeight()); + + node.setMaxHeightPercent(45); + assertEquals(new YogaValue(45, YogaUnit.PERCENT), node.getMaxHeight()); + } + + @Test + public void testMaxHeightAffectsLayout() { + final YogaNode node = + style() + .height(200) + .flexDirection(YogaFlexDirection.ROW) + .children(style().maxHeight(123)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(123, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testMaxHeightPercentAffectsLayout() { + final YogaNode node = + style() + .flexDirection(YogaFlexDirection.ROW) + .height(200) + .children(style().maxHeightPercent(80)) + .node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(160, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void testAspectRatioDefault() { + final YogaNode node = new YogaNode(); + + assertEquals(UNDEFINED, node.getAspectRatio(), 0); + } + + @Test + public void testAspectRatioAssignment() { + final YogaNode node = new YogaNode(); + node.setAspectRatio(2.75f); + + assertEquals(2.75f, node.getAspectRatio(), 0); + } + + @Test + public void aspectRatioAffectsLayoutWithGivenWidth() { + final YogaNode node = style().children(style().width(300).aspectRatio(1.5f)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(200, node.getChildAt(0).getLayoutHeight(), 0); + } + + @Test + public void aspectRatioAffectsLayoutWithGivenHeight() { + final YogaNode node = style().children(style().height(300).aspectRatio(1.5f)).node(); + node.calculateLayout(UNDEFINED, UNDEFINED); + + assertEquals(450, node.getChildAt(0).getLayoutWidth(), 0); + } + + private static StyledNode style() { + return new StyledNode(); + } + + private static class StyledNode { + + private YogaNode mNode = new YogaNode(); + + YogaNode node() { + return mNode; + } + + StyledNode children(StyledNode... children) { + for (int i = mNode.getChildCount(); --i >= 0; ) { + mNode.removeChildAt(i); + } + for (int i = 0; i < children.length; i++) { + mNode.addChildAt(children[i].node(), i); + } + return this; + } + + StyledNode direction(YogaDirection direction) { + mNode.setDirection(direction); + return this; + } + + StyledNode width(float width) { + mNode.setWidth(width); + return this; + } + + StyledNode widthPercent(float width) { + mNode.setWidthPercent(width); + return this; + } + + StyledNode flexDirection(YogaFlexDirection direction) { + mNode.setFlexDirection(direction); + return this; + } + + StyledNode justifyContent(YogaJustify justify) { + mNode.setJustifyContent(justify); + return this; + } + + StyledNode height(float height) { + mNode.setHeight(height); + return this; + } + + StyledNode heightPercent(float height) { + mNode.setHeightPercent(height); + return this; + } + + StyledNode alignItems(YogaAlign align) { + mNode.setAlignItems(align); + return this; + } + + StyledNode alignSelf(YogaAlign align) { + mNode.setAlignSelf(align); + return this; + } + + StyledNode alignContent(YogaAlign align) { + mNode.setAlignContent(align); + return this; + } + + StyledNode flexWrap(YogaWrap wrap) { + mNode.setWrap(wrap); + return this; + } + + StyledNode positionType(YogaPositionType positionType) { + mNode.setPositionType(positionType); + return this; + } + + StyledNode overflow(YogaOverflow overflow) { + mNode.setOverflow(overflow); + return this; + } + + StyledNode flexShrink(float flexShrink) { + mNode.setFlexShrink(flexShrink); + return this; + } + + StyledNode display(YogaDisplay display) { + mNode.setDisplay(display); + return this; + } + + StyledNode flexGrow(float flexGrow) { + mNode.setFlexGrow(flexGrow); + return this; + } + + StyledNode flex(float flex) { + mNode.setFlex(flex); + return this; + } + + StyledNode flexBasis(float flexBasis) { + mNode.setFlexBasis(flexBasis); + return this; + } + + StyledNode flexBasisPercent(float flexBasis) { + mNode.setFlexBasisPercent(flexBasis); + return this; + } + + StyledNode margin(YogaEdge edge, float margin) { + mNode.setMargin(edge, margin); + return this; + } + + StyledNode marginPercent(YogaEdge edge, float margin) { + mNode.setMarginPercent(edge, margin); + return this; + } + + StyledNode marginAuto(YogaEdge edge) { + mNode.setMarginAuto(edge); + return this; + } + + StyledNode padding(YogaEdge edge, float padding) { + mNode.setPadding(edge, padding); + return this; + } + + StyledNode paddingPercent(YogaEdge edge, float padding) { + mNode.setPaddingPercent(edge, padding); + return this; + } + + StyledNode border(YogaEdge edge, float border) { + mNode.setBorder(edge, border); + return this; + } + + StyledNode position(YogaEdge edge, float position) { + mNode.setPosition(edge, position); + return this; + } + + StyledNode positionPercent(YogaEdge edge, float position) { + mNode.setPositionPercent(edge, position); + return this; + } + + StyledNode minWidth(float minWidth) { + mNode.setMinWidth(minWidth); + return this; + } + + StyledNode minWidthPercent(float minWidth) { + mNode.setMinWidthPercent(minWidth); + return this; + } + + StyledNode minHeight(float minHeight) { + mNode.setMinHeight(minHeight); + return this; + } + + StyledNode minHeightPercent(float minHeight) { + mNode.setMinHeightPercent(minHeight); + return this; + } + + StyledNode maxWidth(float maxWidth) { + mNode.setMaxWidth(maxWidth); + return this; + } + + StyledNode maxWidthPercent(float maxWidth) { + mNode.setMaxWidthPercent(maxWidth); + return this; + } + + StyledNode maxHeight(float maxHeight) { + mNode.setMaxHeight(maxHeight); + return this; + } + + StyledNode maxHeightPercent(float maxHeight) { + mNode.setMaxHeightPercent(maxHeight); + return this; + } + + StyledNode aspectRatio(float aspectRatio) { + mNode.setAspectRatio(aspectRatio); + return this; + } + } +} diff --git a/lib/fb/build.gradle b/lib/fb/build.gradle index 7a419b0b..fde3f88a 100644 --- a/lib/fb/build.gradle +++ b/lib/fb/build.gradle @@ -26,7 +26,7 @@ android { } dependencies { - implementation 'com.facebook.soloader:soloader:0.2.0' + implementation 'com.facebook.soloader:soloader:0.5.1' compileOnly 'com.google.code.findbugs:jsr305:3.0.1' compileOnly project(':yoga:proguard-annotations') } diff --git a/lib/soloader/BUCK b/lib/soloader/BUCK index 595c35eb..7ab9627f 100644 --- a/lib/soloader/BUCK +++ b/lib/soloader/BUCK @@ -7,6 +7,6 @@ load("//:yoga_defs.bzl", "YOGA_ROOTS") android_prebuilt_aar( name = "soloader", - aar = "soloader-0.1.0.aar", + aar = "soloader-0.5.1.aar", visibility = YOGA_ROOTS, ) diff --git a/lib/soloader/soloader-0.1.0.aar b/lib/soloader/soloader-0.1.0.aar deleted file mode 100644 index 497494a9..00000000 Binary files a/lib/soloader/soloader-0.1.0.aar and /dev/null differ diff --git a/lib/soloader/soloader-0.5.1.aar b/lib/soloader/soloader-0.5.1.aar new file mode 100644 index 00000000..eba467a7 Binary files /dev/null and b/lib/soloader/soloader-0.5.1.aar differ diff --git a/tests/YGFlexTest.cpp b/tests/YGFlexTest.cpp index e1a8ba89..388bcaca 100644 --- a/tests/YGFlexTest.cpp +++ b/tests/YGFlexTest.cpp @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexTest.html #include @@ -64,6 +64,90 @@ TEST(YogaTest, flex_basis_flex_grow_column) { YGConfigFree(config); } +TEST(YogaTest, flex_shrink_flex_grow_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 0); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 0); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetWidth(root_child1, 500); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_shrink_flex_grow_child_flex_shrink_other_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 0); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetWidth(root_child1, 500); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + TEST(YogaTest, flex_basis_flex_grow_row) { const YGConfigRef config = YGConfigNew(); diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index aea2cd59..0e599cdc 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #include #include #include diff --git a/tests/YGPersistenceTest.cpp b/tests/YGPersistenceTest.cpp index 9df861a8..d7fb98d4 100644 --- a/tests/YGPersistenceTest.cpp +++ b/tests/YGPersistenceTest.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html - #include #include diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 6fa8df82..83995221 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -1,12 +1,14 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #include "Utils.h" +using namespace facebook; + YGFlexDirection YGFlexDirectionCross( const YGFlexDirection flexDirection, const YGDirection direction) { @@ -16,18 +18,18 @@ YGFlexDirection YGFlexDirectionCross( } float YGFloatMax(const float a, const float b) { - if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { return fmaxf(a, b); } - return YGFloatIsUndefined(a) ? b : a; + return yoga::isUndefined(a) ? b : a; } float YGFloatMin(const float a, const float b) { - if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { return fminf(a, b); } - return YGFloatIsUndefined(a) ? b : a; + return yoga::isUndefined(a) ? b : a; } bool YGValueEqual(const YGValue a, const YGValue b) { @@ -36,7 +38,7 @@ bool YGValueEqual(const YGValue a, const YGValue b) { } if (a.unit == YGUnitUndefined || - (YGFloatIsUndefined(a.value) && YGFloatIsUndefined(b.value))) { + (yoga::isUndefined(a.value) && yoga::isUndefined(b.value))) { return true; } @@ -44,14 +46,14 @@ bool YGValueEqual(const YGValue a, const YGValue b) { } bool YGFloatsEqual(const float a, const float b) { - if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { return fabs(a - b) < 0.0001f; } - return YGFloatIsUndefined(a) && YGFloatIsUndefined(b); + return yoga::isUndefined(a) && yoga::isUndefined(b); } float YGFloatSanitize(const float& val) { - return YGFloatIsUndefined(val) ? 0 : val; + return yoga::isUndefined(val) ? 0 : val; } float YGUnwrapFloatOptional(const YGFloatOptional& op) { diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index 00bfc71e..cb867f3a 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -1,17 +1,20 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #include "YGFloatOptional.h" #include #include #include "Yoga.h" +#include "Yoga-internal.h" -YGFloatOptional::YGFloatOptional(const float& value) { - if (YGFloatIsUndefined(value)) { +using namespace facebook; + +YGFloatOptional::YGFloatOptional(float value) { + if (yoga::isUndefined(value)) { isUndefined_ = true; value_ = 0; } else { @@ -20,9 +23,7 @@ YGFloatOptional::YGFloatOptional(const float& value) { } } -YGFloatOptional::YGFloatOptional() : value_(0), isUndefined_(true) {} - -const float& YGFloatOptional::getValue() const { +float YGFloatOptional::getValue() const { if (isUndefined_) { // Abort, accessing a value of an undefined float optional std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; @@ -31,18 +32,9 @@ const float& YGFloatOptional::getValue() const { return value_; } -void YGFloatOptional::setValue(const float& val) { - value_ = val; - isUndefined_ = false; -} - -const bool& YGFloatOptional::isUndefined() const { - return isUndefined_; -} - bool YGFloatOptional::operator==(const YGFloatOptional& op) const { if (isUndefined_ == op.isUndefined()) { - return isUndefined_ ? true : value_ == op.getValue(); + return isUndefined_ || value_ == op.getValue(); } return false; } @@ -51,14 +43,14 @@ bool YGFloatOptional::operator!=(const YGFloatOptional& op) const { return !(*this == op); } -bool YGFloatOptional::operator==(const float& val) const { - if (YGFloatIsUndefined(val) == isUndefined_) { - return isUndefined_ ? true : val == value_; +bool YGFloatOptional::operator==(float val) const { + if (yoga::isUndefined(val) == isUndefined_) { + return isUndefined_ || val == value_; } return false; } -bool YGFloatOptional::operator!=(const float& val) const { +bool YGFloatOptional::operator!=(float val) const { return !(*this == val); } @@ -84,9 +76,9 @@ bool YGFloatOptional::operator<(const YGFloatOptional& op) const { } bool YGFloatOptional::operator>=(const YGFloatOptional& op) const { - return *this == op ? true : *this > op; + return *this == op || *this > op; } bool YGFloatOptional::operator<=(const YGFloatOptional& op) const { - return *this == op ? true : *this < op; + return *this == op || *this < op; } diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 21af2a80..114f3577 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #pragma once struct YGFloatOptional { @@ -13,18 +13,23 @@ struct YGFloatOptional { bool isUndefined_; public: - explicit YGFloatOptional(const float& value); - explicit YGFloatOptional(); + explicit YGFloatOptional(float value); + explicit YGFloatOptional() : value_(0), isUndefined_(true) {} // Program will terminate if the value of an undefined is accessed. Please // make sure to check if the optional is defined before calling this function. // To check if float optional is defined, use `isUndefined()`. - const float& getValue() const; + float getValue() const; // Sets the value of float optional, and thus isUndefined is assigned false. - void setValue(const float& val); + void setValue(float val) { + value_ = val; + isUndefined_ = false; + } - const bool& isUndefined() const; + bool isUndefined() const { + return isUndefined_; + } YGFloatOptional operator+(const YGFloatOptional& op); bool operator>(const YGFloatOptional& op) const; @@ -34,6 +39,6 @@ struct YGFloatOptional { bool operator==(const YGFloatOptional& op) const; bool operator!=(const YGFloatOptional& op) const; - bool operator==(const float& val) const; - bool operator!=(const float& val) const; + bool operator==(float val) const; + bool operator!=(float val) const; }; diff --git a/yoga/YGLayout.cpp b/yoga/YGLayout.cpp index 6e367bd5..03933ac9 100644 --- a/yoga/YGLayout.cpp +++ b/yoga/YGLayout.cpp @@ -1,13 +1,15 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #include "YGLayout.h" #include "Utils.h" +using namespace facebook; + const std::array kYGDefaultDimensionValues = { {YGUndefined, YGUndefined}}; @@ -46,20 +48,16 @@ bool YGLayout::operator==(YGLayout layout) const { isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i]; } - if (!YGFloatIsUndefined(measuredDimensions[0]) || - !YGFloatIsUndefined(layout.measuredDimensions[0])) { + if (!yoga::isUndefined(measuredDimensions[0]) || + !yoga::isUndefined(layout.measuredDimensions[0])) { isEqual = isEqual && (measuredDimensions[0] == layout.measuredDimensions[0]); } - if (!YGFloatIsUndefined(measuredDimensions[1]) || - !YGFloatIsUndefined(layout.measuredDimensions[1])) { + if (!yoga::isUndefined(measuredDimensions[1]) || + !yoga::isUndefined(layout.measuredDimensions[1])) { isEqual = isEqual && (measuredDimensions[1] == layout.measuredDimensions[1]); } return isEqual; } - -bool YGLayout::operator!=(YGLayout layout) const { - return !(*this == layout); -} diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index 46ca130d..1df905d0 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #pragma once #include "YGFloatOptional.h" #include "Yoga-internal.h" @@ -38,5 +38,7 @@ struct YGLayout { YGLayout(); bool operator==(YGLayout layout) const; - bool operator!=(YGLayout layout) const; + bool operator!=(YGLayout layout) const { + return !(*this == layout); + } }; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 289a6b2e..22316fde 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -1,93 +1,15 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #include "YGNode.h" #include #include "Utils.h" -void* YGNode::getContext() const { - return context_; -} - -YGPrintFunc YGNode::getPrintFunc() const { - return print_; -} - -bool YGNode::getHasNewLayout() const { - return hasNewLayout_; -} - -YGNodeType YGNode::getNodeType() const { - return nodeType_; -} - -YGMeasureFunc YGNode::getMeasure() const { - return measure_; -} - -YGBaselineFunc YGNode::getBaseline() const { - return baseline_; -} - -YGDirtiedFunc YGNode::getDirtied() const { - return dirtied_; -} - -YGStyle& YGNode::getStyle() { - return style_; -} - -YGLayout& YGNode::getLayout() { - return layout_; -} - -uint32_t YGNode::getLineIndex() const { - return lineIndex_; -} - -YGNodeRef YGNode::getOwner() const { - return owner_; -} - -YGNodeRef YGNode::getParent() const { - return getOwner(); -} - -YGVector YGNode::getChildren() const { - return children_; -} - -uint32_t YGNode::getChildrenCount() const { - return static_cast(children_.size()); -} - -YGNodeRef YGNode::getChild(uint32_t index) const { - return children_.at(index); -} - -YGNodeRef YGNode::getNextChild() const { - return nextChild_; -} - -YGConfigRef YGNode::getConfig() const { - return config_; -} - -bool YGNode::isDirty() const { - return isDirty_; -} - -YGValue YGNode::getResolvedDimension(int index) { - return resolvedDimensions_[index]; -} - -std::array YGNode::getResolvedDimensions() const { - return resolvedDimensions_; -} +using namespace facebook; YGFloatOptional YGNode::getLeadingPosition( const YGFlexDirection& axis, @@ -177,30 +99,6 @@ YGFloatOptional YGNode::getMarginForAxis( // Setters -void YGNode::setContext(void* context) { - context_ = context; -} - -void YGNode::setPrintFunc(YGPrintFunc printFunc) { - print_ = printFunc; -} - -void YGNode::setHasNewLayout(bool hasNewLayout) { - hasNewLayout_ = hasNewLayout; -} - -void YGNode::setNodeType(YGNodeType nodeType) { - nodeType_ = nodeType; -} - -void YGNode::setStyleFlexDirection(YGFlexDirection direction) { - style_.flexDirection = direction; -} - -void YGNode::setStyleAlignContent(YGAlign alignContent) { - style_.alignContent = alignContent; -} - void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) { if (measureFunc == nullptr) { measure_ = nullptr; @@ -221,38 +119,6 @@ void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) { measure_ = measureFunc; } -void YGNode::setBaseLineFunc(YGBaselineFunc baseLineFunc) { - baseline_ = baseLineFunc; -} - -void YGNode::setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { - dirtied_ = dirtiedFunc; -} - -void YGNode::setStyle(const YGStyle& style) { - style_ = style; -} - -void YGNode::setLayout(const YGLayout& layout) { - layout_ = layout; -} - -void YGNode::setLineIndex(uint32_t lineIndex) { - lineIndex_ = lineIndex; -} - -void YGNode::setOwner(YGNodeRef owner) { - owner_ = owner; -} - -void YGNode::setChildren(const YGVector& children) { - children_ = children; -} - -void YGNode::setNextChild(YGNodeRef nextChild) { - nextChild_ = nextChild; -} - void YGNode::replaceChild(YGNodeRef child, uint32_t index) { children_[index] = child; setChildRoot(child); @@ -268,10 +134,6 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) { setChildRoot(child); } -void YGNode::setConfig(YGConfigRef config) { - config_ = config; -} - void YGNode::setDirty(bool isDirty) { if (isDirty == isDirty_) { return; @@ -395,80 +257,6 @@ void YGNode::setPosition( trailing[crossAxis]); } -YGNode::YGNode() - : context_(nullptr), - print_(nullptr), - hasNewLayout_(true), - nodeType_(YGNodeTypeDefault), - measure_(nullptr), - baseline_(nullptr), - dirtied_(nullptr), - style_(YGStyle()), - layout_(YGLayout()), - lineIndex_(0), - owner_(nullptr), - children_(YGVector()), - nextChild_(nullptr), - config_(nullptr), - isDirty_(false), - resolvedDimensions_({{YGValueUndefined, YGValueUndefined}}) {} - -YGNode::YGNode(const YGNode& node) - : context_(node.context_), - print_(node.print_), - hasNewLayout_(node.hasNewLayout_), - nodeType_(node.nodeType_), - measure_(node.measure_), - baseline_(node.baseline_), - dirtied_(node.dirtied_), - style_(node.style_), - layout_(node.layout_), - lineIndex_(node.lineIndex_), - owner_(node.owner_), - children_(node.children_), - nextChild_(node.nextChild_), - config_(node.config_), - isDirty_(node.isDirty_), - resolvedDimensions_(node.resolvedDimensions_) {} - -YGNode::YGNode(const YGConfigRef newConfig) : YGNode() { - config_ = newConfig; -} - -YGNode::YGNode( - void* context, - YGPrintFunc print, - bool hasNewLayout, - YGNodeType nodeType, - YGMeasureFunc measure, - YGBaselineFunc baseline, - YGDirtiedFunc dirtied, - YGStyle style, - const YGLayout& layout, - uint32_t lineIndex, - YGNodeRef owner, - const YGVector& children, - YGNodeRef nextChild, - YGConfigRef config, - bool isDirty, - std::array resolvedDimensions) - : context_(context), - print_(print), - hasNewLayout_(hasNewLayout), - nodeType_(nodeType), - measure_(measure), - baseline_(baseline), - dirtied_(dirtied), - style_(style), - layout_(layout), - lineIndex_(lineIndex), - owner_(owner), - children_(children), - nextChild_(nextChild), - config_(config), - isDirty_(isDirty), - resolvedDimensions_(resolvedDimensions) {} - YGNode& YGNode::operator=(const YGNode& node) { if (&node == this) { return *this; @@ -490,7 +278,6 @@ YGNode& YGNode::operator=(const YGNode& node) { lineIndex_ = node.getLineIndex(); owner_ = node.getOwner(); children_ = node.getChildren(); - nextChild_ = node.getNextChild(); config_ = node.getConfig(); isDirty_ = node.isDirty(); resolvedDimensions_ = node.getResolvedDimensions(); @@ -542,7 +329,7 @@ void YGNode::resolveDimension() { YGDirection YGNode::resolveDirection(const YGDirection ownerDirection) { if (style_.direction == YGDirectionInherit) { return ownerDirection > YGDirectionInherit ? ownerDirection - : YGDirectionLTR; + : YGDirectionLTR; } else { return style_.direction; } @@ -553,11 +340,6 @@ void YGNode::clearChildren() { children_.shrink_to_fit(); } -YGNode::~YGNode() { - // All the member variables are deallocated externally, so no need to - // deallocate here -} - // Other Methods void YGNode::cloneChildrenIfNeeded() { @@ -648,7 +430,7 @@ bool YGNode::isNodeFlexible() { float YGNode::getLeadingBorder(const YGFlexDirection& axis) const { if (YGFlexDirectionIsRow(axis) && style_.border[YGEdgeStart].unit != YGUnitUndefined && - !YGFloatIsUndefined(style_.border[YGEdgeStart].value) && + !yoga::isUndefined(style_.border[YGEdgeStart].value) && style_.border[YGEdgeStart].value >= 0.0f) { return style_.border[YGEdgeStart].value; } @@ -661,7 +443,7 @@ float YGNode::getLeadingBorder(const YGFlexDirection& axis) const { float YGNode::getTrailingBorder(const YGFlexDirection& flexDirection) const { if (YGFlexDirectionIsRow(flexDirection) && style_.border[YGEdgeEnd].unit != YGUnitUndefined && - !YGFloatIsUndefined(style_.border[YGEdgeEnd].value) && + !yoga::isUndefined(style_.border[YGEdgeEnd].value) && style_.border[YGEdgeEnd].value >= 0.0f) { return style_.border[YGEdgeEnd].value; } diff --git a/yoga/YGNode.h b/yoga/YGNode.h index d9692c8b..6a184963 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #pragma once #include #include "YGConfig.h" @@ -14,83 +14,126 @@ struct YGNode { private: - void* context_; - YGPrintFunc print_; - bool hasNewLayout_; - YGNodeType nodeType_; - YGMeasureFunc measure_; - YGBaselineFunc baseline_; - YGDirtiedFunc dirtied_; - YGStyle style_; - YGLayout layout_; - uint32_t lineIndex_; - YGNodeRef owner_; - YGVector children_; - YGNodeRef nextChild_; - YGConfigRef config_; - bool isDirty_; - std::array resolvedDimensions_; + void* context_ = nullptr; + YGPrintFunc print_ = nullptr; + bool hasNewLayout_ = true; + YGNodeType nodeType_ = YGNodeTypeDefault; + YGMeasureFunc measure_ = nullptr; + YGBaselineFunc baseline_ = nullptr; + YGDirtiedFunc dirtied_ = nullptr; + YGStyle style_ = {}; + YGLayout layout_ = {}; + uint32_t lineIndex_ = 0; + YGNodeRef owner_ = nullptr; + YGVector children_ = {}; + YGConfigRef config_ = nullptr; + bool isDirty_ = false; + std::array resolvedDimensions_ = { + {YGValueUndefined, YGValueUndefined}}; YGFloatOptional relativePosition( const YGFlexDirection& axis, const float& axisSize) const; public: - YGNode(); - ~YGNode(); - explicit YGNode(const YGConfigRef newConfig); - YGNode(const YGNode& node); + YGNode() = default; + ~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree + explicit YGNode(const YGConfigRef newConfig) : config_(newConfig){}; + YGNode(const YGNode& node) = default; YGNode& operator=(const YGNode& node); - YGNode( - void* context, - YGPrintFunc print, - bool hasNewLayout, - YGNodeType nodeType, - YGMeasureFunc measure, - YGBaselineFunc baseline, - YGDirtiedFunc dirtied, - YGStyle style, - const YGLayout& layout, - uint32_t lineIndex, - YGNodeRef owner, - const YGVector& children, - YGNodeRef nextChild, - YGConfigRef config, - bool isDirty, - std::array resolvedDimensions); // Getters - void* getContext() const; - YGPrintFunc getPrintFunc() const; - bool getHasNewLayout() const; - YGNodeType getNodeType() const; - YGMeasureFunc getMeasure() const; - YGBaselineFunc getBaseline() const; - YGDirtiedFunc getDirtied() const; + void* getContext() const { + return context_; + } + + YGPrintFunc getPrintFunc() const { + return print_; + } + + bool getHasNewLayout() const { + return hasNewLayout_; + } + + YGNodeType getNodeType() const { + return nodeType_; + } + + YGMeasureFunc getMeasure() const { + return measure_; + } + + YGBaselineFunc getBaseline() const { + return baseline_; + } + + YGDirtiedFunc getDirtied() const { + return dirtied_; + } + // For Performance reasons passing as reference. - YGStyle& getStyle(); + YGStyle& getStyle() { + return style_; + } + + const YGStyle& getStyle() const { + return style_; + } + // For Performance reasons passing as reference. - YGLayout& getLayout(); - uint32_t getLineIndex() const; + YGLayout& getLayout() { + return layout_; + } + + const YGLayout& getLayout() const { + return layout_; + } + + uint32_t getLineIndex() const { + return lineIndex_; + } + // returns the YGNodeRef that owns this YGNode. An owner is used to identify // the YogaTree that a YGNode belongs to. // This method will return the parent of the YGNode when a YGNode only belongs // to one YogaTree or nullptr when the YGNode is shared between two or more // YogaTrees. - YGNodeRef getOwner() const; + YGNodeRef getOwner() const { + return owner_; + } + // Deprecated, use getOwner() instead. - YGNodeRef getParent() const; - YGVector getChildren() const; - uint32_t getChildrenCount() const; - YGNodeRef getChild(uint32_t index) const; - YGNodeRef getNextChild() const; - YGConfigRef getConfig() const; - bool isDirty() const; - std::array getResolvedDimensions() const; - YGValue getResolvedDimension(int index); + YGNodeRef getParent() const { + return getOwner(); + } + + const YGVector& getChildren() const { + return children_; + } + + YGNodeRef getChild(uint32_t index) const { + return children_.at(index); + } + + YGConfigRef getConfig() const { + return config_; + } + + bool isDirty() const { + return isDirty_; + } + + std::array getResolvedDimensions() const { + return resolvedDimensions_; + } + + YGValue getResolvedDimension(int index) const { + return resolvedDimensions_[index]; + } // Methods related to positions, margin, padding and border - YGFloatOptional getLeadingPosition(const YGFlexDirection& axis, + YGFloatOptional getLeadingPosition( + const YGFlexDirection& axis, const float& axisSize) const; bool isLeadingPositionDefined(const YGFlexDirection& axis) const; bool isTrailingPosDefined(const YGFlexDirection& axis) const; @@ -122,22 +165,66 @@ struct YGNode { const float& widthSize) const; // Setters - void setContext(void* context); - void setPrintFunc(YGPrintFunc printFunc); - void setHasNewLayout(bool hasNewLayout); - void setNodeType(YGNodeType nodeTye); + void setContext(void* context) { + context_ = context; + } + + void setPrintFunc(YGPrintFunc printFunc) { + print_ = printFunc; + } + + void setHasNewLayout(bool hasNewLayout) { + hasNewLayout_ = hasNewLayout; + } + + void setNodeType(YGNodeType nodeType) { + nodeType_ = nodeType; + } + + void setStyleFlexDirection(YGFlexDirection direction) { + style_.flexDirection = direction; + } + + void setStyleAlignContent(YGAlign alignContent) { + style_.alignContent = alignContent; + } + void setMeasureFunc(YGMeasureFunc measureFunc); - void setBaseLineFunc(YGBaselineFunc baseLineFunc); - void setDirtiedFunc(YGDirtiedFunc dirtiedFunc); - void setStyle(const YGStyle& style); - void setStyleFlexDirection(YGFlexDirection direction); - void setStyleAlignContent(YGAlign alignContent); - void setLayout(const YGLayout& layout); - void setLineIndex(uint32_t lineIndex); - void setOwner(YGNodeRef owner); - void setChildren(const YGVector& children); - void setNextChild(YGNodeRef nextChild); - void setConfig(YGConfigRef config); + + void setBaseLineFunc(YGBaselineFunc baseLineFunc) { + baseline_ = baseLineFunc; + } + + void setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { + dirtied_ = dirtiedFunc; + } + + void setStyle(const YGStyle& style) { + style_ = style; + } + + void setLayout(const YGLayout& layout) { + layout_ = layout; + } + + void setLineIndex(uint32_t lineIndex) { + lineIndex_ = lineIndex; + } + + void setOwner(YGNodeRef owner) { + owner_ = owner; + } + + void setChildren(const YGVector& children) { + children_ = children; + } + + // TODO: rvalue override for setChildren + + void setConfig(YGConfigRef config) { + config_ = config; + } + void setDirty(bool isDirty); void setLayoutLastOwnerDirection(YGDirection direction); void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis); diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp index 7664dcf8..06d0f2a4 100644 --- a/yoga/YGStyle.cpp +++ b/yoga/YGStyle.cpp @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #include "YGStyle.h" const YGValue kYGValueUndefined = {0, YGUnitUndefined}; @@ -98,9 +98,3 @@ bool YGStyle::operator==(const YGStyle& style) { return areNonFloatValuesEqual; } - -bool YGStyle::operator!=(YGStyle style) { - return !(*this == style); -} - -YGStyle::~YGStyle() {} diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index f0f97bd8..3f4bbd34 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #pragma once #include "YGFloatOptional.h" #include "Yoga-internal.h" @@ -32,12 +32,14 @@ struct YGStyle { std::array dimensions; std::array minDimensions; std::array maxDimensions; + // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio; YGStyle(); - // Yoga specific properties, not compatible with flexbox specification bool operator==(const YGStyle& style); - bool operator!=(YGStyle style); - ~YGStyle(); + bool operator!=(YGStyle style) { + return !(*this == style); + } + ~YGStyle() = default; }; diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index be1d9632..941147e8 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #pragma once #include #include @@ -16,13 +16,34 @@ using YGVector = std::vector; YG_EXTERN_C_BEGIN -WIN_EXPORT float YGRoundValueToPixelGrid(const float value, - const float pointScaleFactor, - const bool forceCeil, - const bool forceFloor); +WIN_EXPORT float YGRoundValueToPixelGrid( + const float value, + const float pointScaleFactor, + const bool forceCeil, + const bool forceFloor); YG_EXTERN_C_END +namespace facebook { +namespace yoga { + +inline bool isUndefined(float value) { + // Value of a float in the case of it being not defined is 10.1E20. Earlier + // it used to be NAN, the benefit of which was that if NAN is involved in any + // mathematical expression the result was NAN. But since we want to have + // `-ffast-math` flag being used by compiler which assumes that the floating + // point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But + // now if YGUndefined is involved in any mathematical operations this + // value(10.1E20) would change. So the following check makes sure that if the + // value is outside a range (-10E8, 10E8) then it is undefined. + return value >= 10E8 || value <= -10E8; +} + +} // namespace yoga +} // namespace facebook + +using namespace facebook; + extern const std::array trailing; extern const std::array leading; extern bool YGValueEqual(const YGValue a, const YGValue b); @@ -62,20 +83,20 @@ struct YGCachedMeasurement { bool isEqual = widthMeasureMode == measurement.widthMeasureMode && heightMeasureMode == measurement.heightMeasureMode; - if (!YGFloatIsUndefined(availableWidth) || - !YGFloatIsUndefined(measurement.availableWidth)) { + if (!yoga::isUndefined(availableWidth) || + !yoga::isUndefined(measurement.availableWidth)) { isEqual = isEqual && availableWidth == measurement.availableWidth; } - if (!YGFloatIsUndefined(availableHeight) || - !YGFloatIsUndefined(measurement.availableHeight)) { + if (!yoga::isUndefined(availableHeight) || + !yoga::isUndefined(measurement.availableHeight)) { isEqual = isEqual && availableHeight == measurement.availableHeight; } - if (!YGFloatIsUndefined(computedWidth) || - !YGFloatIsUndefined(measurement.computedWidth)) { + if (!yoga::isUndefined(computedWidth) || + !yoga::isUndefined(measurement.computedWidth)) { isEqual = isEqual && computedWidth == measurement.computedWidth; } - if (!YGFloatIsUndefined(computedHeight) || - !YGFloatIsUndefined(measurement.computedHeight)) { + if (!yoga::isUndefined(computedHeight) || + !yoga::isUndefined(measurement.computedHeight)) { isEqual = isEqual && computedHeight == measurement.computedHeight; } @@ -87,7 +108,6 @@ struct YGCachedMeasurement { // layouts should not require more than 16 entries to fit within the cache. #define YG_MAX_CACHED_RESULT_COUNT 16 - static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexShrink = 0.0f; static const float kWebDefaultFlexShrink = 1.0f; diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index feb71c80..a59d640d 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -30,30 +30,46 @@ __forceinline const float fmaxf(const float a, const float b) { #endif #ifdef ANDROID -static int YGAndroidLog(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args); +static int YGAndroidLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args); #else -static int YGDefaultLog(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args); +static int YGDefaultLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args); #endif const YGValue YGValueZero = {0, YGUnitPoint}; const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; +bool operator==(const YGValue& lhs, const YGValue& rhs) { + if ((lhs.unit == YGUnitUndefined && rhs.unit == YGUnitUndefined) || + (lhs.unit == YGUnitAuto && rhs.unit == YGUnitAuto)) { + return true; + } + + return lhs.unit == rhs.unit && lhs.value == rhs.value; +} + +bool operator!=(const YGValue& lhs, const YGValue& rhs) { + return !(lhs == rhs); +} + #ifdef ANDROID #include -static int YGAndroidLog(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args) { +static int YGAndroidLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args) { int androidLevel = YGLogLevelDebug; switch (level) { case YGLogLevelFatal: @@ -81,11 +97,12 @@ static int YGAndroidLog(const YGConfigRef config, #else #define YG_UNUSED(x) (void)(x); -static int YGDefaultLog(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args) { +static int YGDefaultLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args) { YG_UNUSED(config); YG_UNUSED(node); switch (level) { @@ -105,15 +122,7 @@ static int YGDefaultLog(const YGConfigRef config, #endif bool YGFloatIsUndefined(const float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier - // it used to be NAN, the benefit of which was that if NAN is involved in any - // mathematical expression the result was NAN. But since we want to have - // `-ffast-math` flag being used by compiler which assumes that the floating - // point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But - // now if YGUndefined is involved in any mathematical operations this - // value(10.1E20) would change. So the following check makes sure that if the - // value is outside a range (-10E8, 10E8) then it is undefined. - return value >= 10E8 || value <= -10E8; + return facebook::yoga::isUndefined(value); } const YGValue* YGComputedEdgeValue( @@ -129,7 +138,8 @@ const YGValue* YGComputedEdgeValue( return &edges[YGEdgeVertical]; } - if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart || edge == YGEdgeEnd) && + if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart || + edge == YGEdgeEnd) && edges[YGEdgeHorizontal].unit != YGUnitUndefined) { return &edges[YGEdgeHorizontal]; } @@ -266,7 +276,7 @@ static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) { YGVector vec = YGVector(); vec.reserve(oldNode->getChildren().size()); YGNodeRef childNode = nullptr; - for (auto& item : oldNode->getChildren()) { + for (auto* item : oldNode->getChildren()) { childNode = YGNodeDeepClone(item); childNode->setOwner(node); vec.push_back(childNode); @@ -277,10 +287,6 @@ static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) { node->setConfig(YGConfigClone(*(oldNode->getConfig()))); } - if (oldNode->getNextChild() != nullptr) { - node->setNextChild(YGNodeDeepClone(oldNode->getNextChild())); - } - return node; } @@ -307,8 +313,8 @@ static void YGConfigFreeRecursive(const YGNodeRef root) { gConfigInstanceCount--; } // Delete configs recursively for childrens - for (uint32_t i = 0; i < root->getChildrenCount(); ++i) { - YGConfigFreeRecursive(root->getChild(i)); + for (auto* child : root->getChildren()) { + YGConfigFreeRecursive(child); } } @@ -326,9 +332,10 @@ void YGNodeFreeRecursive(const YGNodeRef root) { } void YGNodeReset(const YGNodeRef node) { - YGAssertWithNode(node, - YGNodeGetChildCount(node) == 0, - "Cannot reset a node which still has children attached"); + YGAssertWithNode( + node, + YGNodeGetChildCount(node) == 0, + "Cannot reset a node which still has children attached"); YGAssertWithNode( node, node->getOwner() == nullptr, @@ -354,11 +361,11 @@ int32_t YGConfigGetInstanceCount(void) { } YGConfigRef YGConfigNew(void) { - #ifdef ANDROID +#ifdef ANDROID const YGConfigRef config = new YGConfig(YGAndroidLog); - #else +#else const YGConfigRef config = new YGConfig(YGDefaultLog); - #endif +#endif gConfigInstanceCount++; return config; } @@ -372,7 +379,10 @@ void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) { memcpy(dest, src, sizeof(YGConfig)); } -void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) { +void YGNodeInsertChild( + const YGNodeRef node, + const YGNodeRef child, + const uint32_t index) { YGAssertWithNode( node, child->getOwner() == nullptr, @@ -415,8 +425,8 @@ void YGNodeRemoveChild(const YGNodeRef owner, const YGNodeRef excludedChild) { } const YGNodeRef firstChild = YGNodeGetChild(owner, 0); if (firstChild->getOwner() == owner) { - // If the first child has this node as its owner, we assume that it is already unique. - // We can now try to delete a child in this list. + // If the first child has this node as its owner, we assume that it is + // already unique. We can now try to delete a child in this list. if (owner->removeChild(excludedChild)) { excludedChild->setLayout( YGNode().getLayout()); // layout is no longer valid @@ -425,18 +435,18 @@ void YGNodeRemoveChild(const YGNodeRef owner, const YGNodeRef excludedChild) { } return; } - // Otherwise we have to clone the node list except for the child we're trying to delete. - // We don't want to simply clone all children, because then the host will need to free - // the clone of the child that was just deleted. + // Otherwise we have to clone the node list except for the child we're trying + // to delete. We don't want to simply clone all children, because then the + // host will need to free the clone of the child that was just deleted. const YGCloneNodeFunc cloneNodeCallback = owner->getConfig()->cloneNodeCallback; uint32_t nextInsertIndex = 0; for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef oldChild = owner->getChild(i); if (excludedChild == oldChild) { - // Ignore the deleted child. Don't reset its layout or owner since it is still valid - // in the other owner. However, since this owner has now changed, we need to mark it - // as dirty. + // Ignore the deleted child. Don't reset its layout or owner since it is + // still valid in the other owner. However, since this owner has now + // changed, we need to mark it as dirty. owner->markDirtyAndPropogate(); continue; } @@ -466,7 +476,8 @@ void YGNodeRemoveAllChildren(const YGNodeRef owner) { } const YGNodeRef firstChild = YGNodeGetChild(owner, 0); if (firstChild->getOwner() == owner) { - // If the first child has this node as its owner, we assume that this child set is unique. + // If the first child has this node as its owner, we assume that this child + // set is unique. for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef oldChild = YGNodeGetChild(owner, i); oldChild->setLayout(YGNode().getLayout()); // layout is no longer valid @@ -476,13 +487,15 @@ void YGNodeRemoveAllChildren(const YGNodeRef owner) { owner->markDirtyAndPropogate(); return; } - // Otherwise, we are not the owner of the child set. We don't have to do anything to clear it. + // Otherwise, we are not the owner of the child set. We don't have to do + // anything to clear it. owner->setChildren(YGVector()); owner->markDirtyAndPropogate(); } -static void YGNodeSetChildrenInternal(YGNodeRef const owner, const std::vector &children) -{ +static void YGNodeSetChildrenInternal( + YGNodeRef const owner, + const std::vector& children) { if (!owner) { return; } @@ -498,8 +511,10 @@ static void YGNodeSetChildrenInternal(YGNodeRef const owner, const std::vector 0) { for (YGNodeRef const oldChild : owner->getChildren()) { - // Our new children may have nodes in common with the old children. We don't reset these common nodes. - if (std::find(children.begin(), children.end(), oldChild) == children.end()) { + // Our new children may have nodes in common with the old children. We + // don't reset these common nodes. + if (std::find(children.begin(), children.end(), oldChild) == + children.end()) { oldChild->setLayout(YGLayout()); oldChild->setOwner(nullptr); } @@ -513,13 +528,17 @@ static void YGNodeSetChildrenInternal(YGNodeRef const owner, const std::vector &children) -{ +void YGNodeSetChildren( + YGNodeRef const owner, + const std::vector& children) { YGNodeSetChildrenInternal(owner, children); } @@ -572,16 +591,24 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) { : node->getStyle().flexShrink.getValue(); } -#define YG_NODE_STYLE_PROPERTY_SETTER_IMPL( \ - type, name, paramName, instanceName) \ - void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ - if (node->getStyle().instanceName != paramName) { \ - YGStyle style = node->getStyle(); \ - style.instanceName = paramName; \ - node->setStyle(style); \ - node->markDirtyAndPropogate(); \ - } \ +namespace { + +template +struct StyleProp { + static T get(YGNodeRef node) { + return node->getStyle().*P; } + static void set(YGNodeRef node, T newValue) { + if (node->getStyle().*P != newValue) { + YGStyle style = node->getStyle(); + style.*P = newValue; + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } +}; + +} // namespace #define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_IMPL( \ type, name, paramName, instanceName) \ @@ -657,13 +684,6 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) { } \ } -#define YG_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \ - YG_NODE_STYLE_PROPERTY_SETTER_IMPL(type, name, paramName, instanceName) \ - \ - type YGNodeStyleGet##name(const YGNodeRef node) { \ - return node->getStyle().instanceName; \ - } - #define YG_NODE_STYLE_PROPERTY_UNIT_IMPL(type, name, paramName, instanceName) \ YG_NODE_STYLE_PROPERTY_SETTER_UNIT_IMPL( \ float, name, paramName, instanceName) \ @@ -774,21 +794,85 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) { return node->getLayout().instanceName[edge]; \ } -// YG_NODE_PROPERTY_IMPL(void *, Context, context, context); -// YG_NODE_PROPERTY_IMPL(YGPrintFunc, PrintFunc, printFunc, print); -// YG_NODE_PROPERTY_IMPL(bool, HasNewLayout, hasNewLayout, hasNewLayout); -// YG_NODE_PROPERTY_IMPL(YGNodeType, NodeType, nodeType, nodeType); +void YGNodeStyleSetDirection( + const YGNodeRef node, + const YGDirection direction) { + StyleProp::set(node, direction); +} +YGDirection YGNodeStyleGetDirection(const YGNodeRef node) { + return StyleProp::get(node); +} -YG_NODE_STYLE_PROPERTY_IMPL(YGDirection, Direction, direction, direction); -YG_NODE_STYLE_PROPERTY_IMPL(YGFlexDirection, FlexDirection, flexDirection, flexDirection); -YG_NODE_STYLE_PROPERTY_IMPL(YGJustify, JustifyContent, justifyContent, justifyContent); -YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignContent, alignContent, alignContent); -YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignItems, alignItems, alignItems); -YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignSelf, alignSelf, alignSelf); -YG_NODE_STYLE_PROPERTY_IMPL(YGPositionType, PositionType, positionType, positionType); -YG_NODE_STYLE_PROPERTY_IMPL(YGWrap, FlexWrap, flexWrap, flexWrap); -YG_NODE_STYLE_PROPERTY_IMPL(YGOverflow, Overflow, overflow, overflow); -YG_NODE_STYLE_PROPERTY_IMPL(YGDisplay, Display, display, display); +void YGNodeStyleSetFlexDirection( + const YGNodeRef node, + const YGFlexDirection flexDirection) { + StyleProp::set(node, flexDirection); +} +YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetJustifyContent( + const YGNodeRef node, + const YGJustify justifyContent) { + StyleProp::set(node, justifyContent); +} +YGJustify YGNodeStyleGetJustifyContent(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetAlignContent( + const YGNodeRef node, + const YGAlign alignContent) { + StyleProp::set(node, alignContent); +} +YGAlign YGNodeStyleGetAlignContent(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) { + StyleProp::set(node, alignItems); +} +YGAlign YGNodeStyleGetAlignItems(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) { + StyleProp::set(node, alignSelf); +} +YGAlign YGNodeStyleGetAlignSelf(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetPositionType( + const YGNodeRef node, + const YGPositionType positionType) { + StyleProp::set(node, positionType); +} +YGPositionType YGNodeStyleGetPositionType(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) { + StyleProp::set(node, flexWrap); +} +YGWrap YGNodeStyleGetFlexWrap(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) { + StyleProp::set(node, overflow); +} +YGOverflow YGNodeStyleGetOverflow(const YGNodeRef node) { + return StyleProp::get(node); +} + +void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) { + StyleProp::set(node, display); +} +YGDisplay YGNodeStyleGetDisplay(const YGNodeRef node) { + return StyleProp::get(node); +} // TODO(T26792433): Change the API to accept YGFloatOptional. void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { @@ -939,12 +1023,36 @@ void YGNodeStyleSetAspectRatio(const YGNodeRef node, const float aspectRatio) { } } -YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Width, width, dimensions[YGDimensionWidth]); -YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Height, height, dimensions[YGDimensionHeight]); -YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MinWidth, minWidth, minDimensions[YGDimensionWidth]); -YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MinHeight, minHeight, minDimensions[YGDimensionHeight]); -YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MaxWidth, maxWidth, maxDimensions[YGDimensionWidth]); -YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MaxHeight, maxHeight, maxDimensions[YGDimensionHeight]); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL( + YGValue, + Width, + width, + dimensions[YGDimensionWidth]); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL( + YGValue, + Height, + height, + dimensions[YGDimensionHeight]); +YG_NODE_STYLE_PROPERTY_UNIT_IMPL( + YGValue, + MinWidth, + minWidth, + minDimensions[YGDimensionWidth]); +YG_NODE_STYLE_PROPERTY_UNIT_IMPL( + YGValue, + MinHeight, + minHeight, + minDimensions[YGDimensionHeight]); +YG_NODE_STYLE_PROPERTY_UNIT_IMPL( + YGValue, + MaxWidth, + maxWidth, + maxDimensions[YGDimensionWidth]); +YG_NODE_STYLE_PROPERTY_UNIT_IMPL( + YGValue, + MaxHeight, + maxHeight, + maxDimensions[YGDimensionHeight]); YG_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[YGEdgeLeft]); YG_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[YGEdgeTop]); YG_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[YGEdgeRight]); @@ -962,20 +1070,22 @@ bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node) { return node->getLayout().doesLegacyStretchFlagAffectsLayout; } -bool YGLayoutNodeInternal(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const float ownerWidth, - const float ownerHeight, - const bool performLayout, - const char *reason, - const YGConfigRef config); +bool YGLayoutNodeInternal( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const char* reason, + const YGConfigRef config); -static void YGNodePrintInternal(const YGNodeRef node, - const YGPrintOptions options) { +static void YGNodePrintInternal( + const YGNodeRef node, + const YGPrintOptions options) { std::string str; facebook::yoga::YGNodeToString(&str, node, options, 0); YGLog(node, YGLogLevelDebug, str.c_str()); @@ -1000,15 +1110,18 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { +static inline float YGNodePaddingAndBorderForAxis( + const YGNodeRef node, + const YGFlexDirection axis, + const float widthSize) { return YGUnwrapFloatOptional( node->getLeadingPaddingAndBorder(axis, widthSize) + node->getTrailingPaddingAndBorder(axis, widthSize)); } -static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef child) { +static inline YGAlign YGNodeAlignItem( + const YGNodeRef node, + const YGNodeRef child) { const YGAlign align = child->getStyle().alignSelf == YGAlignAuto ? node->getStyle().alignItems : child->getStyle().alignSelf; @@ -1025,9 +1138,10 @@ static float YGBaseline(const YGNodeRef node) { node, node->getLayout().measuredDimensions[YGDimensionWidth], node->getLayout().measuredDimensions[YGDimensionHeight]); - YGAssertWithNode(node, - !YGFloatIsUndefined(baseline), - "Expect custom baseline function to not return NaN"); + YGAssertWithNode( + node, + !YGFloatIsUndefined(baseline), + "Expect custom baseline function to not return NaN"); return baseline; } @@ -1078,18 +1192,20 @@ static bool YGIsBaselineLayout(const YGNodeRef node) { return false; } -static inline float YGNodeDimWithMargin(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { +static inline float YGNodeDimWithMargin( + const YGNodeRef node, + const YGFlexDirection axis, + const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + YGUnwrapFloatOptional( node->getLeadingMargin(axis, widthSize) + node->getTrailingMargin(axis, widthSize)); } -static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, - const YGFlexDirection axis, - const float ownerSize) { +static inline bool YGNodeIsStyleDimDefined( + const YGNodeRef node, + const YGFlexDirection axis, + const float ownerSize) { bool isUndefined = YGFloatIsUndefined(node->getResolvedDimension(dim[axis]).value); return !( @@ -1103,7 +1219,9 @@ static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, YGFloatIsUndefined(ownerSize)))); } -static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDirection axis) { +static inline bool YGNodeIsLayoutDimDefined( + const YGNodeRef node, + const YGFlexDirection axis) { const float value = node->getLayout().measuredDimensions[dim[axis]]; return !YGFloatIsUndefined(value) && value >= 0.0f; } @@ -1139,23 +1257,24 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( return YGFloatOptional(value); } -// Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't go -// below the -// padding and border amount. -static inline float YGNodeBoundAxis(const YGNodeRef node, - const YGFlexDirection axis, - const float value, - const float axisSize, - const float widthSize) { +// Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't +// go below the padding and border amount. +static inline float YGNodeBoundAxis( + const YGNodeRef node, + const YGFlexDirection axis, + const float value, + const float axisSize, + const float widthSize) { return YGFloatMax( YGUnwrapFloatOptional( YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)), YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } -static void YGNodeSetChildTrailingPosition(const YGNodeRef node, - const YGNodeRef child, - const YGFlexDirection axis) { +static void YGNodeSetChildTrailingPosition( + const YGNodeRef node, + const YGNodeRef child, + const YGFlexDirection axis) { const float size = child->getLayout().measuredDimensions[dim[axis]]; child->setLayoutPosition( node->getLayout().measuredDimensions[dim[axis]] - size - @@ -1163,15 +1282,15 @@ static void YGNodeSetChildTrailingPosition(const YGNodeRef node, trailing[axis]); } -static void YGConstrainMaxSizeForMode(const YGNodeRef node, - const enum YGFlexDirection axis, - const float ownerAxisSize, - const float ownerWidth, - YGMeasureMode *mode, - float *size) { +static void YGConstrainMaxSizeForMode( + const YGNodeRef node, + const enum YGFlexDirection axis, + const float ownerAxisSize, + const float ownerWidth, + YGMeasureMode* mode, + float* size) { const YGFloatOptional maxSize = - YGResolveValue( - node->getStyle().maxDimensions[dim[axis]], ownerAxisSize) + + YGResolveValue(node->getStyle().maxDimensions[dim[axis]], ownerAxisSize) + YGFloatOptional(node->getMarginForAxis(axis, ownerWidth)); switch (*mode) { case YGMeasureModeExactly: @@ -1189,16 +1308,17 @@ static void YGConstrainMaxSizeForMode(const YGNodeRef node, } } -static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, - const YGNodeRef child, - const float width, - const YGMeasureMode widthMode, - const float height, - const float ownerWidth, - const float ownerHeight, - const YGMeasureMode heightMode, - const YGDirection direction, - const YGConfigRef config) { +static void YGNodeComputeFlexBasisForChild( + const YGNodeRef node, + const YGNodeRef child, + const float width, + const YGMeasureMode widthMode, + const float height, + const float ownerWidth, + const float ownerHeight, + const YGMeasureMode heightMode, + const YGDirection direction, + const YGConfigRef config) { const YGFlexDirection mainAxis = YGResolveFlexDirection(node->getStyle().flexDirection, direction); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); @@ -1212,7 +1332,8 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, const YGFloatOptional resolvedFlexBasis = YGResolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); - const bool isRowStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth); + const bool isRowStyleDimDefined = + YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth); const bool isColumnStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, ownerHeight); @@ -1252,9 +1373,9 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, childWidthMeasureMode = YGMeasureModeUndefined; childHeightMeasureMode = YGMeasureModeUndefined; - const float& marginRow = YGUnwrapFloatOptional( + auto marginRow = YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float& marginColumn = YGUnwrapFloatOptional( + auto marginColumn = YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); if (isRowStyleDimDefined) { @@ -1295,7 +1416,8 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, childHeight = marginColumn + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); childHeightMeasureMode = YGMeasureModeExactly; - } else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { + } else if ( + isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { childWidth = marginRow + (childHeight - marginColumn) * child->getStyle().aspectRatio.getValue(); @@ -1307,10 +1429,13 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, // set the cross // axis to be measured exactly with the available inner width - const bool hasExactWidth = !YGFloatIsUndefined(width) && widthMode == YGMeasureModeExactly; - const bool childWidthStretch = YGNodeAlignItem(node, child) == YGAlignStretch && - childWidthMeasureMode != YGMeasureModeExactly; - if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth && childWidthStretch) { + const bool hasExactWidth = + !YGFloatIsUndefined(width) && widthMode == YGMeasureModeExactly; + const bool childWidthStretch = + YGNodeAlignItem(node, child) == YGAlignStretch && + childWidthMeasureMode != YGMeasureModeExactly; + if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth && + childWidthStretch) { childWidth = width; childWidthMeasureMode = YGMeasureModeExactly; if (!child->getStyle().aspectRatio.isUndefined()) { @@ -1320,10 +1445,13 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, } } - const bool hasExactHeight = !YGFloatIsUndefined(height) && heightMode == YGMeasureModeExactly; - const bool childHeightStretch = YGNodeAlignItem(node, child) == YGAlignStretch && - childHeightMeasureMode != YGMeasureModeExactly; - if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight && childHeightStretch) { + const bool hasExactHeight = + !YGFloatIsUndefined(height) && heightMode == YGMeasureModeExactly; + const bool childHeightStretch = + YGNodeAlignItem(node, child) == YGAlignStretch && + childHeightMeasureMode != YGMeasureModeExactly; + if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight && + childHeightStretch) { childHeight = height; childHeightMeasureMode = YGMeasureModeExactly; @@ -1335,26 +1463,33 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, } YGConstrainMaxSizeForMode( - child, YGFlexDirectionRow, ownerWidth, ownerWidth, &childWidthMeasureMode, &childWidth); - YGConstrainMaxSizeForMode(child, - YGFlexDirectionColumn, - ownerHeight, - ownerWidth, - &childHeightMeasureMode, - &childHeight); + child, + YGFlexDirectionRow, + ownerWidth, + ownerWidth, + &childWidthMeasureMode, + &childWidth); + YGConstrainMaxSizeForMode( + child, + YGFlexDirectionColumn, + ownerHeight, + ownerWidth, + &childHeightMeasureMode, + &childHeight); // Measure the child - YGLayoutNodeInternal(child, - childWidth, - childHeight, - direction, - childWidthMeasureMode, - childHeightMeasureMode, - ownerWidth, - ownerHeight, - false, - "measure", - config); + YGLayoutNodeInternal( + child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + ownerWidth, + ownerHeight, + false, + "measure", + config); child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax( child->getLayout().measuredDimensions[dim[mainAxis]], @@ -1363,13 +1498,14 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, child->setLayoutComputedFlexBasisGeneration(node->getRoot()->gCurrentGenerationCount); } -static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, - const YGNodeRef child, - const float width, - const YGMeasureMode widthMode, - const float height, - const YGDirection direction, - const YGConfigRef config) { +static void YGNodeAbsoluteLayoutChild( + const YGNodeRef node, + const YGNodeRef child, + const float width, + const YGMeasureMode widthMode, + const float height, + const YGDirection direction, + const YGConfigRef config) { const YGFlexDirection mainAxis = YGResolveFlexDirection(node->getStyle().flexDirection, direction); const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); @@ -1380,14 +1516,14 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, YGMeasureMode childWidthMeasureMode = YGMeasureModeUndefined; YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined; - const float& marginRow = + auto marginRow = YGUnwrapFloatOptional(child->getMarginForAxis(YGFlexDirectionRow, width)); - const float& marginColumn = YGUnwrapFloatOptional( + auto marginColumn = YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionColumn, width)); if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = - YGUnwrapFloatOptional(YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width)) + + childWidth = YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), width)) + marginRow; } else { // If the child doesn't have a specified width, compute the width based @@ -1401,13 +1537,14 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, YGUnwrapFloatOptional( child->getLeadingPosition(YGFlexDirectionRow, width) + child->getTrailingPosition(YGFlexDirectionRow, width)); - childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); + childWidth = + YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } } if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { - childHeight = - YGUnwrapFloatOptional(YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height)) + + childHeight = YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), height)) + marginColumn; } else { // If the child doesn't have a specified height, compute the height @@ -1422,12 +1559,14 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, YGUnwrapFloatOptional( child->getLeadingPosition(YGFlexDirectionColumn, height) + child->getTrailingPosition(YGFlexDirectionColumn, height)); - childHeight = YGNodeBoundAxis(child, YGFlexDirectionColumn, childHeight, height, width); + childHeight = YGNodeBoundAxis( + child, YGFlexDirectionColumn, childHeight, height, width); } } - // Exactly one dimension needs to be defined for us to be able to do aspect ratio - // calculation. One dimension being the anchor and the other being flexible. + // Exactly one dimension needs to be defined for us to be able to do aspect + // ratio calculation. One dimension being the anchor and the other being + // flexible. if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) { if (!child->getStyle().aspectRatio.isUndefined()) { if (YGFloatIsUndefined(childWidth)) { @@ -1443,14 +1582,17 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, // If we're still missing one or the other dimension, measure the content. if (YGFloatIsUndefined(childWidth) || YGFloatIsUndefined(childHeight)) { - childWidthMeasureMode = - YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeExactly; - childHeightMeasureMode = - YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly; + childWidthMeasureMode = YGFloatIsUndefined(childWidth) + ? YGMeasureModeUndefined + : YGMeasureModeExactly; + childHeightMeasureMode = YGFloatIsUndefined(childHeight) + ? YGMeasureModeUndefined + : YGMeasureModeExactly; - // If the size of the owner is defined then try to constrain the absolute child to that size - // as well. This allows text within the absolute child to wrap to the size of its owner. - // This is the same behavior as many browsers implement. + // If the size of the owner is defined then try to constrain the absolute + // child to that size as well. This allows text within the absolute child to + // wrap to the size of its owner. This is the same behavior as many browsers + // implement. if (!isMainAxisRow && YGFloatIsUndefined(childWidth) && widthMode != YGMeasureModeUndefined && !YGFloatIsUndefined(width) && width > 0) { @@ -1458,17 +1600,18 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, childWidthMeasureMode = YGMeasureModeAtMost; } - YGLayoutNodeInternal(child, - childWidth, - childHeight, - direction, - childWidthMeasureMode, - childHeightMeasureMode, - childWidth, - childHeight, - false, - "abs-measure", - config); + YGLayoutNodeInternal( + child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + childWidth, + childHeight, + false, + "abs-measure", + config); childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionRow, width)); @@ -1477,17 +1620,18 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, child->getMarginForAxis(YGFlexDirectionColumn, width)); } - YGLayoutNodeInternal(child, - childWidth, - childHeight, - direction, - YGMeasureModeExactly, - YGMeasureModeExactly, - childWidth, - childHeight, - true, - "abs-layout", - config); + YGLayoutNodeInternal( + child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + childWidth, + childHeight, + true, + "abs-layout", + config); if (child->isTrailingPosDefined(mainAxis) && !child->isLeadingPositionDefined(mainAxis)) { @@ -1546,13 +1690,14 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, } } -static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const float ownerWidth, - const float ownerHeight) { +static void YGNodeWithMeasureFuncSetMeasuredDimensions( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight) { YGAssertWithNode( node, node->getMeasure() != nullptr, @@ -1560,8 +1705,8 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node, const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); - const float paddingAndBorderAxisColumn = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, availableWidth); + const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis( + node, YGFlexDirectionColumn, availableWidth); const float marginAxisRow = YGUnwrapFloatOptional( node->getMarginForAxis(YGFlexDirectionRow, availableWidth)); const float marginAxisColumn = YGUnwrapFloatOptional( @@ -1628,13 +1773,14 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node, // For nodes with no children, use the available values if they were provided, // or the minimum size as indicated by the padding and border sizes. -static void YGNodeEmptyContainerSetMeasuredDimensions(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const float ownerWidth, - const float ownerHeight) { +static void YGNodeEmptyContainerSetMeasuredDimensions( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight) { const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); const float paddingAndBorderAxisColumn = @@ -1669,22 +1815,23 @@ static void YGNodeEmptyContainerSetMeasuredDimensions(const YGNodeRef node, YGDimensionHeight); } -static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const float ownerWidth, - const float ownerHeight) { +static bool YGNodeFixedSizeSetMeasuredDimensions( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight) { if ((!YGFloatIsUndefined(availableWidth) && widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) || (!YGFloatIsUndefined(availableHeight) && heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) || (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly)) { - const float& marginAxisColumn = YGUnwrapFloatOptional( + auto marginAxisColumn = YGUnwrapFloatOptional( node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); - const float& marginAxisRow = YGUnwrapFloatOptional( + auto marginAxisRow = YGUnwrapFloatOptional( node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); node->setLayoutMeasuredDimension( @@ -1750,12 +1897,14 @@ static float YGNodeCalculateAvailableInnerDim( if (!YGFloatIsUndefined(availableInnerDim)) { // We want to make sure our available height does not violate min and max // constraints - const YGFloatOptional minDimensionOptional = YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim); + const YGFloatOptional minDimensionOptional = + YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim); const float minInnerDim = minDimensionOptional.isUndefined() ? 0.0f : minDimensionOptional.getValue() - paddingAndBorder; - const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim) ; + const YGFloatOptional maxDimensionOptional = + YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim); const float maxInnerDim = maxDimensionOptional.isUndefined() ? FLT_MAX @@ -1787,16 +1936,17 @@ static void YGNodeComputeFlexBasisForChildren( // child to exactly match the remaining space if (measureModeMainDim == YGMeasureModeExactly) { for (auto child : children) { - if (singleFlexChild != nullptr) { - if (child->isNodeFlexible()) { - // There is already a flexible child, abort + if (child->isNodeFlexible()) { + if (singleFlexChild != nullptr || + YGFloatsEqual(child->resolveFlexGrow(), 0.0f) || + YGFloatsEqual(child->resolveFlexShrink(), 0.0f)) { + // There is already a flexible child, or this flexible child doesn't + // have flexGrow and flexShrink, abort singleFlexChild = nullptr; break; + } else { + singleFlexChild = child; } - } else if ( - child->resolveFlexGrow() > 0.0f && - child->resolveFlexShrink() > 0.0f) { - singleFlexChild = child; } } } @@ -1870,7 +2020,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // Add items to the current line until it's full or we run out of items. uint32_t endOfLineIndex = startOfLineIndex; - for (; endOfLineIndex < node->getChildrenCount(); endOfLineIndex++) { + for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { const YGNodeRef child = node->getChild(endOfLineIndex); if (child->getStyle().display == YGDisplayNone || child->getStyle().positionType == YGPositionTypeAbsolute) { @@ -2533,37 +2683,42 @@ static void YGJustifyMainAxis( // - YGMeasureModeExactly: fill available // - YGMeasureModeAtMost: fit content // -// When calling YGNodelayoutImpl and YGLayoutNodeInternal, if the caller passes -// an available size of -// undefined then it must also pass a measure mode of YGMeasureModeUndefined -// in that dimension. +// When calling YGNodelayoutImpl and YGLayoutNodeInternal, if the caller +// passes an available size of undefined then it must also pass a measure +// mode of YGMeasureModeUndefined in that dimension. // -static void YGNodelayoutImpl(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const float ownerWidth, - const float ownerHeight, - const bool performLayout, - const YGConfigRef config) { - YGAssertWithNode(node, - YGFloatIsUndefined(availableWidth) ? widthMeasureMode == YGMeasureModeUndefined - : true, - "availableWidth is indefinite so widthMeasureMode must be " - "YGMeasureModeUndefined"); - YGAssertWithNode(node, - YGFloatIsUndefined(availableHeight) ? heightMeasureMode == YGMeasureModeUndefined - : true, - "availableHeight is indefinite so heightMeasureMode must be " - "YGMeasureModeUndefined"); +static void YGNodelayoutImpl( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const YGConfigRef config) { + YGAssertWithNode( + node, + YGFloatIsUndefined(availableWidth) + ? widthMeasureMode == YGMeasureModeUndefined + : true, + "availableWidth is indefinite so widthMeasureMode must be " + "YGMeasureModeUndefined"); + YGAssertWithNode( + node, + YGFloatIsUndefined(availableHeight) + ? heightMeasureMode == YGMeasureModeUndefined + : true, + "availableHeight is indefinite so heightMeasureMode must be " + "YGMeasureModeUndefined"); // Set the resolved resolution in the node's layout. const YGDirection direction = node->resolveDirection(ownerDirection); node->setLayoutDirection(direction); - const YGFlexDirection flexRowDirection = YGResolveFlexDirection(YGFlexDirectionRow, direction); + const YGFlexDirection flexRowDirection = + YGResolveFlexDirection(YGFlexDirectionRow, direction); const YGFlexDirection flexColumnDirection = YGResolveFlexDirection(YGFlexDirectionColumn, direction); @@ -2608,41 +2763,46 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGEdgeBottom); if (node->getMeasure() != nullptr) { - YGNodeWithMeasureFuncSetMeasuredDimensions(node, - availableWidth, - availableHeight, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight); + YGNodeWithMeasureFuncSetMeasuredDimensions( + node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight); return; } const uint32_t childCount = YGNodeGetChildCount(node); if (childCount == 0) { - YGNodeEmptyContainerSetMeasuredDimensions(node, - availableWidth, - availableHeight, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight); + YGNodeEmptyContainerSetMeasuredDimensions( + node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight); return; } - // If we're not being asked to perform a full layout we can skip the algorithm if we already know - // the size - if (!performLayout && YGNodeFixedSizeSetMeasuredDimensions(node, - availableWidth, - availableHeight, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight)) { + // If we're not being asked to perform a full layout we can skip the algorithm + // if we already know the size + if (!performLayout && + YGNodeFixedSizeSetMeasuredDimensions( + node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight)) { return; } - // At this point we know we're going to perform work. Ensure that each child has a mutable copy. + // At this point we know we're going to perform work. Ensure that each child + // has a mutable copy. node->cloneChildrenIfNeeded(); // Reset layout flags, as they could have changed. node->setLayoutHadOverflow(false); @@ -2659,12 +2819,15 @@ static void YGNodelayoutImpl(const YGNodeRef node, const float leadingPaddingAndBorderCross = YGUnwrapFloatOptional( node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)); - const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); + const float paddingAndBorderAxisMain = + YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); const float paddingAndBorderAxisCross = YGNodePaddingAndBorderForAxis(node, crossAxis, ownerWidth); - YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; - YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; + YGMeasureMode measureModeMainDim = + isMainAxisRow ? widthMeasureMode : heightMeasureMode; + YGMeasureMode measureModeCrossDim = + isMainAxisRow ? heightMeasureMode : widthMeasureMode; const float paddingAndBorderAxisRow = isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross; @@ -2677,13 +2840,16 @@ static void YGNodelayoutImpl(const YGNodeRef node, node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); const float minInnerWidth = - YGUnwrapFloatOptional(YGResolveValue(node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - paddingAndBorderAxisRow; const float maxInnerWidth = - YGUnwrapFloatOptional(YGResolveValue(node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - paddingAndBorderAxisRow; const float minInnerHeight = - YGUnwrapFloatOptional(YGResolveValue(node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - paddingAndBorderAxisColumn; const float maxInnerHeight = YGUnwrapFloatOptional(YGResolveValue( @@ -2766,7 +2932,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, // the line length, so there's no more space left to distribute. bool sizeBasedOnContent = false; - // If we don't measure with exact main dimension we want to ensure we don't violate min and max + // If we don't measure with exact main dimension we want to ensure we don't + // violate min and max if (measureModeMainDim != YGMeasureModeExactly) { if (!YGFloatIsUndefined(minInnerMainDim) && collectedFlexItemsValues.sizeConsumedOnCurrentLine < @@ -2802,10 +2969,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim - collectedFlexItemsValues.sizeConsumedOnCurrentLine; } else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) { - // availableInnerMainDim is indefinite which means the node is being sized based on its - // content. - // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 points for - // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. + // availableInnerMainDim is indefinite which means the node is being sized + // based on its content. sizeConsumedOnCurrentLine is negative which means + // the node will allocate 0 points for its content. Consequently, + // remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. collectedFlexItemsValues.remainingFreeSpace = -collectedFlexItemsValues.sizeConsumedOnCurrentLine; } @@ -2907,7 +3074,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, crossAxis, availableInnerWidth)), pos[crossAxis]); } - // If leading position is not defined or calculations result in Nan, default to border + margin + // If leading position is not defined or calculations result in Nan, + // default to border + margin if (!isChildLeadingPosDefined || YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { child->setLayoutPosition( @@ -2933,7 +3101,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, child->marginTrailingValue(crossAxis).unit != YGUnitAuto) { // If the child defines a definite size for its cross axis, there's // no need to stretch. - if (!YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim)) { + if (!YGNodeIsStyleDimDefined( + child, crossAxis, availableInnerCrossDim)) { float childMainSize = child->getLayout().measuredDimensions[dim[mainAxis]]; float childCrossSize = @@ -2951,21 +3120,25 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; - YGConstrainMaxSizeForMode(child, - mainAxis, - availableInnerMainDim, - availableInnerWidth, - &childMainMeasureMode, - &childMainSize); - YGConstrainMaxSizeForMode(child, - crossAxis, - availableInnerCrossDim, - availableInnerWidth, - &childCrossMeasureMode, - &childCrossSize); + YGConstrainMaxSizeForMode( + child, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainMeasureMode, + &childMainSize); + YGConstrainMaxSizeForMode( + child, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossMeasureMode, + &childCrossSize); - const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; - const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; + const float childWidth = + isMainAxisRow ? childMainSize : childCrossSize; + const float childHeight = + !isMainAxisRow ? childMainSize : childCrossSize; const YGMeasureMode childWidthMeasureMode = YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined @@ -3025,7 +3198,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, // STEP 8: MULTI-LINE CONTENT ALIGNMENT if (performLayout && (lineCount > 1 || YGIsBaselineLayout(node)) && !YGFloatIsUndefined(availableInnerCrossDim)) { - const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; + const float remainingAlignContentDim = + availableInnerCrossDim - totalLineCrossDim; float crossDimLead = 0; float currentLead = leadingPaddingAndBorderCross; @@ -3150,9 +3324,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, crossAxis, availableInnerWidth)), pos[crossAxis]); - // Remeasure child with the line height as it as been only measured with the - // owners height yet. - if (!YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim)) { + // Remeasure child with the line height as it as been only + // measured with the owners height yet. + if (!YGNodeIsStyleDimDefined( + child, crossAxis, availableInnerCrossDim)) { const float childWidth = isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionWidth] + @@ -3175,17 +3350,18 @@ static void YGNodelayoutImpl(const YGNodeRef node, childHeight, child->getLayout() .measuredDimensions[YGDimensionHeight]))) { - YGLayoutNodeInternal(child, - childWidth, - childHeight, - direction, - YGMeasureModeExactly, - YGMeasureModeExactly, - availableInnerWidth, - availableInnerHeight, - true, - "multiline-stretch", - config); + YGLayoutNodeInternal( + child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + availableInnerWidth, + availableInnerHeight, + true, + "multiline-stretch", + config); } } break; @@ -3288,7 +3464,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, dim[crossAxis]); } - // As we only wrapped in normal direction yet, we need to reverse the positions on wrap-reverse. + // As we only wrapped in normal direction yet, we need to reverse the + // positions on wrap-reverse. if (performLayout && node->getStyle().flexWrap == YGWrapWrapReverse) { for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeGetChild(node, i); @@ -3319,10 +3496,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, } // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN - const bool needsMainTrailingPos = - mainAxis == YGFlexDirectionRowReverse || mainAxis == YGFlexDirectionColumnReverse; - const bool needsCrossTrailingPos = - crossAxis == YGFlexDirectionRowReverse || crossAxis == YGFlexDirectionColumnReverse; + const bool needsMainTrailingPos = mainAxis == YGFlexDirectionRowReverse || + mainAxis == YGFlexDirectionColumnReverse; + const bool needsCrossTrailingPos = crossAxis == YGFlexDirectionRowReverse || + crossAxis == YGFlexDirectionColumnReverse; // Set trailing position if necessary. if (needsMainTrailingPos || needsCrossTrailingPos) { @@ -3347,9 +3524,10 @@ bool gPrintTree = false; bool gPrintChanges = false; bool gPrintSkips = false; -static const char *spacer = " "; +static const char* spacer = + " "; -static const char *YGSpacer(const unsigned long level) { +static const char* YGSpacer(const unsigned long level) { const size_t spacerLen = strlen(spacer); if (level > spacerLen) { return &spacer[0]; @@ -3358,9 +3536,12 @@ static const char *YGSpacer(const unsigned long level) { } } -static const char *YGMeasureModeName(const YGMeasureMode mode, const bool performLayout) { - const char *kMeasureModeNames[YGMeasureModeCount] = {"UNDEFINED", "EXACTLY", "AT_MOST"}; - const char *kLayoutModeNames[YGMeasureModeCount] = {"LAY_UNDEFINED", +static const char* YGMeasureModeName( + const YGMeasureMode mode, + const bool performLayout) { + const char* kMeasureModeNames[YGMeasureModeCount] = { + "UNDEFINED", "EXACTLY", "AT_MOST"}; + const char* kLayoutModeNames[YGMeasureModeCount] = {"LAY_UNDEFINED", "LAY_EXACTLY", "LAY_AT_" "MOST"}; @@ -3372,25 +3553,30 @@ static const char *YGMeasureModeName(const YGMeasureMode mode, const bool perfor return performLayout ? kLayoutModeNames[mode] : kMeasureModeNames[mode]; } -static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(YGMeasureMode sizeMode, - float size, - float lastComputedSize) { - return sizeMode == YGMeasureModeExactly && YGFloatsEqual(size, lastComputedSize); +static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( + YGMeasureMode sizeMode, + float size, + float lastComputedSize) { + return sizeMode == YGMeasureModeExactly && + YGFloatsEqual(size, lastComputedSize); } -static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits(YGMeasureMode sizeMode, - float size, - YGMeasureMode lastSizeMode, - float lastComputedSize) { - return sizeMode == YGMeasureModeAtMost && lastSizeMode == YGMeasureModeUndefined && - (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); +static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits( + YGMeasureMode sizeMode, + float size, + YGMeasureMode lastSizeMode, + float lastComputedSize) { + return sizeMode == YGMeasureModeAtMost && + lastSizeMode == YGMeasureModeUndefined && + (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); } -static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(YGMeasureMode sizeMode, - float size, - YGMeasureMode lastSizeMode, - float lastSize, - float lastComputedSize) { +static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( + YGMeasureMode sizeMode, + float size, + YGMeasureMode lastSizeMode, + float lastSize, + float lastComputedSize) { return lastSizeMode == YGMeasureModeAtMost && sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && @@ -3398,10 +3584,11 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(YGMeasureM (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize)); } -float YGRoundValueToPixelGrid(const float value, - const float pointScaleFactor, - const bool forceCeil, - const bool forceFloor) { +float YGRoundValueToPixelGrid( + const float value, + const float pointScaleFactor, + const bool forceCeil, + const bool forceFloor) { float scaledValue = value * pointScaleFactor; float fractial = fmodf(scaledValue, 1.0f); if (YGFloatsEqual(fractial, 0)) { @@ -3428,66 +3615,74 @@ float YGRoundValueToPixelGrid(const float value, : scaledValue / pointScaleFactor; } -bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode, - const float width, - const YGMeasureMode heightMode, - const float height, - const YGMeasureMode lastWidthMode, - const float lastWidth, - const YGMeasureMode lastHeightMode, - const float lastHeight, - const float lastComputedWidth, - const float lastComputedHeight, - const float marginRow, - const float marginColumn, - const YGConfigRef config) { +bool YGNodeCanUseCachedMeasurement( + const YGMeasureMode widthMode, + const float width, + const YGMeasureMode heightMode, + const float height, + const YGMeasureMode lastWidthMode, + const float lastWidth, + const YGMeasureMode lastHeightMode, + const float lastHeight, + const float lastComputedWidth, + const float lastComputedHeight, + const float marginRow, + const float marginColumn, + const YGConfigRef config) { if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) || (!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) { return false; } bool useRoundedComparison = config != nullptr && config->pointScaleFactor != 0; - const float effectiveWidth = - useRoundedComparison ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false) - : width; - const float effectiveHeight = - useRoundedComparison ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false) - : height; - const float effectiveLastWidth = - useRoundedComparison - ? YGRoundValueToPixelGrid(lastWidth, config->pointScaleFactor, false, false) - : lastWidth; - const float effectiveLastHeight = - useRoundedComparison - ? YGRoundValueToPixelGrid(lastHeight, config->pointScaleFactor, false, false) - : lastHeight; + const float effectiveWidth = useRoundedComparison + ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false) + : width; + const float effectiveHeight = useRoundedComparison + ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false) + : height; + const float effectiveLastWidth = useRoundedComparison + ? YGRoundValueToPixelGrid( + lastWidth, config->pointScaleFactor, false, false) + : lastWidth; + const float effectiveLastHeight = useRoundedComparison + ? YGRoundValueToPixelGrid( + lastHeight, config->pointScaleFactor, false, false) + : lastHeight; - const bool hasSameWidthSpec = - lastWidthMode == widthMode && YGFloatsEqual(effectiveLastWidth, effectiveWidth); - const bool hasSameHeightSpec = - lastHeightMode == heightMode && YGFloatsEqual(effectiveLastHeight, effectiveHeight); + const bool hasSameWidthSpec = lastWidthMode == widthMode && + YGFloatsEqual(effectiveLastWidth, effectiveWidth); + const bool hasSameHeightSpec = lastHeightMode == heightMode && + YGFloatsEqual(effectiveLastHeight, effectiveHeight); const bool widthIsCompatible = - hasSameWidthSpec || YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(widthMode, - width - marginRow, - lastComputedWidth) || - YGMeasureModeOldSizeIsUnspecifiedAndStillFits(widthMode, - width - marginRow, - lastWidthMode, - lastComputedWidth) || + hasSameWidthSpec || + YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( + widthMode, width - marginRow, lastComputedWidth) || + YGMeasureModeOldSizeIsUnspecifiedAndStillFits( + widthMode, width - marginRow, lastWidthMode, lastComputedWidth) || YGMeasureModeNewMeasureSizeIsStricterAndStillValid( - widthMode, width - marginRow, lastWidthMode, lastWidth, lastComputedWidth); + widthMode, + width - marginRow, + lastWidthMode, + lastWidth, + lastComputedWidth); const bool heightIsCompatible = - hasSameHeightSpec || YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(heightMode, - height - marginColumn, - lastComputedHeight) || - YGMeasureModeOldSizeIsUnspecifiedAndStillFits(heightMode, - height - marginColumn, - lastHeightMode, - lastComputedHeight) || + hasSameHeightSpec || + YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( + heightMode, height - marginColumn, lastComputedHeight) || + YGMeasureModeOldSizeIsUnspecifiedAndStillFits( + heightMode, + height - marginColumn, + lastHeightMode, + lastComputedHeight) || YGMeasureModeNewMeasureSizeIsStricterAndStillValid( - heightMode, height - marginColumn, lastHeightMode, lastHeight, lastComputedHeight); + heightMode, + height - marginColumn, + lastHeightMode, + lastHeight, + lastComputedHeight); return widthIsCompatible && heightIsCompatible; } @@ -3500,17 +3695,18 @@ bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode, // Input parameters are the same as YGNodelayoutImpl (see above) // Return parameter is true if layout was performed, false if skipped // -bool YGLayoutNodeInternal(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const float ownerWidth, - const float ownerHeight, - const bool performLayout, - const char *reason, - const YGConfigRef config) { +bool YGLayoutNodeInternal( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const char* reason, + const YGConfigRef config) { YGLayout* layout = &node->getLayout(); node->getRoot()->gDepth++; @@ -3522,8 +3718,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node, if (needToVisitNode) { // Invalidate the cached results. layout->nextCachedMeasurementsIndex = 0; - layout->cachedLayout.widthMeasureMode = (YGMeasureMode) -1; - layout->cachedLayout.heightMeasureMode = (YGMeasureMode) -1; + layout->cachedLayout.widthMeasureMode = (YGMeasureMode)-1; + layout->cachedLayout.heightMeasureMode = (YGMeasureMode)-1; layout->cachedLayout.computedWidth = -1; layout->cachedLayout.computedHeight = -1; } @@ -3549,36 +3745,38 @@ bool YGLayoutNodeInternal(const YGNodeRef node, node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); // First, try to use the layout cache. - if (YGNodeCanUseCachedMeasurement(widthMeasureMode, - availableWidth, - heightMeasureMode, - availableHeight, - layout->cachedLayout.widthMeasureMode, - layout->cachedLayout.availableWidth, - layout->cachedLayout.heightMeasureMode, - layout->cachedLayout.availableHeight, - layout->cachedLayout.computedWidth, - layout->cachedLayout.computedHeight, - marginAxisRow, - marginAxisColumn, - config)) { + if (YGNodeCanUseCachedMeasurement( + widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedLayout.widthMeasureMode, + layout->cachedLayout.availableWidth, + layout->cachedLayout.heightMeasureMode, + layout->cachedLayout.availableHeight, + layout->cachedLayout.computedWidth, + layout->cachedLayout.computedHeight, + marginAxisRow, + marginAxisColumn, + config)) { cachedResults = &layout->cachedLayout; } else { // Try to use the measurement cache. for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { - if (YGNodeCanUseCachedMeasurement(widthMeasureMode, - availableWidth, - heightMeasureMode, - availableHeight, - layout->cachedMeasurements[i].widthMeasureMode, - layout->cachedMeasurements[i].availableWidth, - layout->cachedMeasurements[i].heightMeasureMode, - layout->cachedMeasurements[i].availableHeight, - layout->cachedMeasurements[i].computedWidth, - layout->cachedMeasurements[i].computedHeight, - marginAxisRow, - marginAxisColumn, - config)) { + if (YGNodeCanUseCachedMeasurement( + widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedMeasurements[i].widthMeasureMode, + layout->cachedMeasurements[i].availableWidth, + layout->cachedMeasurements[i].heightMeasureMode, + layout->cachedMeasurements[i].availableHeight, + layout->cachedMeasurements[i].computedWidth, + layout->cachedMeasurements[i].computedHeight, + marginAxisRow, + marginAxisColumn, + config)) { cachedResults = &layout->cachedMeasurements[i]; break; } @@ -3593,10 +3791,13 @@ bool YGLayoutNodeInternal(const YGNodeRef node, } } else { for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { - if (YGFloatsEqual(layout->cachedMeasurements[i].availableWidth, availableWidth) && - YGFloatsEqual(layout->cachedMeasurements[i].availableHeight, availableHeight) && + if (YGFloatsEqual( + layout->cachedMeasurements[i].availableWidth, availableWidth) && + YGFloatsEqual( + layout->cachedMeasurements[i].availableHeight, availableHeight) && layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && - layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) { + layout->cachedMeasurements[i].heightMeasureMode == + heightMeasureMode) { cachedResults = &layout->cachedMeasurements[i]; break; } @@ -3605,10 +3806,16 @@ bool YGLayoutNodeInternal(const YGNodeRef node, if (!needToVisitNode && cachedResults != nullptr) { layout->measuredDimensions[YGDimensionWidth] = cachedResults->computedWidth; - layout->measuredDimensions[YGDimensionHeight] = cachedResults->computedHeight; + layout->measuredDimensions[YGDimensionHeight] = + cachedResults->computedHeight; if (gPrintChanges && gPrintSkips) { - YGLog(node, YGLogLevelVerbose, "%s%d.{[skipped] ", YGSpacer(node->getRoot()->gDepth), node->getRoot()->gDepth); + YGLog( + node, + YGLogLevelVerbose, + "%s%d.{[skipped] ", + YGSpacer(node->getRoot()->gDepth), + node->getRoot()->gDepth); if (node->getPrintFunc() != nullptr) { node->getPrintFunc()(node); } @@ -3647,16 +3854,17 @@ bool YGLayoutNodeInternal(const YGNodeRef node, reason); } - YGNodelayoutImpl(node, - availableWidth, - availableHeight, - ownerDirection, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight, - performLayout, - config); + YGNodelayoutImpl( + node, + availableWidth, + availableHeight, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + performLayout, + config); if (gPrintChanges) { YGLog( @@ -3690,13 +3898,14 @@ bool YGLayoutNodeInternal(const YGNodeRef node, layout->nextCachedMeasurementsIndex = 0; } - YGCachedMeasurement *newCacheEntry; + YGCachedMeasurement* newCacheEntry; if (performLayout) { // Use the single layout cache entry. newCacheEntry = &layout->cachedLayout; } else { // Allocate a new measurement cache entry. - newCacheEntry = &layout->cachedMeasurements[layout->nextCachedMeasurementsIndex]; + newCacheEntry = + &layout->cachedMeasurements[layout->nextCachedMeasurementsIndex]; layout->nextCachedMeasurementsIndex++; } @@ -3704,8 +3913,10 @@ bool YGLayoutNodeInternal(const YGNodeRef node, newCacheEntry->availableHeight = availableHeight; newCacheEntry->widthMeasureMode = widthMeasureMode; newCacheEntry->heightMeasureMode = heightMeasureMode; - newCacheEntry->computedWidth = layout->measuredDimensions[YGDimensionWidth]; - newCacheEntry->computedHeight = layout->measuredDimensions[YGDimensionHeight]; + newCacheEntry->computedWidth = + layout->measuredDimensions[YGDimensionWidth]; + newCacheEntry->computedHeight = + layout->measuredDimensions[YGDimensionHeight]; } } @@ -3726,8 +3937,13 @@ bool YGLayoutNodeInternal(const YGNodeRef node, return (needToVisitNode || cachedResults == nullptr); } -void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint) { - YGAssertWithConfig(config, pixelsInPoint >= 0.0f, "Scale factor should not be less than zero"); +void YGConfigSetPointScaleFactor( + const YGConfigRef config, + const float pixelsInPoint) { + YGAssertWithConfig( + config, + pixelsInPoint >= 0.0f, + "Scale factor should not be less than zero"); // We store points for Pixel as we will use it for rounding if (pixelsInPoint == 0.0f) { @@ -3738,10 +3954,11 @@ void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInP } } -static void YGRoundToPixelGrid(const YGNodeRef node, - const float pointScaleFactor, - const float absoluteLeft, - const float absoluteTop) { +static void YGRoundToPixelGrid( + const YGNodeRef node, + const float pointScaleFactor, + const float absoluteLeft, + const float absoluteTop) { if (pointScaleFactor == 0.0f) { return; } @@ -3758,8 +3975,8 @@ static void YGRoundToPixelGrid(const YGNodeRef node, const float absoluteNodeRight = absoluteNodeLeft + nodeWidth; const float absoluteNodeBottom = absoluteNodeTop + nodeHeight; - // If a node has a custom measure function we never want to round down its size as this could - // lead to unwanted text truncation. + // If a node has a custom measure function we never want to round down its + // size as this could lead to unwanted text truncation. const bool textRounding = node->getNodeType() == YGNodeTypeText; node->setLayoutPosition( @@ -3770,13 +3987,15 @@ static void YGRoundToPixelGrid(const YGNodeRef node, YGRoundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding), YGEdgeTop); - // We multiply dimension by scale factor and if the result is close to the whole number, we don't - // have any fraction - // To verify if the result is close to whole number we want to check both floor and ceil numbers - const bool hasFractionalWidth = !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) && - !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0); - const bool hasFractionalHeight = !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) && - !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0); + // We multiply dimension by scale factor and if the result is close to the + // whole number, we don't have any fraction To verify if the result is close + // to whole number we want to check both floor and ceil numbers + const bool hasFractionalWidth = + !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) && + !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0); + const bool hasFractionalHeight = + !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) && + !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0); node->setLayoutDimension( YGRoundValueToPixelGrid( @@ -3853,7 +4072,8 @@ void YGNodeCalculateLayout( node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight) .isUndefined()) { - height = YGUnwrapFloatOptional(YGResolveValue(node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)); + height = YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)); heightMeasureMode = YGMeasureModeAtMost; } else { height = ownerHeight; @@ -3959,12 +4179,14 @@ void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( config->shouldDiffLayoutWithoutLegacyStretchBehaviour = shouldDiffLayout; } -static void YGVLog(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args) { - const YGConfigRef logConfig = config != nullptr ? config : YGConfigGetDefault(); +static void YGVLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args) { + const YGConfigRef logConfig = + config != nullptr ? config : YGConfigGetDefault(); logConfig->logger(logConfig, node, level, format, args); if (level == YGLogLevelFatal) { @@ -3972,14 +4194,18 @@ static void YGVLog(const YGConfigRef config, } } -void YGLogWithConfig(const YGConfigRef config, YGLogLevel level, const char *format, ...) { +void YGLogWithConfig( + const YGConfigRef config, + YGLogLevel level, + const char* format, + ...) { va_list args; va_start(args, format); YGVLog(config, nullptr, level, format, args); va_end(args); } -void YGLog(const YGNodeRef node, YGLogLevel level, const char *format, ...) { +void YGLog(const YGNodeRef node, YGLogLevel level, const char* format, ...) { va_list args; va_start(args, format); YGVLog( @@ -3987,32 +4213,40 @@ void YGLog(const YGNodeRef node, YGLogLevel level, const char *format, ...) { va_end(args); } -void YGAssert(const bool condition, const char *message) { +void YGAssert(const bool condition, const char* message) { if (!condition) { YGLog(nullptr, YGLogLevelFatal, "%s\n", message); } } -void YGAssertWithNode(const YGNodeRef node, const bool condition, const char *message) { +void YGAssertWithNode( + const YGNodeRef node, + const bool condition, + const char* message) { if (!condition) { YGLog(node, YGLogLevelFatal, "%s\n", message); } } -void YGAssertWithConfig(const YGConfigRef config, const bool condition, const char *message) { +void YGAssertWithConfig( + const YGConfigRef config, + const bool condition, + const char* message) { if (!condition) { YGLogWithConfig(config, YGLogLevelFatal, "%s\n", message); } } -void YGConfigSetExperimentalFeatureEnabled(const YGConfigRef config, - const YGExperimentalFeature feature, - const bool enabled) { +void YGConfigSetExperimentalFeatureEnabled( + const YGConfigRef config, + const YGExperimentalFeature feature, + const bool enabled) { config->experimentalFeatures[feature] = enabled; } -inline bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config, - const YGExperimentalFeature feature) { +inline bool YGConfigIsExperimentalFeatureEnabled( + const YGConfigRef config, + const YGExperimentalFeature feature) { return config->experimentalFeatures[feature]; } @@ -4020,8 +4254,9 @@ void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled) { config->useWebDefaults = enabled; } -void YGConfigSetUseLegacyStretchBehaviour(const YGConfigRef config, - const bool useLegacyStretchBehaviour) { +void YGConfigSetUseLegacyStretchBehaviour( + const YGConfigRef config, + const bool useLegacyStretchBehaviour) { config->useLegacyStretchBehaviour = useLegacyStretchBehaviour; } @@ -4029,26 +4264,32 @@ bool YGConfigGetUseWebDefaults(const YGConfigRef config) { return config->useWebDefaults; } -void YGConfigSetContext(const YGConfigRef config, void *context) { +void YGConfigSetContext(const YGConfigRef config, void* context) { config->context = context; } -void *YGConfigGetContext(const YGConfigRef config) { +void* YGConfigGetContext(const YGConfigRef config) { return config->context; } -void YGConfigSetCloneNodeFunc(const YGConfigRef config, const YGCloneNodeFunc callback) { +void YGConfigSetCloneNodeFunc( + const YGConfigRef config, + const YGCloneNodeFunc callback) { config->cloneNodeCallback = callback; } -static void YGTraverseChildrenPreOrder(const YGVector& children, const std::function& f) { +static void YGTraverseChildrenPreOrder( + const YGVector& children, + const std::function& f) { for (YGNodeRef node : children) { f(node); YGTraverseChildrenPreOrder(node->getChildren(), f); } } -void YGTraversePreOrder(YGNodeRef const node, std::function&& f) { +void YGTraversePreOrder( + YGNodeRef const node, + std::function&& f) { if (!node) { return; } diff --git a/yoga/Yoga.h b/yoga/Yoga.h index a9fc89d7..5bcbe2ab 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - #pragma once #include @@ -45,23 +45,33 @@ typedef struct YGValue { extern const YGValue YGValueUndefined; extern const YGValue YGValueAuto; -typedef struct YGConfig *YGConfigRef; +#ifdef __cplusplus + +extern bool operator==(const YGValue& lhs, const YGValue& rhs); +extern bool operator!=(const YGValue& lhs, const YGValue& rhs); + +#endif + +typedef struct YGConfig* YGConfigRef; typedef struct YGNode* YGNodeRef; -typedef YGSize (*YGMeasureFunc)(YGNodeRef node, - float width, - YGMeasureMode widthMode, - float height, - YGMeasureMode heightMode); -typedef float (*YGBaselineFunc)(YGNodeRef node, const float width, const float height); +typedef YGSize (*YGMeasureFunc)( + YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode); +typedef float ( + *YGBaselineFunc)(YGNodeRef node, const float width, const float height); typedef void (*YGDirtiedFunc)(YGNodeRef node); typedef void (*YGPrintFunc)(YGNodeRef node); -typedef int (*YGLogger)(const YGConfigRef config, - const YGNodeRef node, - YGLogLevel level, - const char *format, - va_list args); +typedef int (*YGLogger)( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args); typedef YGNodeRef ( *YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex); @@ -74,9 +84,10 @@ WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node); WIN_EXPORT void YGNodeReset(const YGNodeRef node); WIN_EXPORT int32_t YGNodeGetInstanceCount(void); -WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node, - const YGNodeRef child, - const uint32_t index); +WIN_EXPORT void YGNodeInsertChild( + const YGNodeRef node, + const YGNodeRef child, + const uint32_t index); // This function inserts the child YGNodeRef as a children of the node received // by parameter and set the Owner of the child object to null. This function is @@ -99,10 +110,11 @@ WIN_EXPORT void YGNodeSetChildren( const YGNodeRef children[], const uint32_t count); -WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node, - const float availableWidth, - const float availableHeight, - const YGDirection ownerDirection); +WIN_EXPORT void YGNodeCalculateLayout( + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection); // Mark a node as dirty. Only valid for nodes with a custom measure function // set. @@ -112,70 +124,34 @@ WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node, // marking manually. WIN_EXPORT void YGNodeMarkDirty(const YGNodeRef node); -// This function marks the current node and all its descendants as dirty. This function is added to test yoga benchmarks. -// This function is not expected to be used in production as calling `YGCalculateLayout` will cause the recalculation of each and every node. +// This function marks the current node and all its descendants as dirty. This +// function is added to test yoga benchmarks. This function is not expected to +// be used in production as calling `YGCalculateLayout` will cause the +// recalculation of each and every node. WIN_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(const YGNodeRef node); WIN_EXPORT void YGNodePrint(const YGNodeRef node, const YGPrintOptions options); WIN_EXPORT bool YGFloatIsUndefined(const float value); -WIN_EXPORT bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode, - const float width, - const YGMeasureMode heightMode, - const float height, - const YGMeasureMode lastWidthMode, - const float lastWidth, - const YGMeasureMode lastHeightMode, - const float lastHeight, - const float lastComputedWidth, - const float lastComputedHeight, - const float marginRow, - const float marginColumn, - const YGConfigRef config); +WIN_EXPORT bool YGNodeCanUseCachedMeasurement( + const YGMeasureMode widthMode, + const float width, + const YGMeasureMode heightMode, + const float height, + const YGMeasureMode lastWidthMode, + const float lastWidth, + const YGMeasureMode lastHeightMode, + const float lastHeight, + const float lastComputedWidth, + const float lastComputedHeight, + const float marginRow, + const float marginColumn, + const YGConfigRef config); -WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode); - -#define YG_NODE_PROPERTY(type, name, paramName) \ - WIN_EXPORT void YGNodeSet##name(const YGNodeRef node, type paramName); \ - WIN_EXPORT type YGNodeGet##name(const YGNodeRef node); - -#define YG_NODE_STYLE_PROPERTY(type, name, paramName) \ - WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, const type paramName); \ - WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node); - -#define YG_NODE_STYLE_PROPERTY_UNIT(type, name, paramName) \ - WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, const float paramName); \ - WIN_EXPORT void YGNodeStyleSet##name##Percent(const YGNodeRef node, const float paramName); \ - WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node); - -#define YG_NODE_STYLE_PROPERTY_UNIT_AUTO(type, name, paramName) \ - YG_NODE_STYLE_PROPERTY_UNIT(type, name, paramName) \ - WIN_EXPORT void YGNodeStyleSet##name##Auto(const YGNodeRef node); - -#define YG_NODE_STYLE_EDGE_PROPERTY(type, name, paramName) \ - WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, \ - const YGEdge edge, \ - const type paramName); \ - WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge); - -#define YG_NODE_STYLE_EDGE_PROPERTY_UNIT(type, name, paramName) \ - WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, \ - const YGEdge edge, \ - const float paramName); \ - WIN_EXPORT void YGNodeStyleSet##name##Percent(const YGNodeRef node, \ - const YGEdge edge, \ - const float paramName); \ - WIN_EXPORT WIN_STRUCT(type) YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge); - -#define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO(type, name) \ - WIN_EXPORT void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge); - -#define YG_NODE_LAYOUT_PROPERTY(type, name) \ - WIN_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node); - -#define YG_NODE_LAYOUT_EDGE_PROPERTY(type, name) \ - WIN_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node, const YGEdge edge); +WIN_EXPORT void YGNodeCopyStyle( + const YGNodeRef dstNode, + const YGNodeRef srcNode); void* YGNodeGetContext(YGNodeRef node); void YGNodeSetContext(YGNodeRef node, void* context); @@ -194,90 +170,240 @@ void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType); bool YGNodeIsDirty(YGNodeRef node); bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node); -YG_NODE_STYLE_PROPERTY(YGDirection, Direction, direction); -YG_NODE_STYLE_PROPERTY(YGFlexDirection, FlexDirection, flexDirection); -YG_NODE_STYLE_PROPERTY(YGJustify, JustifyContent, justifyContent); -YG_NODE_STYLE_PROPERTY(YGAlign, AlignContent, alignContent); -YG_NODE_STYLE_PROPERTY(YGAlign, AlignItems, alignItems); -YG_NODE_STYLE_PROPERTY(YGAlign, AlignSelf, alignSelf); -YG_NODE_STYLE_PROPERTY(YGPositionType, PositionType, positionType); -YG_NODE_STYLE_PROPERTY(YGWrap, FlexWrap, flexWrap); -YG_NODE_STYLE_PROPERTY(YGOverflow, Overflow, overflow); -YG_NODE_STYLE_PROPERTY(YGDisplay, Display, display); -YG_NODE_STYLE_PROPERTY(float, Flex, flex); -YG_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow); -YG_NODE_STYLE_PROPERTY(float, FlexShrink, flexShrink); -YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, FlexBasis, flexBasis); +WIN_EXPORT void YGNodeStyleSetDirection( + const YGNodeRef node, + const YGDirection direction); +WIN_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeRef node); -YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Position, position); -YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Margin, margin); -YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO(YGValue, Margin); -YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Padding, padding); -YG_NODE_STYLE_EDGE_PROPERTY(float, Border, border); +WIN_EXPORT void YGNodeStyleSetFlexDirection( + const YGNodeRef node, + const YGFlexDirection flexDirection); +WIN_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeRef node); -YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, Width, width); -YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, Height, height); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MinWidth, minWidth); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MinHeight, minHeight); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MaxWidth, maxWidth); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MaxHeight, maxHeight); +WIN_EXPORT void YGNodeStyleSetJustifyContent( + const YGNodeRef node, + const YGJustify justifyContent); +WIN_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetAlignContent( + const YGNodeRef node, + const YGAlign alignContent); +WIN_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetAlignItems( + const YGNodeRef node, + const YGAlign alignItems); +WIN_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetAlignSelf( + const YGNodeRef node, + const YGAlign alignSelf); +WIN_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetPositionType( + const YGNodeRef node, + const YGPositionType positionType); +WIN_EXPORT YGPositionType YGNodeStyleGetPositionType(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetFlexWrap( + const YGNodeRef node, + const YGWrap flexWrap); +WIN_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetOverflow( + const YGNodeRef node, + const YGOverflow overflow); +WIN_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetDisplay( + const YGNodeRef node, + const YGDisplay display); +WIN_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex); +WIN_EXPORT float YGNodeStyleGetFlex(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetFlexGrow( + const YGNodeRef node, + const float flexGrow); +WIN_EXPORT float YGNodeStyleGetFlexGrow(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetFlexShrink( + const YGNodeRef node, + const float flexShrink); +WIN_EXPORT float YGNodeStyleGetFlexShrink(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetFlexBasis( + const YGNodeRef node, + const float flexBasis); +WIN_EXPORT void YGNodeStyleSetFlexBasisPercent( + const YGNodeRef node, + const float flexBasis); +WIN_EXPORT void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node); +WIN_EXPORT YGValue YGNodeStyleGetFlexBasis(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetPosition( + const YGNodeRef node, + const YGEdge edge, + const float position); +WIN_EXPORT void YGNodeStyleSetPositionPercent( + const YGNodeRef node, + const YGEdge edge, + const float position); +WIN_EXPORT WIN_STRUCT(YGValue) + YGNodeStyleGetPosition(const YGNodeRef node, const YGEdge edge); + +WIN_EXPORT void YGNodeStyleSetMargin( + const YGNodeRef node, + const YGEdge edge, + const float margin); +WIN_EXPORT void YGNodeStyleSetMarginPercent( + const YGNodeRef node, + const YGEdge edge, + const float margin); +WIN_EXPORT void YGNodeStyleSetMarginAuto( + const YGNodeRef node, + const YGEdge edge); +WIN_EXPORT YGValue +YGNodeStyleGetMargin(const YGNodeRef node, const YGEdge edge); + +WIN_EXPORT void YGNodeStyleSetPadding( + const YGNodeRef node, + const YGEdge edge, + const float padding); +WIN_EXPORT void YGNodeStyleSetPaddingPercent( + const YGNodeRef node, + const YGEdge edge, + const float padding); +WIN_EXPORT YGValue +YGNodeStyleGetPadding(const YGNodeRef node, const YGEdge edge); + +WIN_EXPORT void YGNodeStyleSetBorder( + const YGNodeRef node, + const YGEdge edge, + const float border); +WIN_EXPORT float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge); + +WIN_EXPORT void YGNodeStyleSetWidth(const YGNodeRef node, const float width); +WIN_EXPORT void YGNodeStyleSetWidthPercent( + const YGNodeRef node, + const float width); +WIN_EXPORT void YGNodeStyleSetWidthAuto(const YGNodeRef node); +WIN_EXPORT YGValue YGNodeStyleGetWidth(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetHeight(const YGNodeRef node, const float height); +WIN_EXPORT void YGNodeStyleSetHeightPercent( + const YGNodeRef node, + const float height); +WIN_EXPORT void YGNodeStyleSetHeightAuto(const YGNodeRef node); +WIN_EXPORT YGValue YGNodeStyleGetHeight(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetMinWidth( + const YGNodeRef node, + const float minWidth); +WIN_EXPORT void YGNodeStyleSetMinWidthPercent( + const YGNodeRef node, + const float minWidth); +WIN_EXPORT YGValue YGNodeStyleGetMinWidth(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetMinHeight( + const YGNodeRef node, + const float minHeight); +WIN_EXPORT void YGNodeStyleSetMinHeightPercent( + const YGNodeRef node, + const float minHeight); +WIN_EXPORT YGValue YGNodeStyleGetMinHeight(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetMaxWidth( + const YGNodeRef node, + const float maxWidth); +WIN_EXPORT void YGNodeStyleSetMaxWidthPercent( + const YGNodeRef node, + const float maxWidth); +WIN_EXPORT YGValue YGNodeStyleGetMaxWidth(const YGNodeRef node); + +WIN_EXPORT void YGNodeStyleSetMaxHeight( + const YGNodeRef node, + const float maxHeight); +WIN_EXPORT void YGNodeStyleSetMaxHeightPercent( + const YGNodeRef node, + const float maxHeight); +WIN_EXPORT YGValue YGNodeStyleGetMaxHeight(const YGNodeRef node); // Yoga specific properties, not compatible with flexbox specification // Aspect ratio control the size of the undefined dimension of a node. -// Aspect ratio is encoded as a floating point value width/height. e.g. A value of 2 leads to a node -// with a width twice the size of its height while a value of 0.5 gives the opposite effect. +// Aspect ratio is encoded as a floating point value width/height. e.g. A value +// of 2 leads to a node with a width twice the size of its height while a value +// of 0.5 gives the opposite effect. // -// - On a node with a set width/height aspect ratio control the size of the unset dimension -// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if -// unset -// - On a node with a measure function aspect ratio works as though the measure function measures -// the flex basis -// - On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis if -// unset +// - On a node with a set width/height aspect ratio control the size of the +// unset dimension +// - On a node with a set flex basis aspect ratio controls the size of the node +// in the cross axis if unset +// - On a node with a measure function aspect ratio works as though the measure +// function measures the flex basis +// - On a node with flex grow/shrink aspect ratio controls the size of the node +// in the cross axis if unset // - Aspect ratio takes min/max dimensions into account -YG_NODE_STYLE_PROPERTY(float, AspectRatio, aspectRatio); +WIN_EXPORT void YGNodeStyleSetAspectRatio( + const YGNodeRef node, + const float aspectRatio); +WIN_EXPORT float YGNodeStyleGetAspectRatio(const YGNodeRef node); -YG_NODE_LAYOUT_PROPERTY(float, Left); -YG_NODE_LAYOUT_PROPERTY(float, Top); -YG_NODE_LAYOUT_PROPERTY(float, Right); -YG_NODE_LAYOUT_PROPERTY(float, Bottom); -YG_NODE_LAYOUT_PROPERTY(float, Width); -YG_NODE_LAYOUT_PROPERTY(float, Height); -YG_NODE_LAYOUT_PROPERTY(YGDirection, Direction); -YG_NODE_LAYOUT_PROPERTY(bool, HadOverflow); +WIN_EXPORT float YGNodeLayoutGetLeft(const YGNodeRef node); +WIN_EXPORT float YGNodeLayoutGetTop(const YGNodeRef node); +WIN_EXPORT float YGNodeLayoutGetRight(const YGNodeRef node); +WIN_EXPORT float YGNodeLayoutGetBottom(const YGNodeRef node); +WIN_EXPORT float YGNodeLayoutGetWidth(const YGNodeRef node); +WIN_EXPORT float YGNodeLayoutGetHeight(const YGNodeRef node); +WIN_EXPORT YGDirection YGNodeLayoutGetDirection(const YGNodeRef node); +WIN_EXPORT bool YGNodeLayoutGetHadOverflow(const YGNodeRef node); bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node); -// Get the computed values for these nodes after performing layout. If they were set using -// point values then the returned value will be the same as YGNodeStyleGetXXX. However if -// they were set using a percentage value then the returned value is the computed value used -// during layout. -YG_NODE_LAYOUT_EDGE_PROPERTY(float, Margin); -YG_NODE_LAYOUT_EDGE_PROPERTY(float, Border); -YG_NODE_LAYOUT_EDGE_PROPERTY(float, Padding); +// Get the computed values for these nodes after performing layout. If they were +// set using point values then the returned value will be the same as +// YGNodeStyleGetXXX. However if they were set using a percentage value then the +// returned value is the computed value used during layout. +WIN_EXPORT float YGNodeLayoutGetMargin(const YGNodeRef node, const YGEdge edge); +WIN_EXPORT float YGNodeLayoutGetBorder(const YGNodeRef node, const YGEdge edge); +WIN_EXPORT float YGNodeLayoutGetPadding( + const YGNodeRef node, + const YGEdge edge); WIN_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger); -WIN_EXPORT void YGLog(const YGNodeRef node, YGLogLevel level, const char *message, ...); -WIN_EXPORT void YGLogWithConfig(const YGConfigRef config, YGLogLevel level, const char *format, ...); -WIN_EXPORT void YGAssert(const bool condition, const char *message); -WIN_EXPORT void YGAssertWithNode(const YGNodeRef node, const bool condition, const char *message); -WIN_EXPORT void YGAssertWithConfig(const YGConfigRef config, - const bool condition, - const char *message); +WIN_EXPORT void +YGLog(const YGNodeRef node, YGLogLevel level, const char* message, ...); +WIN_EXPORT void YGLogWithConfig( + const YGConfigRef config, + YGLogLevel level, + const char* format, + ...); +WIN_EXPORT void YGAssert(const bool condition, const char* message); +WIN_EXPORT void YGAssertWithNode( + const YGNodeRef node, + const bool condition, + const char* message); +WIN_EXPORT void YGAssertWithConfig( + const YGConfigRef config, + const bool condition, + const char* message); // Set this to number of pixels in 1 point to round calculation results // If you want to avoid rounding - set PointScaleFactor to 0 -WIN_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint); +WIN_EXPORT void YGConfigSetPointScaleFactor( + const YGConfigRef config, + const float pixelsInPoint); void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( const YGConfigRef config, const bool shouldDiffLayout); -// Yoga previously had an error where containers would take the maximum space possible instead of -// the minimum -// like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: -// stretch; -// Because this was such a long-standing bug we must allow legacy users to switch back to this -// behaviour. -WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour(const YGConfigRef config, - const bool useLegacyStretchBehaviour); +// Yoga previously had an error where containers would take the maximum space +// possible instead of the minimum like they are supposed to. In practice this +// resulted in implicit behaviour similar to align-self: stretch; Because this +// was such a long-standing bug we must allow legacy users to switch back to +// this behaviour. +WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour( + const YGConfigRef config, + const bool useLegacyStretchBehaviour); // YGConfig WIN_EXPORT YGConfigRef YGConfigNew(void); @@ -285,25 +411,30 @@ WIN_EXPORT void YGConfigFree(const YGConfigRef config); WIN_EXPORT void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src); WIN_EXPORT int32_t YGConfigGetInstanceCount(void); -WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled(const YGConfigRef config, - const YGExperimentalFeature feature, - const bool enabled); -WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config, - const YGExperimentalFeature feature); +WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled( + const YGConfigRef config, + const YGExperimentalFeature feature, + const bool enabled); +WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled( + const YGConfigRef config, + const YGExperimentalFeature feature); // Using the web defaults is the prefered configuration for new projects. // Usage of non web defaults should be considered as legacy. -WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled); +WIN_EXPORT void YGConfigSetUseWebDefaults( + const YGConfigRef config, + const bool enabled); WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config); -WIN_EXPORT void YGConfigSetCloneNodeFunc(const YGConfigRef config, - const YGCloneNodeFunc callback); +WIN_EXPORT void YGConfigSetCloneNodeFunc( + const YGConfigRef config, + const YGCloneNodeFunc callback); // Export only for C# WIN_EXPORT YGConfigRef YGConfigGetDefault(void); -WIN_EXPORT void YGConfigSetContext(const YGConfigRef config, void *context); -WIN_EXPORT void *YGConfigGetContext(const YGConfigRef config); +WIN_EXPORT void YGConfigSetContext(const YGConfigRef config, void* context); +WIN_EXPORT void* YGConfigGetContext(const YGConfigRef config); WIN_EXPORT float YGRoundValueToPixelGrid( const float value, @@ -319,7 +450,9 @@ YG_EXTERN_C_END #include // Calls f on each node in the tree including the given node argument. -extern void YGTraversePreOrder(YGNodeRef const node, std::function&& f); +extern void YGTraversePreOrder( + YGNodeRef const node, + std::function&& f); extern void YGNodeSetChildren( YGNodeRef const owner, diff --git a/yoga_defs.bzl b/yoga_defs.bzl index 9f33a825..1a574c04 100644 --- a/yoga_defs.bzl +++ b/yoga_defs.bzl @@ -190,3 +190,43 @@ def yoga_prebuilt_jar(*args, **kwargs): def is_apple_platform(): return True + +def yoga_apple_binary(): + if is_apple_platform(): + yoganet_ios_srcs = [] + for arch in [ + "iphonesimulator-x86_64", + "iphoneos-arm64", + ]: + name = "yoganet-" + arch + yoganet_ios_srcs.append(":" + name) + native.genrule( + name = name, + srcs = [ + yoga_dep(":yogaApple#%s,static" % arch), + yoga_dep("YogaKit:YogaKitApple#%s,static" % arch), + yoga_dep("csharp:yoganetApple#%s,static" % arch), + ], + out = "libyoga-%s.a" % arch, + cmd = "libtool -static -o $OUT $SRCS", + visibility = [yoga_dep("csharp:yoganet-ios")], + ) + + native.genrule( + name = "yoganet-ios", + srcs = yoganet_ios_srcs, + out = "libyoga.a", + cmd = "lipo $SRCS -create -output $OUT", + visibility = ["PUBLIC"], + ) + + yoganet_macosx_target = "csharp:yoganetAppleMac#macosx-%s,dynamic" + native.genrule( + name = "yoganet-macosx", + srcs = [ + yoga_dep(yoganet_macosx_target % "x86_64"), + ], + out = "libyoga.dylib", + cmd = "lipo $SRCS -create -output $OUT", + visibility = ["PUBLIC"], + )