react-native-windows 0.72.13 → 0.73.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/.flowconfig +16 -5
  2. package/Chakra/ChakraHelpers.cpp +1 -1
  3. package/Chakra/ChakraUtils.cpp +1 -1
  4. package/Chakra/ChakraValue.h +1 -1
  5. package/Common/packages.lock.json +13 -0
  6. package/Directory.Build.props +6 -2
  7. package/Folly/TEMP_UntilFollyUpdate/dynamic-inl.h +1 -10
  8. package/Folly/TEMP_UntilFollyUpdate/hash/Hash.h +1016 -0
  9. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +1 -1
  10. package/Folly/cgmanifest.json +1 -1
  11. package/Folly/packages.lock.json +23 -0
  12. package/Libraries/Animated/Animated.js +1 -1
  13. package/Libraries/Animated/AnimatedImplementation.js +1 -1
  14. package/Libraries/Animated/NativeAnimatedHelper.js +14 -10
  15. package/Libraries/Animated/NativeAnimatedModule.js +6 -2
  16. package/Libraries/Animated/NativeAnimatedTurboModule.js +7 -4
  17. package/Libraries/Animated/animations/Animation.js +57 -3
  18. package/Libraries/Animated/animations/DecayAnimation.js +9 -0
  19. package/Libraries/Animated/animations/SpringAnimation.js +8 -0
  20. package/Libraries/Animated/animations/TimingAnimation.js +8 -0
  21. package/Libraries/Animated/components/AnimatedFlatList.js +2 -1
  22. package/Libraries/Animated/components/AnimatedScrollView.js +2 -0
  23. package/Libraries/Animated/components/AnimatedSectionList.js +2 -1
  24. package/Libraries/Animated/createAnimatedComponent.js +1 -0
  25. package/Libraries/Animated/nodes/AnimatedColor.js +1 -1
  26. package/Libraries/Animated/nodes/AnimatedObject.js +146 -0
  27. package/Libraries/Animated/nodes/AnimatedProps.js +19 -7
  28. package/Libraries/Animated/nodes/AnimatedStyle.js +29 -55
  29. package/Libraries/Animated/nodes/AnimatedValueXY.js +3 -17
  30. package/Libraries/Animated/shouldUseTurboAnimatedModule.js +17 -0
  31. package/Libraries/Animated/useAnimatedProps.js +9 -10
  32. package/Libraries/AppState/AppState.d.ts +1 -1
  33. package/Libraries/AppState/NativeAppState.js +8 -4
  34. package/Libraries/AppTheme/AppTheme.js +5 -5
  35. package/Libraries/BatchedBridge/MessageQueue.js +45 -36
  36. package/Libraries/Blob/Blob.js +6 -2
  37. package/Libraries/Blob/BlobManager.js +9 -10
  38. package/Libraries/Blob/BlobRegistry.js +14 -9
  39. package/Libraries/Blob/File.js +1 -1
  40. package/Libraries/Blob/FileReader.js +1 -2
  41. package/Libraries/Components/Clipboard/Clipboard.d.ts +4 -4
  42. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +3 -1
  43. package/Libraries/Components/Glyph/Glyph.js +1 -1
  44. package/Libraries/Components/Keyboard/KeyboardAvoidingView.js +26 -6
  45. package/Libraries/Components/Keyboard/KeyboardExt.d.ts +4 -1
  46. package/Libraries/Components/Keyboard/KeyboardExt.js +3 -0
  47. package/Libraries/Components/Keyboard/KeyboardExt.js.map +1 -1
  48. package/Libraries/Components/Keyboard/KeyboardExtProps.d.ts +4 -29
  49. package/Libraries/Components/Keyboard/KeyboardExtProps.js +0 -17
  50. package/Libraries/Components/Keyboard/KeyboardExtProps.js.map +1 -1
  51. package/Libraries/Components/Pressable/Pressable.js +3 -2
  52. package/Libraries/Components/Pressable/Pressable.windows.js +4 -3
  53. package/Libraries/Components/Pressable/useAndroidRippleForView.js +1 -1
  54. package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.js +20 -0
  55. package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.windows.js +7 -1
  56. package/Libraries/Components/SafeAreaView/SafeAreaView.js +7 -7
  57. package/Libraries/Components/SafeAreaView/SafeAreaView.windows.js +7 -10
  58. package/Libraries/Components/ScrollView/ScrollView.js +3 -1
  59. package/Libraries/Components/ScrollView/ScrollView.windows.js +3 -1
  60. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +39 -46
  61. package/Libraries/Components/Switch/Switch.js +1 -0
  62. package/Libraries/Components/Switch/Switch.windows.js +259 -0
  63. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +1 -0
  64. package/Libraries/Components/TextInput/TextInput.d.ts +49 -7
  65. package/Libraries/Components/TextInput/TextInput.flow.js +43 -10
  66. package/Libraries/Components/TextInput/TextInput.js +62 -10
  67. package/Libraries/Components/TextInput/TextInput.windows.js +100 -14
  68. package/Libraries/Components/ToastAndroid/{ToastAndroid.ios.js → ToastAndroid.js} +9 -1
  69. package/Libraries/Components/ToastAndroid/ToastAndroid.windows.js +9 -1
  70. package/Libraries/Components/Touchable/TouchableBounce.js +1 -1
  71. package/Libraries/Components/Touchable/TouchableHighlight.js +1 -1
  72. package/Libraries/Components/Touchable/TouchableHighlight.windows.js +1 -1
  73. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -1
  74. package/Libraries/Components/Touchable/TouchableOpacity.js +4 -1
  75. package/Libraries/Components/Touchable/TouchableOpacity.windows.js +4 -1
  76. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +1 -0
  77. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +1 -0
  78. package/Libraries/Components/TraceUpdateOverlay/TraceUpdateOverlay.js +16 -6
  79. package/Libraries/Components/View/ReactNativeStyleAttributes.js +9 -0
  80. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
  81. package/Libraries/Components/View/ReactNativeViewAttributes.windows.js +1 -0
  82. package/Libraries/Components/View/View.js +46 -32
  83. package/Libraries/Components/View/View.windows.js +23 -7
  84. package/Libraries/Components/View/ViewAccessibility.d.ts +27 -1
  85. package/Libraries/Components/View/ViewAccessibility.windows.js +3 -0
  86. package/Libraries/Components/View/ViewNativeComponent.js +1 -0
  87. package/Libraries/Components/View/ViewPropTypes.d.ts +104 -1
  88. package/Libraries/Components/View/ViewPropTypes.js +18 -3
  89. package/Libraries/Components/View/ViewPropTypes.windows.js +33 -3
  90. package/Libraries/Core/Devtools/loadBundleFromServer.js +152 -0
  91. package/Libraries/Core/Devtools/symbolicateStackTrace.js +2 -1
  92. package/Libraries/Core/ExceptionsManager.js +16 -7
  93. package/Libraries/Core/ExtendedError.js +12 -0
  94. package/Libraries/Core/ReactNativeVersion.js +3 -3
  95. package/Libraries/Core/ReactNativeVersionCheck.js +0 -2
  96. package/Libraries/Core/__mocks__/NativeExceptionsManager.js +20 -0
  97. package/Libraries/Core/setUpDeveloperTools.js +5 -1
  98. package/Libraries/Core/setUpIntersectionObserver.js +16 -0
  99. package/Libraries/Core/setUpMutationObserver.js +16 -0
  100. package/Libraries/Core/setUpPerformance.js +6 -13
  101. package/Libraries/Core/setUpPerformanceObserver.js +16 -0
  102. package/Libraries/Core/setUpRegeneratorRuntime.js +4 -2
  103. package/Libraries/DOM/Nodes/ReactNativeElement.js +135 -18
  104. package/Libraries/DOM/Nodes/ReadOnlyCharacterData.js +72 -0
  105. package/Libraries/DOM/Nodes/ReadOnlyElement.js +209 -21
  106. package/Libraries/DOM/Nodes/ReadOnlyNode.js +206 -17
  107. package/Libraries/DOM/Nodes/ReadOnlyText.js +30 -0
  108. package/Libraries/DOM/Nodes/Utilities/Traversal.js +54 -0
  109. package/Libraries/EventEmitter/NativeEventEmitter.d.ts +0 -6
  110. package/Libraries/EventEmitter/RCTDeviceEventEmitter.js +15 -4
  111. package/Libraries/Image/Image.android.js +8 -2
  112. package/Libraries/Image/Image.d.ts +1 -1
  113. package/Libraries/Image/Image.ios.js +4 -1
  114. package/Libraries/Image/Image.windows.js +6 -3
  115. package/Libraries/Image/ImageBackground.js +3 -0
  116. package/Libraries/Inspector/DevtoolsOverlay.js +6 -3
  117. package/Libraries/Inspector/NetworkOverlay.js +2 -2
  118. package/Libraries/Interaction/JSEventLoopWatchdog.js +1 -5
  119. package/Libraries/Interaction/PanResponder.js +1 -4
  120. package/Libraries/IntersectionObserver/IntersectionObserver.js +252 -0
  121. package/Libraries/IntersectionObserver/IntersectionObserverEntry.js +140 -0
  122. package/Libraries/IntersectionObserver/IntersectionObserverManager.js +221 -0
  123. package/Libraries/IntersectionObserver/NativeIntersectionObserver.js +41 -0
  124. package/Libraries/IntersectionObserver/__mocks__/NativeIntersectionObserver.js +162 -0
  125. package/Libraries/LayoutAnimation/LayoutAnimation.js +1 -1
  126. package/Libraries/Lists/FlatList.d.ts +2 -1
  127. package/Libraries/Lists/FlatList.js +15 -5
  128. package/Libraries/Lists/SectionList.js +4 -0
  129. package/Libraries/LogBox/Data/LogBoxLog.js +4 -1
  130. package/Libraries/LogBox/Data/LogBoxSymbolication.js +5 -2
  131. package/Libraries/LogBox/Data/parseLogBoxLog.js +57 -20
  132. package/Libraries/LogBox/UI/AnsiHighlight.js +1 -1
  133. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +24 -31
  134. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +1 -1
  135. package/Libraries/LogBox/UI/LogBoxMessage.js +4 -7
  136. package/Libraries/MutationObserver/MutationObserver.js +184 -0
  137. package/Libraries/MutationObserver/MutationObserverManager.js +218 -0
  138. package/Libraries/MutationObserver/MutationRecord.js +82 -0
  139. package/Libraries/MutationObserver/NativeMutationObserver.js +58 -0
  140. package/Libraries/MutationObserver/__mocks__/NativeMutationObserver.js +327 -0
  141. package/Libraries/NativeComponent/BaseViewConfig.android.js +18 -3
  142. package/Libraries/NativeComponent/BaseViewConfig.ios.js +33 -0
  143. package/Libraries/NativeComponent/BaseViewConfig.windows.js +34 -4
  144. package/Libraries/NativeComponent/NativeComponentRegistry.js +3 -5
  145. package/Libraries/NativeModules/specs/NativeSourceCode.js +6 -6
  146. package/Libraries/Network/RCTNetworking.android.js +2 -1
  147. package/Libraries/Network/XMLHttpRequest.js +1 -1
  148. package/Libraries/NewAppScreen/components/DebugInstructions.js +4 -4
  149. package/Libraries/NewAppScreen/components/DebugInstructions.windows.js +2 -2
  150. package/Libraries/NewAppScreen/components/LearnMoreLinks.js +9 -2
  151. package/Libraries/Performance/QuickPerformanceLogger.js +1 -1
  152. package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +1 -0
  153. package/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts +1 -0
  154. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +3 -1
  155. package/Libraries/Pressability/Pressability.js +28 -3
  156. package/Libraries/Pressability/Pressability.windows.js +30 -5
  157. package/Libraries/ReactNative/AppContainer.js +2 -3
  158. package/Libraries/ReactNative/AppRegistry.d.ts +0 -5
  159. package/Libraries/ReactNative/AppRegistry.js +66 -53
  160. package/Libraries/ReactNative/BridgelessUIManager.js +38 -9
  161. package/Libraries/ReactNative/FabricUIManager.js +143 -34
  162. package/Libraries/ReactNative/I18nManager.js +5 -11
  163. package/Libraries/ReactNative/NativeI18nManager.js +7 -5
  164. package/Libraries/ReactNative/PaperUIManager.windows.js +2 -2
  165. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +151 -0
  166. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance.js +81 -0
  167. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactNativeAttributePayload.js +492 -0
  168. package/Libraries/ReactNative/ReactFabricPublicInstance/warnForStyleProps.js +32 -0
  169. package/Libraries/ReactNative/ReactNativeFeatureFlags.js +19 -3
  170. package/Libraries/ReactNative/UIManager.js +8 -0
  171. package/Libraries/ReactNative/__mocks__/FabricUIManager.js +648 -0
  172. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +38 -2
  173. package/Libraries/Renderer/implementations/ReactFabric-dev.js +27 -27
  174. package/Libraries/Renderer/implementations/ReactFabric-prod.js +3 -3
  175. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +3 -3
  176. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +27 -27
  177. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +3 -3
  178. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +3 -3
  179. package/Libraries/Renderer/shims/ReactFabric.js +5 -6
  180. package/Libraries/Renderer/shims/ReactFeatureFlags.js +2 -3
  181. package/Libraries/Renderer/shims/ReactNative.js +2 -3
  182. package/Libraries/Renderer/shims/ReactNativeTypes.js +35 -17
  183. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +3 -3
  184. package/Libraries/Renderer/shims/createReactNativeComponentClass.js +2 -3
  185. package/Libraries/Settings/{Settings.android.js → Settings.js} +4 -4
  186. package/Libraries/Share/Share.d.ts +3 -9
  187. package/Libraries/StyleSheet/PlatformColorValueTypes.android.js +9 -4
  188. package/Libraries/StyleSheet/PlatformColorValueTypes.ios.js +28 -13
  189. package/Libraries/StyleSheet/PlatformColorValueTypes.windows.js +10 -6
  190. package/Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js +1 -1
  191. package/Libraries/StyleSheet/StyleSheet.d.ts +10 -1
  192. package/Libraries/StyleSheet/StyleSheet.js +3 -0
  193. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +31 -17
  194. package/Libraries/StyleSheet/StyleSheetTypes.js +90 -6
  195. package/Libraries/StyleSheet/flattenStyle.js +4 -0
  196. package/Libraries/StyleSheet/private/_TransformStyle.js +16 -2
  197. package/Libraries/StyleSheet/processColor.js +1 -2
  198. package/Libraries/StyleSheet/processTransformOrigin.js +136 -0
  199. package/Libraries/StyleSheet/splitLayoutProps.js +1 -0
  200. package/Libraries/Text/Text.d.ts +5 -5
  201. package/Libraries/Text/Text.js +17 -10
  202. package/Libraries/Text/Text.windows.js +53 -20
  203. package/Libraries/Text/TextProps.windows.js +275 -0
  204. package/Libraries/TurboModule/TurboModuleRegistry.js +47 -7
  205. package/Libraries/TurboModule/samples/NativeSampleTurboModule.js +6 -0
  206. package/Libraries/Types/CoreEventTypes.d.ts +5 -2
  207. package/Libraries/Utilities/GlobalPerformanceLogger.js +2 -12
  208. package/Libraries/Utilities/NativeDeviceInfo.js +8 -9
  209. package/Libraries/Utilities/NativePlatformConstantsAndroid.js +23 -18
  210. package/Libraries/Utilities/NativePlatformConstantsIOS.js +16 -13
  211. package/Libraries/Utilities/NativePlatformConstantsWin.js +13 -10
  212. package/Libraries/Utilities/PerformanceLoggerContext.js +1 -1
  213. package/Libraries/Utilities/Platform.android.js +12 -8
  214. package/Libraries/Utilities/Platform.d.ts +1 -0
  215. package/Libraries/Utilities/Platform.flow.js +84 -0
  216. package/Libraries/Utilities/Platform.flow.windows.js +111 -0
  217. package/Libraries/Utilities/Platform.ios.js +12 -8
  218. package/Libraries/Utilities/Platform.windows.js +12 -8
  219. package/Libraries/Utilities/PolyfillFunctions.js +1 -1
  220. package/Libraries/Utilities/ReactNativeTestTools.js +1 -2
  221. package/Libraries/Utilities/SceneTracker.js +1 -1
  222. package/Libraries/Utilities/createPerformanceLogger.js +63 -32
  223. package/Libraries/Utilities/useColorScheme.js +7 -8
  224. package/Libraries/WebPerformance/MemoryInfo.js +1 -1
  225. package/Libraries/WebPerformance/NativePerformance.js +3 -8
  226. package/Libraries/WebPerformance/NativePerformanceObserver.js +4 -0
  227. package/Libraries/WebPerformance/Performance.js +42 -15
  228. package/Libraries/WebPerformance/PerformanceEntry.js +14 -6
  229. package/Libraries/WebPerformance/PerformanceEventTiming.js +18 -1
  230. package/Libraries/WebPerformance/ReactNativeStartupTiming.js +40 -14
  231. package/Libraries/WebPerformance/__mocks__/NativePerformance.js +4 -2
  232. package/Libraries/WebPerformance/__mocks__/NativePerformanceObserver.js +21 -3
  233. package/Libraries/__tests__/ViewWindows-test.js +3 -3
  234. package/Libraries/platform-types.d.ts +6 -2
  235. package/Libraries/promiseRejectionTrackingOptions.js +1 -3
  236. package/Libraries/vendor/emitter/EventEmitter.js +20 -18
  237. package/Microsoft.ReactNative/Composition.Input.idl +103 -0
  238. package/Microsoft.ReactNative/CompositionContext.idl +31 -8
  239. package/Microsoft.ReactNative/CompositionRootView.idl +8 -4
  240. package/Microsoft.ReactNative/CompositionSwitcher.idl +28 -17
  241. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +15 -28
  242. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +7 -10
  243. package/Microsoft.ReactNative/Fabric/ComponentView.h +42 -4
  244. package/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp +57 -4
  245. package/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h +22 -1
  246. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +137 -0
  247. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +59 -0
  248. package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +8 -2
  249. package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +575 -0
  250. package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +170 -0
  251. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +890 -226
  252. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.h +38 -6
  253. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper_emptyimpl.cpp +79 -0
  254. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +130 -27
  255. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +6 -1
  256. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +382 -228
  257. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +35 -8
  258. package/Microsoft.ReactNative/Fabric/Composition/CompositionHelpers.h +46 -8
  259. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +5 -21
  260. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h +1 -1
  261. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +232 -4
  262. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +36 -1
  263. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +51 -14
  264. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +15 -6
  265. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp +123 -0
  266. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService_emptyimpl.cpp +18 -0
  267. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +333 -137
  268. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +52 -8
  269. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +32 -26
  270. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +5 -3
  271. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +183 -175
  272. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +7 -4
  273. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +101 -2
  274. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +46 -2
  275. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +36 -9
  276. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +8 -2
  277. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +247 -42
  278. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +25 -8
  279. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +78 -50
  280. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +12 -4
  281. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +26 -28
  282. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +429 -89
  283. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +24 -3
  284. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +1 -0
  285. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +3 -2
  286. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +5 -7
  287. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -6
  288. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp +1 -7
  289. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +1 -17
  290. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +74 -3
  291. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +12 -0
  292. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +53 -59
  293. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h +3 -2
  294. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +5 -4
  295. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +2 -1
  296. package/Microsoft.ReactNative/Fabric/ImageRequest.cpp +1 -1
  297. package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +1 -1
  298. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +3 -4
  299. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformTouch.h +10 -0
  300. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +59 -0
  301. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.h +31 -0
  302. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +69 -0
  303. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +25 -2
  304. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +23 -0
  305. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/KeyEvent.h +113 -0
  306. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/WindowsViewEvents.h +75 -0
  307. package/Microsoft.ReactNative/Fabric/platform/react/renderer/core/graphicsConversions.h +18 -21
  308. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Color.cpp +158 -7
  309. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Color.h +15 -17
  310. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +1 -1
  311. package/Microsoft.ReactNative/GlyphViewManager.cpp +1 -1
  312. package/Microsoft.ReactNative/IJSValueReader.idl +2 -2
  313. package/Microsoft.ReactNative/IJSValueWriter.idl +2 -2
  314. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +23 -1
  315. package/Microsoft.ReactNative/IReactContext.cpp +1 -1
  316. package/Microsoft.ReactNative/IReactNotificationService.cpp +4 -3
  317. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -4
  318. package/Microsoft.ReactNative/Modules/AlertModule.cpp +2 -2
  319. package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedNodeManager.cpp +1 -2
  320. package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedNodeManager.h +1 -1
  321. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.cpp +3 -4
  322. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +1 -1
  323. package/Microsoft.ReactNative/Modules/AppStateModule.h +2 -2
  324. package/Microsoft.ReactNative/Modules/AppearanceModule.h +1 -1
  325. package/Microsoft.ReactNative/Modules/DeviceInfoModule.cpp +4 -2
  326. package/Microsoft.ReactNative/Modules/DeviceInfoModule.h +1 -1
  327. package/Microsoft.ReactNative/Modules/I18nManagerModule.cpp +2 -2
  328. package/Microsoft.ReactNative/Modules/I18nManagerModule.h +1 -1
  329. package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +21 -15
  330. package/Microsoft.ReactNative/Modules/PaperUIManagerModule.cpp +10 -6
  331. package/Microsoft.ReactNative/Modules/PaperUIManagerModule.h +4 -1
  332. package/Microsoft.ReactNative/QuirkSettings.idl +1 -1
  333. package/Microsoft.ReactNative/ReactApplication.cpp +13 -11
  334. package/Microsoft.ReactNative/ReactApplication.h +4 -4
  335. package/Microsoft.ReactNative/ReactCoreInjection.h +6 -5
  336. package/Microsoft.ReactNative/ReactHost/JSCallInvokerScheduler.cpp +2 -2
  337. package/Microsoft.ReactNative/ReactHost/MsoUtils.cpp +1 -1
  338. package/Microsoft.ReactNative/ReactHost/React.h +3 -6
  339. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +0 -16
  340. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +8 -16
  341. package/Microsoft.ReactNative/ReactInstanceSettings.cpp +6 -5
  342. package/Microsoft.ReactNative/ReactInstanceSettings.h +7 -7
  343. package/Microsoft.ReactNative/ReactNativeHost.h +4 -4
  344. package/Microsoft.ReactNative/ReactRootView.cpp +5 -4
  345. package/Microsoft.ReactNative/ReactRootView.h +2 -2
  346. package/Microsoft.ReactNative/ReactSupport.h +1 -1
  347. package/Microsoft.ReactNative/RedBox.cpp +1 -1
  348. package/Microsoft.ReactNative/RedBoxHandler.idl +1 -1
  349. package/Microsoft.ReactNative/Utils/UwpPreparedScriptStore.h +1 -1
  350. package/Microsoft.ReactNative/Utils/ValueUtils.cpp +49 -21
  351. package/Microsoft.ReactNative/Utils/ValueUtils.h +2 -1
  352. package/Microsoft.ReactNative/Views/DynamicAutomationPeer.cpp +31 -59
  353. package/Microsoft.ReactNative/Views/DynamicAutomationPeer.h +3 -4
  354. package/Microsoft.ReactNative/Views/DynamicAutomationProperties.cpp +15 -46
  355. package/Microsoft.ReactNative/Views/DynamicAutomationProperties.h +5 -13
  356. package/Microsoft.ReactNative/Views/FlyoutViewManager.cpp +4 -4
  357. package/Microsoft.ReactNative/Views/FrameworkElementTransferProperties.cpp +2 -8
  358. package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +127 -86
  359. package/Microsoft.ReactNative/Views/ICompositionRootView.h +1 -1
  360. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
  361. package/Microsoft.ReactNative/Views/Image/Microsoft.UI.Composition.Effects_Impl.h +2 -2
  362. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +1 -1
  363. package/Microsoft.ReactNative/Views/SIPEventHandler.cpp +5 -5
  364. package/Microsoft.ReactNative/Views/SIPEventHandler.h +1 -1
  365. package/Microsoft.ReactNative/Views/ShadowNodeBase.h +8 -5
  366. package/Microsoft.ReactNative/Views/SwitchViewManager.cpp +2 -2
  367. package/Microsoft.ReactNative/Views/Text/TextTransformVisitor.cpp +1 -1
  368. package/Microsoft.ReactNative/Views/TextInputViewManager.cpp +32 -14
  369. package/Microsoft.ReactNative/Views/TouchEventHandler.cpp +1 -1
  370. package/Microsoft.ReactNative/Views/ViewManagerBase.cpp +14 -2
  371. package/Microsoft.ReactNative/Views/ViewManagerBase.h +1 -1
  372. package/Microsoft.ReactNative/Views/ViewPanel.cpp +20 -219
  373. package/Microsoft.ReactNative/Views/ViewPanel.h +0 -30
  374. package/Microsoft.ReactNative/Views/ViewViewManager.cpp +17 -158
  375. package/Microsoft.ReactNative/Views/cppwinrt/DynamicAutomationPeer.idl +9 -12
  376. package/Microsoft.ReactNative/Views/cppwinrt/ViewPanel.idl +1 -9
  377. package/Microsoft.ReactNative/XamlHelper.cpp +1 -1
  378. package/Microsoft.ReactNative/XamlHelper.h +1 -1
  379. package/Microsoft.ReactNative/packages.lock.json +128 -0
  380. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +1 -1
  381. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +1 -1
  382. package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.cpp +2 -2
  383. package/Microsoft.ReactNative.Cxx/JSValue.h +2 -2
  384. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +0 -1
  385. package/Microsoft.ReactNative.Cxx/NativeModules.h +4 -4
  386. package/Microsoft.ReactNative.Cxx/ReactHandleHelper.h +1 -1
  387. package/Microsoft.ReactNative.Cxx/ReactNonAbiValue.h +2 -2
  388. package/Microsoft.ReactNative.Cxx/ReactNotificationService.h +10 -9
  389. package/Microsoft.ReactNative.Cxx/ReactPropertyBag.h +13 -12
  390. package/Microsoft.ReactNative.Managed/JSValueReaderGenerator.cs +5 -5
  391. package/Microsoft.ReactNative.Managed/JSValueWriterGenerator.cs +5 -5
  392. package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +8 -2
  393. package/Microsoft.ReactNative.Managed/ReactPackageBuilderExtensions.cs +1 -1
  394. package/Microsoft.ReactNative.Managed/ReflectionReactPackageProvider.cs +1 -1
  395. package/Microsoft.ReactNative.Managed/packages.lock.json +9 -9
  396. package/Microsoft.ReactNative.Managed.CodeGen/CodeAnalyzer.cs +2 -0
  397. package/Microsoft.ReactNative.Managed.CodeGen/CodeGenerator.Module.cs +4 -2
  398. package/Microsoft.ReactNative.Managed.CodeGen/CodeGenerator.ViewManager.cs +1 -1
  399. package/Microsoft.ReactNative.Managed.CodeGen/DiagnosticDescriptors.cs +1 -1
  400. package/Microsoft.ReactNative.Managed.CodeGen/packages.lock.json +3197 -0
  401. package/Mso/compilerAdapters/compilerFeatures.h +1 -1
  402. package/Mso/compilerAdapters/functionDecorations.h +6 -6
  403. package/Mso/debugAssertApi/debugAssertDetails.h +1 -1
  404. package/Mso/dispatchQueue/dispatchQueue.h +3 -3
  405. package/Mso/motifCpp/motifCppTest.h +1 -1
  406. package/Mso/motifCpp/testCheck.h +1 -1
  407. package/Mso/oacr/oacr.h +1 -1
  408. package/Mso/smartPtr/smartPointerBase.h +1 -1
  409. package/Mso/src/dispatchQueue/looperScheduler.cpp +2 -2
  410. package/Mso/src/dispatchQueue/queueService.cpp +1 -1
  411. package/Mso/src/dispatchQueue/taskQueue.h +1 -1
  412. package/Mso/src/dispatchQueue/threadPoolScheduler_win.cpp +2 -2
  413. package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +122 -45
  414. package/Mso/src/eventWaitHandle/eventWaitHandleImpl_win.cpp +2 -2
  415. package/Mso/src/future/futureImpl.cpp +5 -5
  416. package/Mso/src/future/futureImpl.h +1 -1
  417. package/PropertySheets/External/Microsoft.ReactNative.Common.props +3 -0
  418. package/PropertySheets/External/{Microsoft.ReactNative.WinAppSDK.Common.props → Microsoft.ReactNative.Composition.Common.props} +2 -2
  419. package/PropertySheets/External/{Microsoft.ReactNative.WinAppSDK.CSharpApp.props → Microsoft.ReactNative.Composition.CppApp.props} +7 -10
  420. package/PropertySheets/External/Microsoft.ReactNative.Composition.CppApp.targets +19 -0
  421. package/PropertySheets/External/Microsoft.ReactNative.Composition.Package.props +14 -0
  422. package/PropertySheets/External/Microsoft.ReactNative.Composition.Package.targets +18 -0
  423. package/PropertySheets/External/Microsoft.ReactNative.WindowsSdk.Default.props +1 -1
  424. package/PropertySheets/Generated/PackageVersion.g.props +4 -4
  425. package/PropertySheets/HybridCRT.props +34 -0
  426. package/PropertySheets/JSEngine.props +1 -2
  427. package/PropertySheets/React.Cpp.props +0 -1
  428. package/PropertySheets/Warnings.props +1 -1
  429. package/PropertySheets/WinUI.props +1 -1
  430. package/ReactCommon/ReactCommon.vcxproj +15 -9
  431. package/ReactCommon/ReactCommon.vcxproj.filters +0 -3
  432. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +32 -5
  433. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/Bridging.h +20 -0
  434. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp +1038 -0
  435. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp +228 -38
  436. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/conversions.h +895 -0
  437. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/mounting/ShadowTree.cpp +543 -0
  438. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManagerBinding.cpp +1509 -0
  439. package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/bits/NumericBitfield.h +67 -0
  440. package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/config/Config.h +93 -0
  441. package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h +88 -0
  442. package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.cpp +606 -0
  443. package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h +344 -0
  444. package/ReactCommon/Yoga.cpp +497 -3895
  445. package/ReactCommon/packages.lock.json +30 -0
  446. package/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 +22 -0
  447. package/Scripts/OfficeReact.Win32.nuspec +1 -0
  448. package/Scripts/rnw-dependencies.ps1 +79 -26
  449. package/Shared/BaseScriptStoreImpl.cpp +42 -13
  450. package/Shared/BaseScriptStoreImpl.h +1 -1
  451. package/Shared/Composition/AutoDraw.h +36 -0
  452. package/Shared/CxxMessageQueue.cpp +1 -1
  453. package/Shared/DevSettings.h +3 -0
  454. package/Shared/DevSupportManager.h +1 -1
  455. package/Shared/Hasher.cpp +64 -0
  456. package/Shared/Hasher.h +24 -0
  457. package/Shared/HermesRuntimeHolder.cpp +6 -6
  458. package/Shared/IDevSupportManager.h +1 -1
  459. package/Shared/JSI/ChakraApi.cpp +1 -1
  460. package/Shared/JSI/ChakraRuntime.cpp +10 -10
  461. package/Shared/JSI/ChakraRuntime.h +6 -6
  462. package/Shared/JSI/V8RuntimeHolder.cpp +1 -1
  463. package/Shared/Modules/IRequestBodyHandler.h +1 -1
  464. package/Shared/Modules/IUriHandler.h +1 -1
  465. package/Shared/Modules/PlatformConstantsModule.cpp +1 -1
  466. package/Shared/Modules/WebSocketModule.cpp +1 -1
  467. package/Shared/Networking/DefaultBlobResource.cpp +2 -2
  468. package/Shared/Networking/OriginPolicyHttpFilter.cpp +22 -16
  469. package/Shared/Networking/OriginPolicyHttpFilter.h +12 -11
  470. package/Shared/OInstance.cpp +9 -23
  471. package/Shared/OInstance.h +1 -1
  472. package/Shared/PackagerConnection.h +1 -1
  473. package/Shared/SafeLoadLibrary.cpp +8 -44
  474. package/Shared/SafeLoadLibrary.h +1 -5
  475. package/Shared/Shared.vcxitems +50 -20
  476. package/Shared/Shared.vcxitems.filters +26 -17
  477. package/Shared/Threading/BatchingQueueThread.cpp +5 -5
  478. package/Shared/Threading/BatchingQueueThread.h +4 -4
  479. package/Shared/TurboModuleManager.cpp +1 -1
  480. package/Shared/Utils.cpp +1 -1
  481. package/Shared/tracing/fbsystrace.h +1 -1
  482. package/codegen/NativeAnimatedModuleSpec.g.h +2 -0
  483. package/codegen/NativeAnimatedTurboModuleSpec.g.h +2 -0
  484. package/codegen/NativeAppStateSpec.g.h +11 -21
  485. package/codegen/NativeDeviceInfoSpec.g.h +4 -14
  486. package/codegen/NativeI18nManagerSpec.g.h +6 -16
  487. package/codegen/NativeIntersectionObserverSpec.g.h +96 -0
  488. package/codegen/NativeMutationObserverSpec.g.h +90 -0
  489. package/codegen/NativePerformanceObserverSpec.g.h +19 -13
  490. package/codegen/NativePerformanceSpec.g.h +6 -23
  491. package/codegen/NativePlatformConstantsAndroidSpec.g.h +22 -30
  492. package/codegen/NativePlatformConstantsIOSSpec.g.h +17 -25
  493. package/codegen/NativePlatformConstantsWinSpec.g.h +14 -22
  494. package/codegen/NativeSampleTurboModuleSpec.g.h +36 -0
  495. package/codegen/NativeSourceCodeSpec.g.h +3 -13
  496. package/codegen/react/components/rnwcore/EventEmitters.cpp +85 -58
  497. package/codegen/react/components/rnwcore/EventEmitters.h +17 -35
  498. package/codegen/react/components/rnwcore/Props.h +16 -17
  499. package/codegen/rnwcoreJSI-generated.cpp +1462 -319
  500. package/codegen/rnwcoreJSI.h +1609 -462
  501. package/fmt/packages.lock.json +13 -0
  502. package/index.windows.js +3 -3
  503. package/{Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js → jest/ReactNativeInternalFeatureFlagsMock.js} +2 -1
  504. package/jest/__tests__/setup-test.js +18 -0
  505. package/jest/mockModal.js +6 -4
  506. package/jest/setup.js +61 -30
  507. package/just-task.js +1 -0
  508. package/package.json +37 -42
  509. package/template/cs-app/proj/MyApp.csproj +0 -1
  510. package/template/cs-lib/proj/MyLib.csproj +0 -1
  511. package/templates/.clang-format +4 -0
  512. package/templates/cpp-app/metro.config.js +51 -0
  513. package/templates/cpp-app/template.config.js +119 -0
  514. package/templates/cpp-app/windows/ExperimentalFeatures.props +12 -0
  515. package/templates/cpp-app/windows/MyApp/MyApp.cpp +284 -0
  516. package/templates/cpp-app/windows/MyApp/MyApp.h +3 -0
  517. package/templates/cpp-app/windows/MyApp/MyApp.ico +0 -0
  518. package/templates/cpp-app/windows/MyApp/MyApp.rc +0 -0
  519. package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +142 -0
  520. package/templates/cpp-app/windows/MyApp/MyApp.vcxproj.filters +55 -0
  521. package/templates/cpp-app/windows/MyApp/_gitignore +1 -0
  522. package/templates/cpp-app/windows/MyApp/pch.cpp +1 -0
  523. package/templates/cpp-app/windows/MyApp/pch.h +35 -0
  524. package/templates/cpp-app/windows/MyApp/resource.h +18 -0
  525. package/templates/cpp-app/windows/MyApp/small.ico +0 -0
  526. package/templates/cpp-app/windows/MyApp/targetver.h +8 -0
  527. package/templates/cpp-app/windows/MyApp.Package/Images/LockScreenLogo.scale-200.png +0 -0
  528. package/templates/cpp-app/windows/MyApp.Package/Images/SplashScreen.scale-200.png +0 -0
  529. package/templates/cpp-app/windows/MyApp.Package/Images/Square150x150Logo.scale-200.png +0 -0
  530. package/templates/cpp-app/windows/MyApp.Package/Images/Square44x44Logo.scale-200.png +0 -0
  531. package/templates/cpp-app/windows/MyApp.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png +0 -0
  532. package/templates/cpp-app/windows/MyApp.Package/Images/StoreLogo.png +0 -0
  533. package/templates/cpp-app/windows/MyApp.Package/Images/Wide310x150Logo.scale-200.png +0 -0
  534. package/templates/cpp-app/windows/MyApp.Package/MyApp.Package.wapproj +78 -0
  535. package/{template/cs-app-WinAppSDK/MyApp → templates/cpp-app/windows/MyApp.Package}/Package.appxmanifest +9 -8
  536. package/templates/cpp-app/windows/MyApp.sln +176 -0
  537. package/templates/cpp-app/windows/_gitignore +41 -0
  538. package/templates/old/generateWrapper.js +67 -0
  539. package/templates/old/uwp-cpp-app/template.config.js +15 -0
  540. package/templates/old/uwp-cpp-lib/template.config.js +15 -0
  541. package/templates/old/uwp-cs-app/template.config.js +15 -0
  542. package/templates/old/uwp-cs-lib/template.config.js +15 -0
  543. package/types/experimental.d.ts +44 -0
  544. package/types/index.d.ts +2 -1
  545. package/types/modules/Devtools.d.ts +1 -0
  546. package/types/modules/globals.d.ts +16 -1
  547. package/Libraries/Components/View/ViewWindows.d.ts +0 -19
  548. package/Libraries/Components/View/ViewWindows.js +0 -22
  549. package/Libraries/Components/View/ViewWindows.js.map +0 -1
  550. package/Libraries/Components/View/ViewWindowsProps.d.ts +0 -69
  551. package/Libraries/Components/View/ViewWindowsProps.js +0 -8
  552. package/Libraries/Components/View/ViewWindowsProps.js.map +0 -1
  553. package/Libraries/Utilities/AcessibilityMapping.js +0 -154
  554. package/Libraries/Utilities/NativeDevSplitBundleLoader.js +0 -19
  555. package/Libraries/Utilities/useColorScheme.windows.js +0 -26
  556. package/Microsoft.ReactNative/Fabric/platform/react/components/view/windows/WindowsViewProps.cpp +0 -61
  557. package/Microsoft.ReactNative/Fabric/platform/react/components/view/windows/WindowsViewProps.h +0 -34
  558. package/Microsoft.ReactNative/Fabric/platform/react/components/view/windows/primitives.h +0 -42
  559. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharp.PackageReferences.props +0 -11
  560. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +0 -51
  561. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/TouchEventEmitter.cpp +0 -237
  562. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/TouchEventEmitter.h +0 -59
  563. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/ViewEventEmitter.cpp +0 -159
  564. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/ViewEventEmitter.h +0 -94
  565. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/ViewProps.cpp +0 -465
  566. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/ViewProps.h +0 -116
  567. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/ViewShadowNode.cpp +0 -98
  568. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/primitives.h +0 -326
  569. package/Scripts/Microsoft.ReactNative.WindowsAppSDK.nuspec +0 -30
  570. package/Shared/V8JSIRuntimeHolder.cpp +0 -71
  571. package/Shared/V8JSIRuntimeHolder.h +0 -56
  572. package/codegen/NativeDevSplitBundleLoaderSpec.g.h +0 -34
  573. package/template/cs-app-WinAppSDK/MyApp/App.xaml +0 -16
  574. package/template/cs-app-WinAppSDK/MyApp/App.xaml.cs +0 -70
  575. package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml +0 -14
  576. package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml.cs +0 -38
  577. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-arm64.pubxml +0 -19
  578. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x64.pubxml +0 -19
  579. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x86.pubxml +0 -19
  580. package/template/cs-app-WinAppSDK/MyApp/Properties/launchSettings.json +0 -10
  581. package/template/cs-app-WinAppSDK/MyApp/app.manifest +0 -15
  582. package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +0 -24
  583. package/template/cs-app-WinAppSDK/proj/MyApp.csproj +0 -53
  584. package/template/cs-app-WinAppSDK/proj/MyApp.sln +0 -43
  585. package/template/cs-app-WinAppSDK/proj/NuGet_Config +0 -19
  586. /package/Libraries/Components/DrawerAndroid/{DrawerLayoutAndroid.ios.js → DrawerLayoutAndroid.js} +0 -0
  587. /package/Libraries/{Renderer/public → ReactNative/ReactFabricPublicInstance}/ReactFabricPublicInstanceUtils.js +0 -0
@@ -5,211 +5,117 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ #include <yoga/Yoga-internal.h>
8
9
  #include "Yoga.h"
9
- #include <float.h>
10
- #include <string.h>
11
- #include <algorithm>
12
- #include <atomic>
13
- #include <memory>
14
- #include "Utils.h"
15
- #include "YGNode.h"
16
- #include "YGNodePrint.h"
17
- #include "Yoga-internal.h"
18
- #include "event/event.h"
19
- #include "log.h"
20
- #ifdef _MSC_VER
21
- #include <float.h>
22
-
23
- /* define fmaxf if < VC12 */
24
- #if _MSC_VER < 1800
25
- __forceinline const float fmaxf(const float a, const float b) {
26
- return (a > b) ? a : b;
27
- }
28
- #endif
29
- #endif
30
-
10
+ #include <yoga/algorithm/Cache.h>
11
+ #include <yoga/algorithm/CalculateLayout.h>
12
+ #include <yoga/algorithm/PixelGrid.h>
13
+ #include <yoga/debug/AssertFatal.h>
14
+ #include <yoga/debug/Log.h>
15
+ #include <yoga/debug/NodeToString.h>
16
+ #include <yoga/event/event.h>
17
+ #include <yoga/node/Node.h>
18
+
19
+ using namespace facebook;
31
20
  using namespace facebook::yoga;
32
- using detail::Log;
33
-
34
- #ifdef ANDROID
35
- static int YGAndroidLog(
36
- const YGConfigRef config,
37
- const YGNodeRef node,
38
- YGLogLevel level,
39
- const char *format,
40
- va_list args);
41
- #else
42
- static int YGDefaultLog(
43
- const YGConfigRef config,
44
- const YGNodeRef node,
45
- YGLogLevel level,
46
- const char *format,
47
- va_list args);
48
- #endif
49
21
 
50
- #ifdef ANDROID
51
- #include <android/log.h>
52
- static int YGAndroidLog(
53
- const YGConfigRef config,
54
- const YGNodeRef node,
55
- YGLogLevel level,
56
- const char *format,
57
- va_list args) {
58
- int androidLevel = YGLogLevelDebug;
59
- switch (level) {
60
- case YGLogLevelFatal:
61
- androidLevel = ANDROID_LOG_FATAL;
62
- break;
63
- case YGLogLevelError:
64
- androidLevel = ANDROID_LOG_ERROR;
65
- break;
66
- case YGLogLevelWarn:
67
- androidLevel = ANDROID_LOG_WARN;
68
- break;
69
- case YGLogLevelInfo:
70
- androidLevel = ANDROID_LOG_INFO;
71
- break;
72
- case YGLogLevelDebug:
73
- androidLevel = ANDROID_LOG_DEBUG;
74
- break;
75
- case YGLogLevelVerbose:
76
- androidLevel = ANDROID_LOG_VERBOSE;
77
- break;
78
- }
79
- const int result = __android_log_vprint(androidLevel, "yoga", format, args);
80
- return result;
22
+ bool YGFloatIsUndefined(const float value) {
23
+ return yoga::isUndefined(value);
81
24
  }
82
- #else
83
- #define YG_UNUSED(x) (void)(x);
84
25
 
85
- static int YGDefaultLog(
86
- const YGConfigRef config,
87
- const YGNodeRef node,
88
- YGLogLevel level,
89
- const char *format,
90
- va_list args) {
91
- YG_UNUSED(config);
92
- YG_UNUSED(node);
93
- switch (level) {
94
- case YGLogLevelError:
95
- case YGLogLevelFatal:
96
- return vfprintf(stderr, format, args);
97
- case YGLogLevelWarn:
98
- case YGLogLevelInfo:
99
- case YGLogLevelDebug:
100
- case YGLogLevelVerbose:
101
- default:
102
- return vprintf(format, args);
103
- }
26
+ void* YGNodeGetContext(YGNodeConstRef node) {
27
+ return resolveRef(node)->getContext();
104
28
  }
105
29
 
106
- #undef YG_UNUSED
107
- #endif
108
-
109
- static inline bool YGDoubleIsUndefined(const double value) {
110
- return facebook::yoga::isUndefined(value);
111
- }
112
-
113
- YOGA_EXPORT bool YGFloatIsUndefined(const float value) {
114
- return facebook::yoga::isUndefined(value);
30
+ void YGNodeSetContext(YGNodeRef node, void* context) {
31
+ return resolveRef(node)->setContext(context);
115
32
  }
116
33
 
117
- YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) {
118
- return node->getContext();
34
+ YGConfigConstRef YGNodeGetConfig(YGNodeRef node) {
35
+ return resolveRef(node)->getConfig();
119
36
  }
120
37
 
121
- YOGA_EXPORT void YGNodeSetContext(YGNodeRef node, void* context) {
122
-
123
- return node->setContext(context);
38
+ void YGNodeSetConfig(YGNodeRef node, YGConfigRef config) {
39
+ resolveRef(node)->setConfig(resolveRef(config));
124
40
  }
125
41
 
126
- YOGA_EXPORT bool YGNodeHasMeasureFunc(YGNodeRef node) {
127
- return node->hasMeasureFunc();
42
+ bool YGNodeHasMeasureFunc(YGNodeConstRef node) {
43
+ return resolveRef(node)->hasMeasureFunc();
128
44
  }
129
45
 
130
- YOGA_EXPORT void YGNodeSetMeasureFunc(
131
- YGNodeRef node,
132
- YGMeasureFunc measureFunc) {
133
- node->setMeasureFunc(measureFunc);
46
+ void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc) {
47
+ resolveRef(node)->setMeasureFunc(measureFunc);
134
48
  }
135
49
 
136
- YOGA_EXPORT bool YGNodeHasBaselineFunc(YGNodeRef node) {
137
- return node->hasBaselineFunc();
50
+ bool YGNodeHasBaselineFunc(YGNodeConstRef node) {
51
+ return resolveRef(node)->hasBaselineFunc();
138
52
  }
139
53
 
140
- YOGA_EXPORT void YGNodeSetBaselineFunc(
141
- YGNodeRef node,
142
- YGBaselineFunc baselineFunc) {
143
- node->setBaselineFunc(baselineFunc);
54
+ void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc) {
55
+ resolveRef(node)->setBaselineFunc(baselineFunc);
144
56
  }
145
57
 
146
- YOGA_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node) {
147
- return node->getDirtied();
58
+ YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeConstRef node) {
59
+ return resolveRef(node)->getDirtiedFunc();
148
60
  }
149
61
 
150
- YOGA_EXPORT void YGNodeSetDirtiedFunc(
151
- YGNodeRef node,
152
- YGDirtiedFunc dirtiedFunc) {
153
- node->setDirtiedFunc(dirtiedFunc);
62
+ void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc) {
63
+ resolveRef(node)->setDirtiedFunc(dirtiedFunc);
154
64
  }
155
65
 
156
- YOGA_EXPORT void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc) {
157
- node->setPrintFunc(printFunc);
66
+ void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc) {
67
+ resolveRef(node)->setPrintFunc(printFunc);
158
68
  }
159
69
 
160
- YOGA_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node) {
161
- return node->getHasNewLayout();
70
+ bool YGNodeGetHasNewLayout(YGNodeConstRef node) {
71
+ return resolveRef(node)->getHasNewLayout();
162
72
  }
163
73
 
164
- YOGA_EXPORT void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled) {
165
- config->printTree = enabled;
74
+ void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled) {
75
+ resolveRef(config)->setShouldPrintTree(enabled);
166
76
  }
167
77
 
168
- YOGA_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) {
169
- node->setHasNewLayout(hasNewLayout);
78
+ void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) {
79
+ resolveRef(node)->setHasNewLayout(hasNewLayout);
170
80
  }
171
81
 
172
- YOGA_EXPORT YGNodeType YGNodeGetNodeType(YGNodeRef node) {
173
- return node->getNodeType();
82
+ YGNodeType YGNodeGetNodeType(YGNodeConstRef node) {
83
+ return unscopedEnum(resolveRef(node)->getNodeType());
174
84
  }
175
85
 
176
- YOGA_EXPORT void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) {
177
- return node->setNodeType(nodeType);
86
+ void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) {
87
+ return resolveRef(node)->setNodeType(scopedEnum(nodeType));
178
88
  }
179
89
 
180
- YOGA_EXPORT bool YGNodeIsDirty(YGNodeRef node) {
181
- return node->isDirty();
90
+ bool YGNodeIsDirty(YGNodeConstRef node) {
91
+ return resolveRef(node)->isDirty();
182
92
  }
183
93
 
184
- YOGA_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(
185
- const YGNodeRef node) {
186
- return node->markDirtyAndPropogateDownwards();
94
+ void YGNodeMarkDirtyAndPropagateToDescendants(const YGNodeRef node) {
95
+ return resolveRef(node)->markDirtyAndPropagateDownwards();
187
96
  }
188
97
 
189
- int32_t gConfigInstanceCount = 0;
190
-
191
- YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
192
- const YGNodeRef node = new YGNode{config};
193
- YGAssert(config != nullptr, "Tried to construct YGNode with null config");
194
- YGAssertWithConfig(
195
- config, node != nullptr, "Could not allocate memory for node");
98
+ YGNodeRef YGNodeNewWithConfig(const YGConfigConstRef config) {
99
+ auto* node = new yoga::Node{resolveRef(config)};
100
+ yoga::assertFatal(
101
+ config != nullptr, "Tried to construct YGNode with null config");
196
102
  Event::publish<Event::NodeAllocation>(node, {config});
197
103
 
198
104
  return node;
199
105
  }
200
106
 
201
- YOGA_EXPORT YGConfigRef YGConfigGetDefault() {
202
- static YGConfigRef defaultConfig = YGConfigNew();
203
- return defaultConfig;
107
+ YGConfigConstRef YGConfigGetDefault() {
108
+ return &yoga::Config::getDefault();
204
109
  }
205
110
 
206
- YOGA_EXPORT YGNodeRef YGNodeNew(void) {
111
+ YGNodeRef YGNodeNew(void) {
207
112
  return YGNodeNewWithConfig(YGConfigGetDefault());
208
113
  }
209
114
 
210
- YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) {
211
- YGNodeRef node = new YGNode(*oldNode);
212
- YGAssertWithConfig(
115
+ YGNodeRef YGNodeClone(YGNodeConstRef oldNodeRef) {
116
+ auto oldNode = resolveRef(oldNodeRef);
117
+ const auto node = new yoga::Node(*oldNode);
118
+ yoga::assertFatalWithConfig(
213
119
  oldNode->getConfig(),
214
120
  node != nullptr,
215
121
  "Could not allocate memory for node");
@@ -218,29 +124,37 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) {
218
124
  return node;
219
125
  }
220
126
 
221
- YOGA_EXPORT void YGNodeFree(const YGNodeRef node) {
222
- if (YGNodeRef owner = node->getOwner()) {
127
+ void YGNodeFree(const YGNodeRef nodeRef) {
128
+ const auto node = resolveRef(nodeRef);
129
+
130
+ if (auto owner = node->getOwner()) {
223
131
  owner->removeChild(node);
224
132
  node->setOwner(nullptr);
225
133
  }
226
134
 
227
- const uint32_t childCount = YGNodeGetChildCount(node);
228
- for (uint32_t i = 0; i < childCount; i++) {
229
- const YGNodeRef child = YGNodeGetChild(node, i);
135
+ const size_t childCount = node->getChildCount();
136
+ for (size_t i = 0; i < childCount; i++) {
137
+ auto child = node->getChild(i);
230
138
  child->setOwner(nullptr);
231
139
  }
232
140
 
233
141
  node->clearChildren();
234
- Event::publish<Event::NodeDeallocation>(node, {node->getConfig()});
235
- delete node;
142
+ YGNodeDeallocate(node);
143
+ }
144
+
145
+ void YGNodeDeallocate(const YGNodeRef node) {
146
+ Event::publish<Event::NodeDeallocation>(node, {YGNodeGetConfig(node)});
147
+ delete resolveRef(node);
236
148
  }
237
149
 
238
- YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(
239
- const YGNodeRef root,
150
+ void YGNodeFreeRecursiveWithCleanupFunc(
151
+ const YGNodeRef rootRef,
240
152
  YGNodeCleanupFunc cleanup) {
241
- uint32_t skipped = 0;
242
- while (YGNodeGetChildCount(root) > skipped) {
243
- const YGNodeRef child = YGNodeGetChild(root, skipped);
153
+ const auto root = resolveRef(rootRef);
154
+
155
+ size_t skipped = 0;
156
+ while (root->getChildCount() > skipped) {
157
+ const auto child = root->getChild(skipped);
244
158
  if (child->getOwner() != root) {
245
159
  // Don't free shared nodes that we don't own.
246
160
  skipped += 1;
@@ -255,81 +169,74 @@ YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(
255
169
  YGNodeFree(root);
256
170
  }
257
171
 
258
- YOGA_EXPORT void YGNodeFreeRecursive(const YGNodeRef root) {
172
+ void YGNodeFreeRecursive(const YGNodeRef root) {
259
173
  return YGNodeFreeRecursiveWithCleanupFunc(root, nullptr);
260
174
  }
261
175
 
262
- YOGA_EXPORT void YGNodeReset(YGNodeRef node) {
263
- node->reset();
176
+ void YGNodeReset(YGNodeRef node) {
177
+ resolveRef(node)->reset();
264
178
  }
265
179
 
266
- YOGA_EXPORT int32_t YGConfigGetInstanceCount(void) {
267
- return gConfigInstanceCount;
180
+ YGConfigRef YGConfigNew(void) {
181
+ return new yoga::Config(getDefaultLogger());
268
182
  }
269
183
 
270
- YOGA_EXPORT YGConfigRef YGConfigNew(void) {
271
- #ifdef ANDROID
272
- const YGConfigRef config = new YGConfig(YGAndroidLog);
273
- #else
274
- const YGConfigRef config = new YGConfig(YGDefaultLog);
275
- #endif
276
- gConfigInstanceCount++;
277
- return config;
184
+ void YGConfigFree(const YGConfigRef config) {
185
+ delete resolveRef(config);
278
186
  }
279
187
 
280
- YOGA_EXPORT void YGConfigFree(const YGConfigRef config) {
281
- delete config;
282
- gConfigInstanceCount--;
283
- }
284
-
285
- void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) {
286
- memcpy(dest, src, sizeof(YGConfig));
287
- }
288
-
289
- YOGA_EXPORT void YGNodeSetIsReferenceBaseline(
290
- YGNodeRef node,
291
- bool isReferenceBaseline) {
188
+ void YGNodeSetIsReferenceBaseline(YGNodeRef nodeRef, bool isReferenceBaseline) {
189
+ const auto node = resolveRef(nodeRef);
292
190
  if (node->isReferenceBaseline() != isReferenceBaseline) {
293
191
  node->setIsReferenceBaseline(isReferenceBaseline);
294
- node->markDirtyAndPropogate();
192
+ node->markDirtyAndPropagate();
295
193
  }
296
194
  }
297
195
 
298
- YOGA_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node) {
299
- return node->isReferenceBaseline();
196
+ bool YGNodeIsReferenceBaseline(YGNodeConstRef node) {
197
+ return resolveRef(node)->isReferenceBaseline();
300
198
  }
301
199
 
302
- YOGA_EXPORT void YGNodeInsertChild(
303
- const YGNodeRef owner,
304
- const YGNodeRef child,
305
- const uint32_t index) {
306
- YGAssertWithNode(
200
+ void YGNodeInsertChild(
201
+ const YGNodeRef ownerRef,
202
+ const YGNodeRef childRef,
203
+ const size_t index) {
204
+ auto owner = resolveRef(ownerRef);
205
+ auto child = resolveRef(childRef);
206
+
207
+ yoga::assertFatalWithNode(
307
208
  owner,
308
209
  child->getOwner() == nullptr,
309
210
  "Child already has a owner, it must be removed first.");
310
211
 
311
- YGAssertWithNode(
212
+ yoga::assertFatalWithNode(
312
213
  owner,
313
214
  !owner->hasMeasureFunc(),
314
215
  "Cannot add child: Nodes with measure functions cannot have children.");
315
216
 
316
217
  owner->insertChild(child, index);
317
218
  child->setOwner(owner);
318
- owner->markDirtyAndPropogate();
219
+ owner->markDirtyAndPropagate();
319
220
  }
320
221
 
321
- YOGA_EXPORT void YGNodeSwapChild(
322
- const YGNodeRef owner,
323
- const YGNodeRef child,
324
- const uint32_t index) {
222
+ void YGNodeSwapChild(
223
+ const YGNodeRef ownerRef,
224
+ const YGNodeRef childRef,
225
+ const size_t index) {
226
+ auto owner = resolveRef(ownerRef);
227
+ auto child = resolveRef(childRef);
228
+
325
229
  owner->replaceChild(child, index);
326
230
  child->setOwner(owner);
327
231
  }
328
232
 
329
- YOGA_EXPORT void YGNodeRemoveChild(
330
- const YGNodeRef owner,
331
- const YGNodeRef excludedChild) {
332
- if (YGNodeGetChildCount(owner) == 0) {
233
+ void YGNodeRemoveChild(
234
+ const YGNodeRef ownerRef,
235
+ const YGNodeRef excludedChildRef) {
236
+ auto owner = resolveRef(ownerRef);
237
+ auto excludedChild = resolveRef(excludedChildRef);
238
+
239
+ if (owner->getChildCount() == 0) {
333
240
  // This is an empty set. Nothing to remove.
334
241
  return;
335
242
  }
@@ -343,133 +250,135 @@ YOGA_EXPORT void YGNodeRemoveChild(
343
250
  excludedChild->setLayout({}); // layout is no longer valid
344
251
  excludedChild->setOwner(nullptr);
345
252
  }
346
- owner->markDirtyAndPropogate();
253
+ owner->markDirtyAndPropagate();
347
254
  }
348
255
  }
349
256
 
350
- YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef owner) {
351
- const uint32_t childCount = YGNodeGetChildCount(owner);
257
+ void YGNodeRemoveAllChildren(const YGNodeRef ownerRef) {
258
+ auto owner = resolveRef(ownerRef);
259
+
260
+ const size_t childCount = owner->getChildCount();
352
261
  if (childCount == 0) {
353
262
  // This is an empty set already. Nothing to do.
354
263
  return;
355
264
  }
356
- const YGNodeRef firstChild = YGNodeGetChild(owner, 0);
265
+ auto* firstChild = owner->getChild(0);
357
266
  if (firstChild->getOwner() == owner) {
358
267
  // If the first child has this node as its owner, we assume that this child
359
268
  // set is unique.
360
- for (uint32_t i = 0; i < childCount; i++) {
361
- const YGNodeRef oldChild = YGNodeGetChild(owner, i);
362
- oldChild->setLayout(YGNode().getLayout()); // layout is no longer valid
269
+ for (size_t i = 0; i < childCount; i++) {
270
+ yoga::Node* oldChild = owner->getChild(i);
271
+ oldChild->setLayout({}); // layout is no longer valid
363
272
  oldChild->setOwner(nullptr);
364
273
  }
365
274
  owner->clearChildren();
366
- owner->markDirtyAndPropogate();
275
+ owner->markDirtyAndPropagate();
367
276
  return;
368
277
  }
369
278
  // Otherwise, we are not the owner of the child set. We don't have to do
370
279
  // anything to clear it.
371
- owner->setChildren(YGVector());
372
- owner->markDirtyAndPropogate();
280
+ owner->setChildren({});
281
+ owner->markDirtyAndPropagate();
373
282
  }
374
283
 
375
- static void YGNodeSetChildrenInternal(
376
- YGNodeRef const owner,
377
- const std::vector<YGNodeRef> &children) {
284
+ void YGNodeSetChildren(
285
+ const YGNodeRef ownerRef,
286
+ const YGNodeRef* childrenRefs,
287
+ const size_t count) {
288
+ auto owner = resolveRef(ownerRef);
289
+ auto children = reinterpret_cast<yoga::Node* const*>(childrenRefs);
290
+
378
291
  if (!owner) {
379
292
  return;
380
293
  }
381
- if (children.size() == 0) {
382
- if (YGNodeGetChildCount(owner) > 0) {
383
- for (YGNodeRef const child : owner->getChildren()) {
384
- child->setLayout(YGLayout());
294
+
295
+ const std::vector<yoga::Node*> childrenVector = {children, children + count};
296
+ if (childrenVector.size() == 0) {
297
+ if (owner->getChildCount() > 0) {
298
+ for (auto* child : owner->getChildren()) {
299
+ child->setLayout({});
385
300
  child->setOwner(nullptr);
386
301
  }
387
- owner->setChildren(YGVector());
388
- owner->markDirtyAndPropogate();
302
+ owner->setChildren({});
303
+ owner->markDirtyAndPropagate();
389
304
  }
390
305
  } else {
391
- if (YGNodeGetChildCount(owner) > 0) {
392
- for (YGNodeRef const oldChild : owner->getChildren()) {
306
+ if (owner->getChildCount() > 0) {
307
+ for (auto* oldChild : owner->getChildren()) {
393
308
  // Our new children may have nodes in common with the old children. We
394
309
  // don't reset these common nodes.
395
- if (std::find(children.begin(), children.end(), oldChild) ==
396
- children.end()) {
397
- oldChild->setLayout(YGLayout());
310
+ if (std::find(childrenVector.begin(), childrenVector.end(), oldChild) ==
311
+ childrenVector.end()) {
312
+ oldChild->setLayout({});
398
313
  oldChild->setOwner(nullptr);
399
314
  }
400
315
  }
401
316
  }
402
- owner->setChildren(children);
403
- for (YGNodeRef child : children) {
317
+ owner->setChildren(childrenVector);
318
+ for (yoga::Node* child : childrenVector) {
404
319
  child->setOwner(owner);
405
320
  }
406
- owner->markDirtyAndPropogate();
321
+ owner->markDirtyAndPropagate();
407
322
  }
408
323
  }
409
324
 
410
- YOGA_EXPORT void YGNodeSetChildren(
411
- const YGNodeRef owner,
412
- const YGNodeRef c[],
413
- const uint32_t count) {
414
- const YGVector children = {c, c + count};
415
- YGNodeSetChildrenInternal(owner, children);
416
- }
325
+ YGNodeRef YGNodeGetChild(const YGNodeRef nodeRef, const size_t index) {
326
+ const auto node = resolveRef(nodeRef);
417
327
 
418
- YOGA_EXPORT void YGNodeSetChildren(
419
- YGNodeRef const owner,
420
- const std::vector<YGNodeRef> &children) {
421
- YGNodeSetChildrenInternal(owner, children);
422
- }
423
-
424
- YOGA_EXPORT YGNodeRef
425
- YGNodeGetChild(const YGNodeRef node, const uint32_t index) {
426
328
  if (index < node->getChildren().size()) {
427
329
  return node->getChild(index);
428
330
  }
429
331
  return nullptr;
430
332
  }
431
333
 
432
- YOGA_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node) {
433
- return static_cast<uint32_t>(node->getChildren().size());
334
+ size_t YGNodeGetChildCount(const YGNodeConstRef node) {
335
+ return resolveRef(node)->getChildren().size();
434
336
  }
435
337
 
436
- YOGA_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node) {
437
- return node->getOwner();
338
+ YGNodeRef YGNodeGetOwner(const YGNodeRef node) {
339
+ return resolveRef(node)->getOwner();
438
340
  }
439
341
 
440
- YOGA_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node) {
441
- return node->getOwner();
342
+ YGNodeRef YGNodeGetParent(const YGNodeRef node) {
343
+ return resolveRef(node)->getOwner();
442
344
  }
443
345
 
444
- YOGA_EXPORT void YGNodeMarkDirty(const YGNodeRef node) {
445
- YGAssertWithNode(
346
+ void YGNodeMarkDirty(const YGNodeRef nodeRef) {
347
+ const auto node = resolveRef(nodeRef);
348
+
349
+ yoga::assertFatalWithNode(
446
350
  node,
447
351
  node->hasMeasureFunc(),
448
- "Only leaf nodes with custom measure functions"
352
+ "Only leaf nodes with custom measure functions "
449
353
  "should manually mark themselves as dirty");
450
354
 
451
- node->markDirtyAndPropogate();
355
+ node->markDirtyAndPropagate();
452
356
  }
453
357
 
454
- YOGA_EXPORT void YGNodeCopyStyle(
455
- const YGNodeRef dstNode,
456
- const YGNodeRef srcNode) {
358
+ void YGNodeCopyStyle(
359
+ const YGNodeRef dstNodeRef,
360
+ const YGNodeConstRef srcNodeRef) {
361
+ auto dstNode = resolveRef(dstNodeRef);
362
+ auto srcNode = resolveRef(srcNodeRef);
363
+
457
364
  if (!(dstNode->getStyle() == srcNode->getStyle())) {
458
365
  dstNode->setStyle(srcNode->getStyle());
459
- dstNode->markDirtyAndPropogate();
366
+ dstNode->markDirtyAndPropagate();
460
367
  }
461
368
  }
462
369
 
463
- YOGA_EXPORT float YGNodeStyleGetFlexGrow(const YGNodeConstRef node) {
370
+ float YGNodeStyleGetFlexGrow(const YGNodeConstRef nodeRef) {
371
+ const auto node = resolveRef(nodeRef);
464
372
  return node->getStyle().flexGrow().isUndefined()
465
- ? kDefaultFlexGrow
373
+ ? Style::DefaultFlexGrow
466
374
  : node->getStyle().flexGrow().unwrap();
467
375
  }
468
376
 
469
- YOGA_EXPORT float YGNodeStyleGetFlexShrink(const YGNodeConstRef node) {
377
+ float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) {
378
+ const auto node = resolveRef(nodeRef);
470
379
  return node->getStyle().flexShrink().isUndefined()
471
- ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink
472
- : kDefaultFlexShrink)
380
+ ? (node->getConfig()->useWebDefaults() ? Style::WebDefaultFlexShrink
381
+ : Style::DefaultFlexShrink)
473
382
  : node->getStyle().flexShrink().unwrap();
474
383
  }
475
384
 
@@ -477,37 +386,45 @@ namespace {
477
386
 
478
387
  template <typename T, typename NeedsUpdate, typename Update>
479
388
  void updateStyle(
480
- YGNode *node,
389
+ yoga::Node* node,
481
390
  T value,
482
391
  NeedsUpdate &&needsUpdate,
483
392
  Update &&update) {
484
393
  if (needsUpdate(node->getStyle(), value)) {
485
394
  update(node->getStyle(), value);
486
- node->markDirtyAndPropogate();
395
+ node->markDirtyAndPropagate();
487
396
  }
488
397
  }
489
398
 
490
399
  template <typename Ref, typename T>
491
- void updateStyle(YGNode *node, Ref (YGStyle::*prop)(), T value) {
400
+ void updateStyle(YGNodeRef node, Ref (Style::*prop)(), T value) {
492
401
  updateStyle(
493
- node,
402
+ resolveRef(node),
494
403
  value,
495
- [prop](YGStyle &s, T x) { return (s.*prop)() != x; },
496
- [prop](YGStyle &s, T x) { (s.*prop)() = x; });
404
+ [prop](Style& s, T x) { return (s.*prop)() != x; },
405
+ [prop](Style& s, T x) { (s.*prop)() = x; });
497
406
  }
498
407
 
499
408
  template <typename Ref, typename Idx>
500
409
  void updateIndexedStyleProp(
501
- YGNode *node,
502
- Ref (YGStyle::*prop)(),
410
+ YGNodeRef node,
411
+ Ref (Style::*prop)(),
503
412
  Idx idx,
504
- detail::CompactValue value) {
505
- using detail::CompactValue;
413
+ CompactValue value) {
506
414
  updateStyle(
507
- node,
415
+ resolveRef(node),
416
+ value,
417
+ [idx, prop](Style& s, CompactValue x) { return (s.*prop)()[idx] != x; },
418
+ [idx, prop](Style& s, CompactValue x) { (s.*prop)()[idx] = x; });
419
+ }
420
+
421
+ template <auto GetterT, auto SetterT, typename IdxT>
422
+ void updateIndexedStyleProp(YGNodeRef node, IdxT idx, CompactValue value) {
423
+ updateStyle(
424
+ resolveRef(node),
508
425
  value,
509
- [idx, prop](YGStyle &s, CompactValue x) { return (s.*prop)()[idx] != x; },
510
- [idx, prop](YGStyle &s, CompactValue x) { (s.*prop)()[idx] = x; });
426
+ [idx](Style& s, CompactValue x) { return (s.*GetterT)(idx) != x; },
427
+ [idx](Style& s, CompactValue x) { (s.*SetterT)(idx, x); });
511
428
  }
512
429
 
513
430
  } // namespace
@@ -515,264 +432,214 @@ void updateIndexedStyleProp(
515
432
  // MSVC has trouble inferring the return type of pointer to member functions
516
433
  // with const and non-const overloads, instead of preferring the non-const
517
434
  // overload like clang and GCC. For the purposes of updateStyle(), we can help
518
- // MSVC by specifying that return type explicitely. In combination with
435
+ // MSVC by specifying that return type explicitly. In combination with
519
436
  // decltype, MSVC will prefer the non-const version.
520
- #define MSVC_HINT(PROP) decltype(YGStyle{}.PROP())
437
+ #define MSVC_HINT(PROP) decltype(Style{}.PROP())
521
438
 
522
- YOGA_EXPORT void YGNodeStyleSetDirection(
523
- const YGNodeRef node,
524
- const YGDirection value) {
525
- updateStyle<MSVC_HINT(direction)>(node, &YGStyle::direction, value);
439
+ void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) {
440
+ updateStyle<MSVC_HINT(direction)>(node, &Style::direction, scopedEnum(value));
526
441
  }
527
- YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) {
528
- return node->getStyle().direction();
442
+ YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) {
443
+ return unscopedEnum(resolveRef(node)->getStyle().direction());
529
444
  }
530
445
 
531
- YOGA_EXPORT void YGNodeStyleSetFlexDirection(
446
+ void YGNodeStyleSetFlexDirection(
532
447
  const YGNodeRef node,
533
448
  const YGFlexDirection flexDirection) {
534
449
  updateStyle<MSVC_HINT(flexDirection)>(
535
- node, &YGStyle::flexDirection, flexDirection);
450
+ node, &Style::flexDirection, scopedEnum(flexDirection));
536
451
  }
537
- YOGA_EXPORT YGFlexDirection
538
- YGNodeStyleGetFlexDirection(const YGNodeConstRef node) {
539
- return node->getStyle().flexDirection();
452
+ YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) {
453
+ return unscopedEnum(resolveRef(node)->getStyle().flexDirection());
540
454
  }
541
455
 
542
- YOGA_EXPORT void YGNodeStyleSetJustifyContent(
456
+ void YGNodeStyleSetJustifyContent(
543
457
  const YGNodeRef node,
544
458
  const YGJustify justifyContent) {
545
459
  updateStyle<MSVC_HINT(justifyContent)>(
546
- node, &YGStyle::justifyContent, justifyContent);
460
+ node, &Style::justifyContent, scopedEnum(justifyContent));
547
461
  }
548
- YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) {
549
- return node->getStyle().justifyContent();
462
+ YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) {
463
+ return unscopedEnum(resolveRef(node)->getStyle().justifyContent());
550
464
  }
551
465
 
552
- YOGA_EXPORT void YGNodeStyleSetAlignContent(
466
+ void YGNodeStyleSetAlignContent(
553
467
  const YGNodeRef node,
554
468
  const YGAlign alignContent) {
555
469
  updateStyle<MSVC_HINT(alignContent)>(
556
- node, &YGStyle::alignContent, alignContent);
470
+ node, &Style::alignContent, scopedEnum(alignContent));
557
471
  }
558
- YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) {
559
- return node->getStyle().alignContent();
472
+ YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) {
473
+ return unscopedEnum(resolveRef(node)->getStyle().alignContent());
560
474
  }
561
475
 
562
- YOGA_EXPORT void YGNodeStyleSetAlignItems(
563
- const YGNodeRef node,
564
- const YGAlign alignItems) {
565
- updateStyle<MSVC_HINT(alignItems)>(node, &YGStyle::alignItems, alignItems);
476
+ void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) {
477
+ updateStyle<MSVC_HINT(alignItems)>(
478
+ node, &Style::alignItems, scopedEnum(alignItems));
566
479
  }
567
- YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) {
568
- return node->getStyle().alignItems();
480
+ YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) {
481
+ return unscopedEnum(resolveRef(node)->getStyle().alignItems());
569
482
  }
570
483
 
571
- YOGA_EXPORT void YGNodeStyleSetAlignSelf(
572
- const YGNodeRef node,
573
- const YGAlign alignSelf) {
574
- updateStyle<MSVC_HINT(alignSelf)>(node, &YGStyle::alignSelf, alignSelf);
484
+ void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) {
485
+ updateStyle<MSVC_HINT(alignSelf)>(
486
+ node, &Style::alignSelf, scopedEnum(alignSelf));
575
487
  }
576
- YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) {
577
- return node->getStyle().alignSelf();
488
+ YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) {
489
+ return unscopedEnum(resolveRef(node)->getStyle().alignSelf());
578
490
  }
579
491
 
580
- YOGA_EXPORT void YGNodeStyleSetPositionType(
492
+ void YGNodeStyleSetPositionType(
581
493
  const YGNodeRef node,
582
494
  const YGPositionType positionType) {
583
495
  updateStyle<MSVC_HINT(positionType)>(
584
- node, &YGStyle::positionType, positionType);
496
+ node, &Style::positionType, scopedEnum(positionType));
585
497
  }
586
- YOGA_EXPORT YGPositionType
587
- YGNodeStyleGetPositionType(const YGNodeConstRef node) {
588
- return node->getStyle().positionType();
498
+ YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) {
499
+ return unscopedEnum(resolveRef(node)->getStyle().positionType());
589
500
  }
590
501
 
591
- YOGA_EXPORT void YGNodeStyleSetFlexWrap(
592
- const YGNodeRef node,
593
- const YGWrap flexWrap) {
594
- updateStyle<MSVC_HINT(flexWrap)>(node, &YGStyle::flexWrap, flexWrap);
502
+ void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) {
503
+ updateStyle<MSVC_HINT(flexWrap)>(
504
+ node, &Style::flexWrap, scopedEnum(flexWrap));
595
505
  }
596
- YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) {
597
- return node->getStyle().flexWrap();
506
+ YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) {
507
+ return unscopedEnum(resolveRef(node)->getStyle().flexWrap());
598
508
  }
599
509
 
600
- YOGA_EXPORT void YGNodeStyleSetOverflow(
601
- const YGNodeRef node,
602
- const YGOverflow overflow) {
603
- updateStyle<MSVC_HINT(overflow)>(node, &YGStyle::overflow, overflow);
510
+ void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) {
511
+ updateStyle<MSVC_HINT(overflow)>(
512
+ node, &Style::overflow, scopedEnum(overflow));
604
513
  }
605
- YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) {
606
- return node->getStyle().overflow();
514
+ YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) {
515
+ return unscopedEnum(resolveRef(node)->getStyle().overflow());
607
516
  }
608
517
 
609
- YOGA_EXPORT void YGNodeStyleSetDisplay(
610
- const YGNodeRef node,
611
- const YGDisplay display) {
612
- updateStyle<MSVC_HINT(display)>(node, &YGStyle::display, display);
518
+ void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) {
519
+ updateStyle<MSVC_HINT(display)>(node, &Style::display, scopedEnum(display));
613
520
  }
614
- YOGA_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) {
615
- return node->getStyle().display();
521
+ YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) {
522
+ return unscopedEnum(resolveRef(node)->getStyle().display());
616
523
  }
617
524
 
618
- // TODO(T26792433): Change the API to accept YGFloatOptional.
619
- YOGA_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) {
620
- updateStyle<MSVC_HINT(flex)>(node, &YGStyle::flex, YGFloatOptional{flex});
525
+ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) {
526
+ updateStyle<MSVC_HINT(flex)>(node, &Style::flex, FloatOptional{flex});
621
527
  }
622
528
 
623
- // TODO(T26792433): Change the API to accept YGFloatOptional.
624
- YOGA_EXPORT float YGNodeStyleGetFlex(const YGNodeConstRef node) {
529
+ float YGNodeStyleGetFlex(const YGNodeConstRef nodeRef) {
530
+ const auto node = resolveRef(nodeRef);
625
531
  return node->getStyle().flex().isUndefined()
626
532
  ? YGUndefined
627
533
  : node->getStyle().flex().unwrap();
628
534
  }
629
535
 
630
- // TODO(T26792433): Change the API to accept YGFloatOptional.
631
- YOGA_EXPORT void YGNodeStyleSetFlexGrow(
632
- const YGNodeRef node,
633
- const float flexGrow) {
536
+ void YGNodeStyleSetFlexGrow(const YGNodeRef node, const float flexGrow) {
634
537
  updateStyle<MSVC_HINT(flexGrow)>(
635
- node, &YGStyle::flexGrow, YGFloatOptional{flexGrow});
538
+ node, &Style::flexGrow, FloatOptional{flexGrow});
636
539
  }
637
540
 
638
- // TODO(T26792433): Change the API to accept YGFloatOptional.
639
- YOGA_EXPORT void YGNodeStyleSetFlexShrink(
640
- const YGNodeRef node,
641
- const float flexShrink) {
541
+ void YGNodeStyleSetFlexShrink(const YGNodeRef node, const float flexShrink) {
642
542
  updateStyle<MSVC_HINT(flexShrink)>(
643
- node, &YGStyle::flexShrink, YGFloatOptional{flexShrink});
543
+ node, &Style::flexShrink, FloatOptional{flexShrink});
644
544
  }
645
545
 
646
- YOGA_EXPORT YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) {
647
- YGValue flexBasis = node->getStyle().flexBasis();
546
+ YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) {
547
+ YGValue flexBasis = resolveRef(node)->getStyle().flexBasis();
648
548
  if (flexBasis.unit == YGUnitUndefined || flexBasis.unit == YGUnitAuto) {
649
- // TODO(T26792433): Get rid off the use of YGUndefined at client side
650
549
  flexBasis.value = YGUndefined;
651
550
  }
652
551
  return flexBasis;
653
552
  }
654
553
 
655
- YOGA_EXPORT void YGNodeStyleSetFlexBasis(
656
- const YGNodeRef node,
657
- const float flexBasis) {
658
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(flexBasis);
659
- updateStyle<MSVC_HINT(flexBasis)>(node, &YGStyle::flexBasis, value);
554
+ void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) {
555
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(flexBasis);
556
+ updateStyle<MSVC_HINT(flexBasis)>(node, &Style::flexBasis, value);
660
557
  }
661
558
 
662
- YOGA_EXPORT void YGNodeStyleSetFlexBasisPercent(
559
+ void YGNodeStyleSetFlexBasisPercent(
663
560
  const YGNodeRef node,
664
561
  const float flexBasisPercent) {
665
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(flexBasisPercent);
666
- updateStyle<MSVC_HINT(flexBasis)>(node, &YGStyle::flexBasis, value);
562
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(flexBasisPercent);
563
+ updateStyle<MSVC_HINT(flexBasis)>(node, &Style::flexBasis, value);
667
564
  }
668
565
 
669
- YOGA_EXPORT void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) {
566
+ void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) {
670
567
  updateStyle<MSVC_HINT(flexBasis)>(
671
- node, &YGStyle::flexBasis, detail::CompactValue::ofAuto());
568
+ node, &Style::flexBasis, CompactValue::ofAuto());
672
569
  }
673
570
 
674
- YOGA_EXPORT void YGNodeStyleSetPosition(
675
- YGNodeRef node,
676
- YGEdge edge,
677
- float points) {
678
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(points);
571
+ void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float points) {
572
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
679
573
  updateIndexedStyleProp<MSVC_HINT(position)>(
680
- node, &YGStyle::position, edge, value);
574
+ node, &Style::position, edge, value);
681
575
  }
682
- YOGA_EXPORT void YGNodeStyleSetPositionPercent(
683
- YGNodeRef node,
684
- YGEdge edge,
685
- float percent) {
686
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(percent);
576
+ void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) {
577
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
687
578
  updateIndexedStyleProp<MSVC_HINT(position)>(
688
- node, &YGStyle::position, edge, value);
579
+ node, &Style::position, edge, value);
689
580
  }
690
- YOGA_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) {
691
- return node->getStyle().position()[edge];
581
+ YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) {
582
+ return resolveRef(node)->getStyle().position()[edge];
692
583
  }
693
584
 
694
- YOGA_EXPORT void YGNodeStyleSetMargin(
695
- YGNodeRef node,
696
- YGEdge edge,
697
- float points) {
698
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(points);
699
- updateIndexedStyleProp<MSVC_HINT(margin)>(
700
- node, &YGStyle::margin, edge, value);
585
+ void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) {
586
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
587
+ updateIndexedStyleProp<MSVC_HINT(margin)>(node, &Style::margin, edge, value);
701
588
  }
702
- YOGA_EXPORT void YGNodeStyleSetMarginPercent(
703
- YGNodeRef node,
704
- YGEdge edge,
705
- float percent) {
706
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(percent);
707
- updateIndexedStyleProp<MSVC_HINT(margin)>(
708
- node, &YGStyle::margin, edge, value);
589
+ void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float percent) {
590
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
591
+ updateIndexedStyleProp<MSVC_HINT(margin)>(node, &Style::margin, edge, value);
709
592
  }
710
- YOGA_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) {
593
+ void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) {
711
594
  updateIndexedStyleProp<MSVC_HINT(margin)>(
712
- node, &YGStyle::margin, edge, detail::CompactValue::ofAuto());
595
+ node, &Style::margin, edge, CompactValue::ofAuto());
713
596
  }
714
- YOGA_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) {
715
- return node->getStyle().margin()[edge];
597
+ YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) {
598
+ return resolveRef(node)->getStyle().margin()[edge];
716
599
  }
717
600
 
718
- YOGA_EXPORT void YGNodeStyleSetPadding(
719
- YGNodeRef node,
720
- YGEdge edge,
721
- float points) {
722
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(points);
601
+ void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) {
602
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
723
603
  updateIndexedStyleProp<MSVC_HINT(padding)>(
724
- node, &YGStyle::padding, edge, value);
604
+ node, &Style::padding, edge, value);
725
605
  }
726
- YOGA_EXPORT void YGNodeStyleSetPaddingPercent(
727
- YGNodeRef node,
728
- YGEdge edge,
729
- float percent) {
730
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(percent);
606
+ void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) {
607
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
731
608
  updateIndexedStyleProp<MSVC_HINT(padding)>(
732
- node, &YGStyle::padding, edge, value);
609
+ node, &Style::padding, edge, value);
733
610
  }
734
- YOGA_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) {
735
- return node->getStyle().padding()[edge];
611
+ YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) {
612
+ return resolveRef(node)->getStyle().padding()[edge];
736
613
  }
737
614
 
738
- // TODO(T26792433): Change the API to accept YGFloatOptional.
739
- YOGA_EXPORT void YGNodeStyleSetBorder(
615
+ void YGNodeStyleSetBorder(
740
616
  const YGNodeRef node,
741
617
  const YGEdge edge,
742
618
  const float border) {
743
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(border);
744
- updateIndexedStyleProp<MSVC_HINT(border)>(
745
- node, &YGStyle::border, edge, value);
619
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(border);
620
+ updateIndexedStyleProp<MSVC_HINT(border)>(node, &Style::border, edge, value);
746
621
  }
747
622
 
748
- YOGA_EXPORT float YGNodeStyleGetBorder(
749
- const YGNodeConstRef node,
750
- const YGEdge edge) {
751
- auto border = node->getStyle().border()[edge];
623
+ float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) {
624
+ auto border = resolveRef(node)->getStyle().border()[edge];
752
625
  if (border.isUndefined() || border.isAuto()) {
753
- // TODO(T26792433): Rather than returning YGUndefined, change the api to
754
- // return YGFloatOptional.
755
626
  return YGUndefined;
756
627
  }
757
628
 
758
629
  return static_cast<YGValue>(border).value;
759
630
  }
760
631
 
761
- YOGA_EXPORT void YGNodeStyleSetGap(
632
+ void YGNodeStyleSetGap(
762
633
  const YGNodeRef node,
763
634
  const YGGutter gutter,
764
635
  const float gapLength) {
765
- auto length = detail::CompactValue::ofMaybe<YGUnitPoint>(gapLength);
766
- updateIndexedStyleProp<MSVC_HINT(gap)>(node, &YGStyle::gap, gutter, length);
636
+ auto length = CompactValue::ofMaybe<YGUnitPoint>(gapLength);
637
+ updateIndexedStyleProp<MSVC_HINT(gap)>(node, &Style::gap, gutter, length);
767
638
  }
768
639
 
769
- YOGA_EXPORT float YGNodeStyleGetGap(
770
- const YGNodeConstRef node,
771
- const YGGutter gutter) {
772
- auto gapLength = node->getStyle().gap()[gutter];
640
+ float YGNodeStyleGetGap(const YGNodeConstRef node, const YGGutter gutter) {
641
+ auto gapLength = resolveRef(node)->getStyle().gap()[gutter];
773
642
  if (gapLength.isUndefined() || gapLength.isAuto()) {
774
- // TODO(T26792433): Rather than returning YGUndefined, change the api to
775
- // return YGFloatOptional.
776
643
  return YGUndefined;
777
644
  }
778
645
 
@@ -781,3579 +648,314 @@ YOGA_EXPORT float YGNodeStyleGetGap(
781
648
 
782
649
  // Yoga specific properties, not compatible with flexbox specification
783
650
 
784
- // TODO(T26792433): Change the API to accept YGFloatOptional.
785
- YOGA_EXPORT float YGNodeStyleGetAspectRatio(const YGNodeConstRef node) {
786
- const YGFloatOptional op = node->getStyle().aspectRatio();
651
+ float YGNodeStyleGetAspectRatio(const YGNodeConstRef node) {
652
+ const FloatOptional op = resolveRef(node)->getStyle().aspectRatio();
787
653
  return op.isUndefined() ? YGUndefined : op.unwrap();
788
654
  }
789
655
 
790
- // TODO(T26792433): Change the API to accept YGFloatOptional.
791
- YOGA_EXPORT void YGNodeStyleSetAspectRatio(
792
- const YGNodeRef node,
793
- const float aspectRatio) {
656
+ void YGNodeStyleSetAspectRatio(const YGNodeRef node, const float aspectRatio) {
794
657
  updateStyle<MSVC_HINT(aspectRatio)>(
795
- node, &YGStyle::aspectRatio, YGFloatOptional{aspectRatio});
658
+ node, &Style::aspectRatio, FloatOptional{aspectRatio});
796
659
  }
797
660
 
798
- YOGA_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, float points) {
799
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(points);
800
- updateIndexedStyleProp<MSVC_HINT(dimensions)>(
801
- node, &YGStyle::dimensions, YGDimensionWidth, value);
661
+ void YGNodeStyleSetWidth(YGNodeRef node, float points) {
662
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
663
+ updateIndexedStyleProp<&Style::dimension, &Style::setDimension>(
664
+ node, YGDimensionWidth, value);
802
665
  }
803
- YOGA_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) {
804
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(percent);
805
- updateIndexedStyleProp<MSVC_HINT(dimensions)>(
806
- node, &YGStyle::dimensions, YGDimensionWidth, value);
666
+ void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) {
667
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
668
+ updateIndexedStyleProp<&Style::dimension, &Style::setDimension>(
669
+ node, YGDimensionWidth, value);
807
670
  }
808
- YOGA_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node) {
809
- updateIndexedStyleProp<MSVC_HINT(dimensions)>(
810
- node,
811
- &YGStyle::dimensions,
812
- YGDimensionWidth,
813
- detail::CompactValue::ofAuto());
671
+ void YGNodeStyleSetWidthAuto(YGNodeRef node) {
672
+ updateIndexedStyleProp<&Style::dimension, &Style::setDimension>(
673
+ node, YGDimensionWidth, CompactValue::ofAuto());
814
674
  }
815
- YOGA_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node) {
816
- return node->getStyle().dimensions()[YGDimensionWidth];
675
+ YGValue YGNodeStyleGetWidth(YGNodeConstRef node) {
676
+ return resolveRef(node)->getStyle().dimension(YGDimensionWidth);
817
677
  }
818
678
 
819
- YOGA_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float points) {
820
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(points);
821
- updateIndexedStyleProp<MSVC_HINT(dimensions)>(
822
- node, &YGStyle::dimensions, YGDimensionHeight, value);
679
+ void YGNodeStyleSetHeight(YGNodeRef node, float points) {
680
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
681
+ updateIndexedStyleProp<&Style::dimension, &Style::setDimension>(
682
+ node, YGDimensionHeight, value);
823
683
  }
824
- YOGA_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) {
825
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(percent);
826
- updateIndexedStyleProp<MSVC_HINT(dimensions)>(
827
- node, &YGStyle::dimensions, YGDimensionHeight, value);
684
+ void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) {
685
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
686
+ updateIndexedStyleProp<&Style::dimension, &Style::setDimension>(
687
+ node, YGDimensionHeight, value);
828
688
  }
829
- YOGA_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node) {
830
- updateIndexedStyleProp<MSVC_HINT(dimensions)>(
831
- node,
832
- &YGStyle::dimensions,
833
- YGDimensionHeight,
834
- detail::CompactValue::ofAuto());
689
+ void YGNodeStyleSetHeightAuto(YGNodeRef node) {
690
+ updateIndexedStyleProp<&Style::dimension, &Style::setDimension>(
691
+ node, YGDimensionHeight, CompactValue::ofAuto());
835
692
  }
836
- YOGA_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node) {
837
- return node->getStyle().dimensions()[YGDimensionHeight];
693
+ YGValue YGNodeStyleGetHeight(YGNodeConstRef node) {
694
+ return resolveRef(node)->getStyle().dimension(YGDimensionHeight);
838
695
  }
839
696
 
840
- YOGA_EXPORT void YGNodeStyleSetMinWidth(
841
- const YGNodeRef node,
842
- const float minWidth) {
843
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(minWidth);
844
- updateIndexedStyleProp<MSVC_HINT(minDimensions)>(
845
- node, &YGStyle::minDimensions, YGDimensionWidth, value);
697
+ void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) {
698
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(minWidth);
699
+ updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>(
700
+ node, YGDimensionWidth, value);
846
701
  }
847
- YOGA_EXPORT void YGNodeStyleSetMinWidthPercent(
848
- const YGNodeRef node,
849
- const float minWidth) {
850
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(minWidth);
851
- updateIndexedStyleProp<MSVC_HINT(minDimensions)>(
852
- node, &YGStyle::minDimensions, YGDimensionWidth, value);
702
+ void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) {
703
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(minWidth);
704
+ updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>(
705
+ node, YGDimensionWidth, value);
853
706
  }
854
- YOGA_EXPORT YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) {
855
- return node->getStyle().minDimensions()[YGDimensionWidth];
856
- };
857
-
858
- YOGA_EXPORT void YGNodeStyleSetMinHeight(
859
- const YGNodeRef node,
860
- const float minHeight) {
861
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(minHeight);
862
- updateIndexedStyleProp<MSVC_HINT(minDimensions)>(
863
- node, &YGStyle::minDimensions, YGDimensionHeight, value);
864
- }
865
- YOGA_EXPORT void YGNodeStyleSetMinHeightPercent(
866
- const YGNodeRef node,
867
- const float minHeight) {
868
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(minHeight);
869
- updateIndexedStyleProp<MSVC_HINT(minDimensions)>(
870
- node, &YGStyle::minDimensions, YGDimensionHeight, value);
707
+ YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) {
708
+ return resolveRef(node)->getStyle().minDimension(YGDimensionWidth);
871
709
  }
872
- YOGA_EXPORT YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) {
873
- return node->getStyle().minDimensions()[YGDimensionHeight];
874
- };
875
710
 
876
- YOGA_EXPORT void YGNodeStyleSetMaxWidth(
877
- const YGNodeRef node,
878
- const float maxWidth) {
879
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(maxWidth);
880
- updateIndexedStyleProp<MSVC_HINT(maxDimensions)>(
881
- node, &YGStyle::maxDimensions, YGDimensionWidth, value);
711
+ void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) {
712
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(minHeight);
713
+ updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>(
714
+ node, YGDimensionHeight, value);
882
715
  }
883
- YOGA_EXPORT void YGNodeStyleSetMaxWidthPercent(
716
+ void YGNodeStyleSetMinHeightPercent(
884
717
  const YGNodeRef node,
885
- const float maxWidth) {
886
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(maxWidth);
887
- updateIndexedStyleProp<MSVC_HINT(maxDimensions)>(
888
- node, &YGStyle::maxDimensions, YGDimensionWidth, value);
889
- }
890
- YOGA_EXPORT YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) {
891
- return node->getStyle().maxDimensions()[YGDimensionWidth];
892
- };
893
-
894
- YOGA_EXPORT void YGNodeStyleSetMaxHeight(
895
- const YGNodeRef node,
896
- const float maxHeight) {
897
- auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(maxHeight);
898
- updateIndexedStyleProp<MSVC_HINT(maxDimensions)>(
899
- node, &YGStyle::maxDimensions, YGDimensionHeight, value);
900
- }
901
- YOGA_EXPORT void YGNodeStyleSetMaxHeightPercent(
902
- const YGNodeRef node,
903
- const float maxHeight) {
904
- auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(maxHeight);
905
- updateIndexedStyleProp<MSVC_HINT(maxDimensions)>(
906
- node, &YGStyle::maxDimensions, YGDimensionHeight, value);
907
- }
908
- YOGA_EXPORT YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) {
909
- return node->getStyle().maxDimensions()[YGDimensionHeight];
910
- };
911
-
912
- #define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \
913
- YOGA_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node) { \
914
- return node->getLayout().instanceName; \
915
- }
916
-
917
- #define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \
918
- YOGA_EXPORT type YGNodeLayoutGet##name( \
919
- const YGNodeRef node, const YGEdge edge) { \
920
- YGAssertWithNode( \
921
- node, \
922
- edge <= YGEdgeEnd, \
923
- "Cannot get layout properties of multi-edge shorthands"); \
924
- \
925
- if (edge == YGEdgeStart) { \
926
- if (node->getLayout().direction() == YGDirectionRTL) { \
927
- return node->getLayout().instanceName[YGEdgeRight]; \
928
- } else { \
929
- return node->getLayout().instanceName[YGEdgeLeft]; \
930
- } \
931
- } \
932
- \
933
- if (edge == YGEdgeEnd) { \
934
- if (node->getLayout().direction() == YGDirectionRTL) { \
935
- return node->getLayout().instanceName[YGEdgeLeft]; \
936
- } else { \
937
- return node->getLayout().instanceName[YGEdgeRight]; \
938
- } \
939
- } \
940
- \
941
- return node->getLayout().instanceName[edge]; \
942
- }
943
-
944
- YG_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[YGEdgeLeft]);
945
- YG_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[YGEdgeTop]);
946
- YG_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[YGEdgeRight]);
947
- YG_NODE_LAYOUT_PROPERTY_IMPL(float, Bottom, position[YGEdgeBottom]);
948
- YG_NODE_LAYOUT_PROPERTY_IMPL(float, Width, dimensions[YGDimensionWidth]);
949
- YG_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[YGDimensionHeight]);
950
- YG_NODE_LAYOUT_PROPERTY_IMPL(YGDirection, Direction, direction());
951
- YG_NODE_LAYOUT_PROPERTY_IMPL(bool, HadOverflow, hadOverflow());
952
-
953
- YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Margin, margin);
954
- YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Border, border);
955
- YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Padding, padding);
956
-
957
- std::atomic<uint32_t> gCurrentGenerationCount(0);
958
-
959
- bool YGLayoutNodeInternal(
960
- const YGNodeRef node,
961
- const float availableWidth,
962
- const float availableHeight,
963
- const YGDirection ownerDirection,
964
- const YGMeasureMode widthMeasureMode,
965
- const YGMeasureMode heightMeasureMode,
966
- const float ownerWidth,
967
- const float ownerHeight,
968
- const bool performLayout,
969
- const LayoutPassReason reason,
970
- const YGConfigRef config,
971
- LayoutData &layoutMarkerData,
972
- void *const layoutContext,
973
- const uint32_t depth,
974
- const uint32_t generationCount);
975
-
976
- #ifdef DEBUG
977
- static void YGNodePrintInternal(
978
- const YGNodeRef node,
979
- const YGPrintOptions options) {
980
- std::string str;
981
- facebook::yoga::YGNodeToString(str, node, options, 0);
982
- Log::log(node, YGLogLevelDebug, nullptr, str.c_str());
983
- }
984
-
985
- YOGA_EXPORT void YGNodePrint(
986
- const YGNodeRef node,
987
- const YGPrintOptions options) {
988
- YGNodePrintInternal(node, options);
718
+ const float minHeight) {
719
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(minHeight);
720
+ updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>(
721
+ node, YGDimensionHeight, value);
989
722
  }
990
- #endif
991
-
992
- const std::array<YGEdge, 4> leading = {
993
- {YGEdgeTop, YGEdgeBottom, YGEdgeLeft, YGEdgeRight}};
994
-
995
- const std::array<YGEdge, 4> trailing = {
996
- {YGEdgeBottom, YGEdgeTop, YGEdgeRight, YGEdgeLeft}};
997
- static const std::array<YGEdge, 4> pos = {{
998
- YGEdgeTop,
999
- YGEdgeBottom,
1000
- YGEdgeLeft,
1001
- YGEdgeRight,
1002
- }};
1003
-
1004
- static const std::array<YGDimension, 4> dim = {
1005
- {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}};
1006
-
1007
- static inline float YGNodePaddingAndBorderForAxis(
1008
- const YGNodeConstRef node,
1009
- const YGFlexDirection axis,
1010
- const float widthSize) {
1011
- return (node->getLeadingPaddingAndBorder(axis, widthSize) +
1012
- node->getTrailingPaddingAndBorder(axis, widthSize))
1013
- .unwrap();
1014
- }
1015
-
1016
- static inline YGAlign YGNodeAlignItem(const YGNode *node, const YGNode *child) {
1017
- const YGAlign align = child->getStyle().alignSelf() == YGAlignAuto
1018
- ? node->getStyle().alignItems()
1019
- : child->getStyle().alignSelf();
1020
- if (align == YGAlignBaseline &&
1021
- YGFlexDirectionIsColumn(node->getStyle().flexDirection())) {
1022
- return YGAlignFlexStart;
1023
- }
1024
- return align;
723
+ YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) {
724
+ return resolveRef(node)->getStyle().minDimension(YGDimensionHeight);
1025
725
  }
1026
726
 
1027
- static float YGBaseline(const YGNodeRef node, void *layoutContext) {
1028
- if (node->hasBaselineFunc()) {
1029
- Event::publish<Event::NodeBaselineStart>(node);
1030
-
1031
- const float baseline = node->baseline(
1032
- node->getLayout().measuredDimensions[YGDimensionWidth],
1033
- node->getLayout().measuredDimensions[YGDimensionHeight],
1034
- layoutContext);
1035
-
1036
- Event::publish<Event::NodeBaselineEnd>(node);
1037
-
1038
- YGAssertWithNode(
1039
- node,
1040
- !YGFloatIsUndefined(baseline),
1041
- "Expect custom baseline function to not return NaN");
1042
- return baseline;
1043
- }
1044
-
1045
- YGNodeRef baselineChild = nullptr;
1046
- const uint32_t childCount = YGNodeGetChildCount(node);
1047
- for (uint32_t i = 0; i < childCount; i++) {
1048
- const YGNodeRef child = YGNodeGetChild(node, i);
1049
- if (child->getLineIndex() > 0) {
1050
- break;
1051
- }
1052
- if (child->getStyle().positionType() == YGPositionTypeAbsolute) {
1053
- continue;
1054
- }
1055
- if (YGNodeAlignItem(node, child) == YGAlignBaseline ||
1056
- child->isReferenceBaseline()) {
1057
- baselineChild = child;
1058
- break;
1059
- }
1060
-
1061
- if (baselineChild == nullptr) {
1062
- baselineChild = child;
1063
- }
1064
- }
1065
-
1066
- if (baselineChild == nullptr) {
1067
- return node->getLayout().measuredDimensions[YGDimensionHeight];
1068
- }
1069
-
1070
- const float baseline = YGBaseline(baselineChild, layoutContext);
1071
- return baseline + baselineChild->getLayout().position[YGEdgeTop];
727
+ void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) {
728
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(maxWidth);
729
+ updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>(
730
+ node, YGDimensionWidth, value);
1072
731
  }
1073
-
1074
- static bool YGIsBaselineLayout(const YGNodeRef node) {
1075
- if (YGFlexDirectionIsColumn(node->getStyle().flexDirection())) {
1076
- return false;
1077
- }
1078
- if (node->getStyle().alignItems() == YGAlignBaseline) {
1079
- return true;
1080
- }
1081
- const uint32_t childCount = YGNodeGetChildCount(node);
1082
- for (uint32_t i = 0; i < childCount; i++) {
1083
- const YGNodeRef child = YGNodeGetChild(node, i);
1084
- if (child->getStyle().positionType() != YGPositionTypeAbsolute &&
1085
- child->getStyle().alignSelf() == YGAlignBaseline) {
1086
- return true;
1087
- }
1088
- }
1089
-
1090
- return false;
732
+ void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) {
733
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(maxWidth);
734
+ updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>(
735
+ node, YGDimensionWidth, value);
1091
736
  }
1092
-
1093
- static inline float YGNodeDimWithMargin(
1094
- const YGNodeRef node,
1095
- const YGFlexDirection axis,
1096
- const float widthSize) {
1097
- return node->getLayout().measuredDimensions[dim[axis]] +
1098
- (node->getLeadingMargin(axis, widthSize) +
1099
- node->getTrailingMargin(axis, widthSize))
1100
- .unwrap();
737
+ YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) {
738
+ return resolveRef(node)->getStyle().maxDimension(YGDimensionWidth);
1101
739
  }
1102
740
 
1103
- static inline bool YGNodeIsStyleDimDefined(
1104
- const YGNodeRef node,
1105
- const YGFlexDirection axis,
1106
- const float ownerSize) {
1107
- bool isUndefined =
1108
- YGFloatIsUndefined(node->getResolvedDimension(dim[axis]).value);
1109
- return !(
1110
- node->getResolvedDimension(dim[axis]).unit == YGUnitAuto ||
1111
- node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined ||
1112
- (node->getResolvedDimension(dim[axis]).unit == YGUnitPoint &&
1113
- !isUndefined && node->getResolvedDimension(dim[axis]).value < 0.0f) ||
1114
- (node->getResolvedDimension(dim[axis]).unit == YGUnitPercent &&
1115
- !isUndefined &&
1116
- (node->getResolvedDimension(dim[axis]).value < 0.0f ||
1117
- YGFloatIsUndefined(ownerSize))));
1118
- }
1119
-
1120
- static inline bool YGNodeIsLayoutDimDefined(
1121
- const YGNodeRef node,
1122
- const YGFlexDirection axis) {
1123
- const float value = node->getLayout().measuredDimensions[dim[axis]];
1124
- return !YGFloatIsUndefined(value) && value >= 0.0f;
1125
- }
1126
-
1127
- static YGFloatOptional YGNodeBoundAxisWithinMinAndMax(
1128
- const YGNodeConstRef node,
1129
- const YGFlexDirection axis,
1130
- const YGFloatOptional value,
1131
- const float axisSize) {
1132
- YGFloatOptional min;
1133
- YGFloatOptional max;
1134
-
1135
- if (YGFlexDirectionIsColumn(axis)) {
1136
- min = YGResolveValue(
1137
- node->getStyle().minDimensions()[YGDimensionHeight], axisSize);
1138
- max = YGResolveValue(
1139
- node->getStyle().maxDimensions()[YGDimensionHeight], axisSize);
1140
- } else if (YGFlexDirectionIsRow(axis)) {
1141
- min = YGResolveValue(
1142
- node->getStyle().minDimensions()[YGDimensionWidth], axisSize);
1143
- max = YGResolveValue(
1144
- node->getStyle().maxDimensions()[YGDimensionWidth], axisSize);
1145
- }
1146
-
1147
- if (max >= YGFloatOptional{0} && value > max) {
1148
- return max;
1149
- }
1150
-
1151
- if (min >= YGFloatOptional{0} && value < min) {
1152
- return min;
1153
- }
1154
-
1155
- return value;
741
+ void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) {
742
+ auto value = CompactValue::ofMaybe<YGUnitPoint>(maxHeight);
743
+ updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>(
744
+ node, YGDimensionHeight, value);
1156
745
  }
1157
-
1158
- // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't
1159
- // go below the padding and border amount.
1160
- static inline float YGNodeBoundAxis(
746
+ void YGNodeStyleSetMaxHeightPercent(
1161
747
  const YGNodeRef node,
1162
- const YGFlexDirection axis,
1163
- const float value,
1164
- const float axisSize,
1165
- const float widthSize) {
1166
- return YGFloatMax(
1167
- YGNodeBoundAxisWithinMinAndMax(
1168
- node, axis, YGFloatOptional{value}, axisSize)
1169
- .unwrap(),
1170
- YGNodePaddingAndBorderForAxis(node, axis, widthSize));
1171
- }
1172
-
1173
- static void YGNodeSetChildTrailingPosition(
1174
- const YGNodeRef node,
1175
- const YGNodeRef child,
1176
- const YGFlexDirection axis) {
1177
- const float size = child->getLayout().measuredDimensions[dim[axis]];
1178
- child->setLayoutPosition(
1179
- node->getLayout().measuredDimensions[dim[axis]] - size -
1180
- child->getLayout().position[pos[axis]],
1181
- trailing[axis]);
1182
- }
1183
-
1184
- static void YGConstrainMaxSizeForMode(
1185
- const YGNodeConstRef node,
1186
- const enum YGFlexDirection axis,
1187
- const float ownerAxisSize,
1188
- const float ownerWidth,
1189
- YGMeasureMode *mode,
1190
- float *size) {
1191
- const YGFloatOptional maxSize =
1192
- YGResolveValue(
1193
- node->getStyle().maxDimensions()[dim[axis]], ownerAxisSize) +
1194
- YGFloatOptional(node->getMarginForAxis(axis, ownerWidth));
1195
- switch (*mode) {
1196
- case YGMeasureModeExactly:
1197
- case YGMeasureModeAtMost:
1198
- *size = (maxSize.isUndefined() || *size < maxSize.unwrap())
1199
- ? *size
1200
- : maxSize.unwrap();
1201
- break;
1202
- case YGMeasureModeUndefined:
1203
- if (!maxSize.isUndefined()) {
1204
- *mode = YGMeasureModeAtMost;
1205
- *size = maxSize.unwrap();
1206
- }
1207
- break;
1208
- }
748
+ const float maxHeight) {
749
+ auto value = CompactValue::ofMaybe<YGUnitPercent>(maxHeight);
750
+ updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>(
751
+ node, YGDimensionHeight, value);
1209
752
  }
1210
-
1211
- static void YGNodeComputeFlexBasisForChild(
1212
- const YGNodeRef node,
1213
- const YGNodeRef child,
1214
- const float width,
1215
- const YGMeasureMode widthMode,
1216
- const float height,
1217
- const float ownerWidth,
1218
- const float ownerHeight,
1219
- const YGMeasureMode heightMode,
1220
- const YGDirection direction,
1221
- const YGConfigRef config,
1222
- LayoutData &layoutMarkerData,
1223
- void *const layoutContext,
1224
- const uint32_t depth,
1225
- const uint32_t generationCount) {
1226
- const YGFlexDirection mainAxis =
1227
- YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
1228
- const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
1229
- const float mainAxisSize = isMainAxisRow ? width : height;
1230
- const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
1231
-
1232
- float childWidth;
1233
- float childHeight;
1234
- YGMeasureMode childWidthMeasureMode;
1235
- YGMeasureMode childHeightMeasureMode;
1236
-
1237
- const YGFloatOptional resolvedFlexBasis =
1238
- YGResolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize);
1239
- const bool isRowStyleDimDefined =
1240
- YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth);
1241
- const bool isColumnStyleDimDefined =
1242
- YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, ownerHeight);
1243
-
1244
- if (!resolvedFlexBasis.isUndefined() && !YGFloatIsUndefined(mainAxisSize)) {
1245
- if (child->getLayout().computedFlexBasis.isUndefined() ||
1246
- (YGConfigIsExperimentalFeatureEnabled(
1247
- child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
1248
- child->getLayout().computedFlexBasisGeneration != generationCount)) {
1249
- const YGFloatOptional paddingAndBorder = YGFloatOptional(
1250
- YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
1251
- child->setLayoutComputedFlexBasis(
1252
- YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder));
1253
- }
1254
- } else if (isMainAxisRow && isRowStyleDimDefined) {
1255
- // The width is definite, so use that as the flex basis.
1256
- const YGFloatOptional paddingAndBorder = YGFloatOptional(
1257
- YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth));
1258
-
1259
- child->setLayoutComputedFlexBasis(YGFloatOptionalMax(
1260
- YGResolveValue(
1261
- child->getResolvedDimensions()[YGDimensionWidth], ownerWidth),
1262
- paddingAndBorder));
1263
- } else if (!isMainAxisRow && isColumnStyleDimDefined) {
1264
- // The height is definite, so use that as the flex basis.
1265
- const YGFloatOptional paddingAndBorder =
1266
- YGFloatOptional(YGNodePaddingAndBorderForAxis(
1267
- child, YGFlexDirectionColumn, ownerWidth));
1268
- child->setLayoutComputedFlexBasis(YGFloatOptionalMax(
1269
- YGResolveValue(
1270
- child->getResolvedDimensions()[YGDimensionHeight], ownerHeight),
1271
- paddingAndBorder));
1272
- } else {
1273
- // Compute the flex basis and hypothetical main size (i.e. the clamped flex
1274
- // basis).
1275
- childWidth = YGUndefined;
1276
- childHeight = YGUndefined;
1277
- childWidthMeasureMode = YGMeasureModeUndefined;
1278
- childHeightMeasureMode = YGMeasureModeUndefined;
1279
-
1280
- auto marginRow =
1281
- child->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap();
1282
- auto marginColumn =
1283
- child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap();
1284
-
1285
- if (isRowStyleDimDefined) {
1286
- childWidth =
1287
- YGResolveValue(
1288
- child->getResolvedDimensions()[YGDimensionWidth], ownerWidth)
1289
- .unwrap() +
1290
- marginRow;
1291
- childWidthMeasureMode = YGMeasureModeExactly;
1292
- }
1293
- if (isColumnStyleDimDefined) {
1294
- childHeight =
1295
- YGResolveValue(
1296
- child->getResolvedDimensions()[YGDimensionHeight], ownerHeight)
1297
- .unwrap() +
1298
- marginColumn;
1299
- childHeightMeasureMode = YGMeasureModeExactly;
1300
- }
1301
-
1302
- // The W3C spec doesn't say anything about the 'overflow' property, but all
1303
- // major browsers appear to implement the following logic.
1304
- if ((!isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
1305
- node->getStyle().overflow() != YGOverflowScroll) {
1306
- if (YGFloatIsUndefined(childWidth) && !YGFloatIsUndefined(width)) {
1307
- childWidth = width;
1308
- childWidthMeasureMode = YGMeasureModeAtMost;
1309
- }
1310
- }
1311
-
1312
- if ((isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
1313
- node->getStyle().overflow() != YGOverflowScroll) {
1314
- if (YGFloatIsUndefined(childHeight) && !YGFloatIsUndefined(height)) {
1315
- childHeight = height;
1316
- childHeightMeasureMode = YGMeasureModeAtMost;
1317
- }
1318
- }
1319
-
1320
- const auto &childStyle = child->getStyle();
1321
- if (!childStyle.aspectRatio().isUndefined()) {
1322
- if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
1323
- childHeight = marginColumn +
1324
- (childWidth - marginRow) / childStyle.aspectRatio().unwrap();
1325
- childHeightMeasureMode = YGMeasureModeExactly;
1326
- } else if (
1327
- isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
1328
- childWidth = marginRow +
1329
- (childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
1330
- childWidthMeasureMode = YGMeasureModeExactly;
1331
- }
1332
- }
1333
-
1334
- // If child has no defined size in the cross axis and is set to stretch, set
1335
- // the cross axis to be measured exactly with the available inner width
1336
-
1337
- const bool hasExactWidth =
1338
- !YGFloatIsUndefined(width) && widthMode == YGMeasureModeExactly;
1339
- const bool childWidthStretch =
1340
- YGNodeAlignItem(node, child) == YGAlignStretch &&
1341
- childWidthMeasureMode != YGMeasureModeExactly;
1342
- if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth &&
1343
- childWidthStretch) {
1344
- childWidth = width;
1345
- childWidthMeasureMode = YGMeasureModeExactly;
1346
- if (!childStyle.aspectRatio().isUndefined()) {
1347
- childHeight =
1348
- (childWidth - marginRow) / childStyle.aspectRatio().unwrap();
1349
- childHeightMeasureMode = YGMeasureModeExactly;
1350
- }
1351
- }
1352
-
1353
- const bool hasExactHeight =
1354
- !YGFloatIsUndefined(height) && heightMode == YGMeasureModeExactly;
1355
- const bool childHeightStretch =
1356
- YGNodeAlignItem(node, child) == YGAlignStretch &&
1357
- childHeightMeasureMode != YGMeasureModeExactly;
1358
- if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight &&
1359
- childHeightStretch) {
1360
- childHeight = height;
1361
- childHeightMeasureMode = YGMeasureModeExactly;
1362
-
1363
- if (!childStyle.aspectRatio().isUndefined()) {
1364
- childWidth =
1365
- (childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
1366
- childWidthMeasureMode = YGMeasureModeExactly;
1367
- }
1368
- }
1369
-
1370
- YGConstrainMaxSizeForMode(
1371
- child,
1372
- YGFlexDirectionRow,
1373
- ownerWidth,
1374
- ownerWidth,
1375
- &childWidthMeasureMode,
1376
- &childWidth);
1377
- YGConstrainMaxSizeForMode(
1378
- child,
1379
- YGFlexDirectionColumn,
1380
- ownerHeight,
1381
- ownerWidth,
1382
- &childHeightMeasureMode,
1383
- &childHeight);
1384
-
1385
- // Measure the child
1386
- YGLayoutNodeInternal(
1387
- child,
1388
- childWidth,
1389
- childHeight,
1390
- direction,
1391
- childWidthMeasureMode,
1392
- childHeightMeasureMode,
1393
- ownerWidth,
1394
- ownerHeight,
1395
- false,
1396
- LayoutPassReason::kMeasureChild,
1397
- config,
1398
- layoutMarkerData,
1399
- layoutContext,
1400
- depth,
1401
- generationCount);
1402
-
1403
- child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax(
1404
- child->getLayout().measuredDimensions[dim[mainAxis]],
1405
- YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth))));
1406
- }
1407
- child->setLayoutComputedFlexBasisGeneration(generationCount);
753
+ YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) {
754
+ return resolveRef(node)->getStyle().maxDimension(YGDimensionHeight);
1408
755
  }
1409
756
 
1410
- static void YGNodeAbsoluteLayoutChild(
1411
- const YGNodeRef node,
1412
- const YGNodeRef child,
1413
- const float width,
1414
- const YGMeasureMode widthMode,
1415
- const float height,
1416
- const YGDirection direction,
1417
- const YGConfigRef config,
1418
- LayoutData &layoutMarkerData,
1419
- void *const layoutContext,
1420
- const uint32_t depth,
1421
- const uint32_t generationCount) {
1422
- const YGFlexDirection mainAxis =
1423
- YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
1424
- const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
1425
- const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
1426
-
1427
- float childWidth = YGUndefined;
1428
- float childHeight = YGUndefined;
1429
- YGMeasureMode childWidthMeasureMode = YGMeasureModeUndefined;
1430
- YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined;
1431
-
1432
- auto marginRow = child->getMarginForAxis(YGFlexDirectionRow, width).unwrap();
1433
- auto marginColumn =
1434
- child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap();
1435
-
1436
- if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) {
1437
- childWidth =
1438
- YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], width)
1439
- .unwrap() +
1440
- marginRow;
1441
- } else {
1442
- // If the child doesn't have a specified width, compute the width based on
1443
- // the left/right offsets if they're defined.
1444
- if (child->isLeadingPositionDefined(YGFlexDirectionRow) &&
1445
- child->isTrailingPosDefined(YGFlexDirectionRow)) {
1446
- childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] -
1447
- (node->getLeadingBorder(YGFlexDirectionRow) +
1448
- node->getTrailingBorder(YGFlexDirectionRow)) -
1449
- (child->getLeadingPosition(YGFlexDirectionRow, width) +
1450
- child->getTrailingPosition(YGFlexDirectionRow, width))
1451
- .unwrap();
1452
- childWidth =
1453
- YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width);
1454
- }
1455
- }
757
+ namespace {
1456
758
 
1457
- if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) {
1458
- childHeight = YGResolveValue(
1459
- child->getResolvedDimensions()[YGDimensionHeight], height)
1460
- .unwrap() +
1461
- marginColumn;
1462
- } else {
1463
- // If the child doesn't have a specified height, compute the height based on
1464
- // the top/bottom offsets if they're defined.
1465
- if (child->isLeadingPositionDefined(YGFlexDirectionColumn) &&
1466
- child->isTrailingPosDefined(YGFlexDirectionColumn)) {
1467
- childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] -
1468
- (node->getLeadingBorder(YGFlexDirectionColumn) +
1469
- node->getTrailingBorder(YGFlexDirectionColumn)) -
1470
- (child->getLeadingPosition(YGFlexDirectionColumn, height) +
1471
- child->getTrailingPosition(YGFlexDirectionColumn, height))
1472
- .unwrap();
1473
- childHeight = YGNodeBoundAxis(
1474
- child, YGFlexDirectionColumn, childHeight, height, width);
1475
- }
1476
- }
759
+ template <auto LayoutMember>
760
+ float getResolvedLayoutProperty(
761
+ const YGNodeConstRef nodeRef,
762
+ const YGEdge edge) {
763
+ const auto node = resolveRef(nodeRef);
764
+ yoga::assertFatalWithNode(
765
+ node,
766
+ edge <= YGEdgeEnd,
767
+ "Cannot get layout properties of multi-edge shorthands");
1477
768
 
1478
- // Exactly one dimension needs to be defined for us to be able to do aspect
1479
- // ratio calculation. One dimension being the anchor and the other being
1480
- // flexible.
1481
- const auto &childStyle = child->getStyle();
1482
- if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) {
1483
- if (!childStyle.aspectRatio().isUndefined()) {
1484
- if (YGFloatIsUndefined(childWidth)) {
1485
- childWidth = marginRow +
1486
- (childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
1487
- } else if (YGFloatIsUndefined(childHeight)) {
1488
- childHeight = marginColumn +
1489
- (childWidth - marginRow) / childStyle.aspectRatio().unwrap();
1490
- }
769
+ if (edge == YGEdgeStart) {
770
+ if (node->getLayout().direction() == Direction::RTL) {
771
+ return (node->getLayout().*LayoutMember)[YGEdgeRight];
772
+ } else {
773
+ return (node->getLayout().*LayoutMember)[YGEdgeLeft];
1491
774
  }
1492
775
  }
1493
776
 
1494
- // If we're still missing one or the other dimension, measure the content.
1495
- if (YGFloatIsUndefined(childWidth) || YGFloatIsUndefined(childHeight)) {
1496
- childWidthMeasureMode = YGFloatIsUndefined(childWidth)
1497
- ? YGMeasureModeUndefined
1498
- : YGMeasureModeExactly;
1499
- childHeightMeasureMode = YGFloatIsUndefined(childHeight)
1500
- ? YGMeasureModeUndefined
1501
- : YGMeasureModeExactly;
1502
-
1503
- // If the size of the owner is defined then try to constrain the absolute
1504
- // child to that size as well. This allows text within the absolute child to
1505
- // wrap to the size of its owner. This is the same behavior as many browsers
1506
- // implement.
1507
- if (!isMainAxisRow && YGFloatIsUndefined(childWidth) &&
1508
- widthMode != YGMeasureModeUndefined && !YGFloatIsUndefined(width) &&
1509
- width > 0) {
1510
- childWidth = width;
1511
- childWidthMeasureMode = YGMeasureModeAtMost;
777
+ if (edge == YGEdgeEnd) {
778
+ if (node->getLayout().direction() == Direction::RTL) {
779
+ return (node->getLayout().*LayoutMember)[YGEdgeLeft];
780
+ } else {
781
+ return (node->getLayout().*LayoutMember)[YGEdgeRight];
1512
782
  }
1513
-
1514
- YGLayoutNodeInternal(
1515
- child,
1516
- childWidth,
1517
- childHeight,
1518
- direction,
1519
- childWidthMeasureMode,
1520
- childHeightMeasureMode,
1521
- childWidth,
1522
- childHeight,
1523
- false,
1524
- LayoutPassReason::kAbsMeasureChild,
1525
- config,
1526
- layoutMarkerData,
1527
- layoutContext,
1528
- depth,
1529
- generationCount);
1530
- childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] +
1531
- child->getMarginForAxis(YGFlexDirectionRow, width).unwrap();
1532
- childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] +
1533
- child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap();
1534
- }
1535
-
1536
- YGLayoutNodeInternal(
1537
- child,
1538
- childWidth,
1539
- childHeight,
1540
- direction,
1541
- YGMeasureModeExactly,
1542
- YGMeasureModeExactly,
1543
- childWidth,
1544
- childHeight,
1545
- true,
1546
- LayoutPassReason::kAbsLayout,
1547
- config,
1548
- layoutMarkerData,
1549
- layoutContext,
1550
- depth,
1551
- generationCount);
1552
-
1553
- auto trailingMarginOuterSize =
1554
- YGConfigIsExperimentalFeatureEnabled(
1555
- node->getConfig(),
1556
- YGExperimentalFeatureFixAbsoluteTrailingColumnMargin)
1557
- ? isMainAxisRow ? height : width
1558
- : width;
1559
-
1560
- if (child->isTrailingPosDefined(mainAxis) &&
1561
- !child->isLeadingPositionDefined(mainAxis)) {
1562
- child->setLayoutPosition(
1563
- node->getLayout().measuredDimensions[dim[mainAxis]] -
1564
- child->getLayout().measuredDimensions[dim[mainAxis]] -
1565
- node->getTrailingBorder(mainAxis) -
1566
- child->getTrailingMargin(mainAxis, trailingMarginOuterSize)
1567
- .unwrap() -
1568
- child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height)
1569
- .unwrap(),
1570
- leading[mainAxis]);
1571
- } else if (
1572
- !child->isLeadingPositionDefined(mainAxis) &&
1573
- node->getStyle().justifyContent() == YGJustifyCenter) {
1574
- child->setLayoutPosition(
1575
- (node->getLayout().measuredDimensions[dim[mainAxis]] -
1576
- child->getLayout().measuredDimensions[dim[mainAxis]]) /
1577
- 2.0f,
1578
- leading[mainAxis]);
1579
- } else if (
1580
- !child->isLeadingPositionDefined(mainAxis) &&
1581
- node->getStyle().justifyContent() == YGJustifyFlexEnd) {
1582
- child->setLayoutPosition(
1583
- (node->getLayout().measuredDimensions[dim[mainAxis]] -
1584
- child->getLayout().measuredDimensions[dim[mainAxis]]),
1585
- leading[mainAxis]);
1586
- } else if (
1587
- YGConfigIsExperimentalFeatureEnabled(
1588
- node->getConfig(),
1589
- YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) &&
1590
- child->isLeadingPositionDefined(mainAxis)) {
1591
- child->setLayoutPosition(
1592
- child->getLeadingPosition(
1593
- mainAxis, node->getLayout().measuredDimensions[dim[mainAxis]])
1594
- .unwrap() +
1595
- node->getLeadingBorder(mainAxis) +
1596
- child
1597
- ->getLeadingMargin(
1598
- mainAxis,
1599
- node->getLayout().measuredDimensions[dim[mainAxis]])
1600
- .unwrap(),
1601
- leading[mainAxis]);
1602
783
  }
1603
784
 
1604
- if (child->isTrailingPosDefined(crossAxis) &&
1605
- !child->isLeadingPositionDefined(crossAxis)) {
1606
- child->setLayoutPosition(
1607
- node->getLayout().measuredDimensions[dim[crossAxis]] -
1608
- child->getLayout().measuredDimensions[dim[crossAxis]] -
1609
- node->getTrailingBorder(crossAxis) -
1610
- child->getTrailingMargin(crossAxis, trailingMarginOuterSize)
1611
- .unwrap() -
1612
- child
1613
- ->getTrailingPosition(crossAxis, isMainAxisRow ? height : width)
1614
- .unwrap(),
1615
- leading[crossAxis]);
1616
-
1617
- } else if (
1618
- !child->isLeadingPositionDefined(crossAxis) &&
1619
- YGNodeAlignItem(node, child) == YGAlignCenter) {
1620
- child->setLayoutPosition(
1621
- (node->getLayout().measuredDimensions[dim[crossAxis]] -
1622
- child->getLayout().measuredDimensions[dim[crossAxis]]) /
1623
- 2.0f,
1624
- leading[crossAxis]);
1625
- } else if (
1626
- !child->isLeadingPositionDefined(crossAxis) &&
1627
- ((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^
1628
- (node->getStyle().flexWrap() == YGWrapWrapReverse))) {
1629
- child->setLayoutPosition(
1630
- (node->getLayout().measuredDimensions[dim[crossAxis]] -
1631
- child->getLayout().measuredDimensions[dim[crossAxis]]),
1632
- leading[crossAxis]);
1633
- } else if (
1634
- YGConfigIsExperimentalFeatureEnabled(
1635
- node->getConfig(),
1636
- YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) &&
1637
- child->isLeadingPositionDefined(crossAxis)) {
1638
- child->setLayoutPosition(
1639
- child->getLeadingPosition(
1640
- crossAxis,
1641
- node->getLayout().measuredDimensions[dim[crossAxis]])
1642
- .unwrap() +
1643
- node->getLeadingBorder(crossAxis) +
1644
- child
1645
- ->getLeadingMargin(
1646
- crossAxis,
1647
- node->getLayout().measuredDimensions[dim[crossAxis]])
1648
- .unwrap(),
1649
- leading[crossAxis]);
1650
- }
785
+ return (node->getLayout().*LayoutMember)[edge];
1651
786
  }
1652
787
 
1653
- static void YGNodeWithMeasureFuncSetMeasuredDimensions(
1654
- const YGNodeRef node,
1655
- float availableWidth,
1656
- float availableHeight,
1657
- const YGMeasureMode widthMeasureMode,
1658
- const YGMeasureMode heightMeasureMode,
1659
- const float ownerWidth,
1660
- const float ownerHeight,
1661
- LayoutData &layoutMarkerData,
1662
- void *const layoutContext,
1663
- const LayoutPassReason reason) {
1664
- YGAssertWithNode(
1665
- node,
1666
- node->hasMeasureFunc(),
1667
- "Expected node to have custom measure function");
1668
-
1669
- if (widthMeasureMode == YGMeasureModeUndefined) {
1670
- availableWidth = YGUndefined;
1671
- }
1672
- if (heightMeasureMode == YGMeasureModeUndefined) {
1673
- availableHeight = YGUndefined;
1674
- }
788
+ } // namespace
1675
789
 
1676
- const auto& padding = node->getLayout().padding;
1677
- const auto& border = node->getLayout().border;
1678
- const float paddingAndBorderAxisRow = padding[YGEdgeLeft] +
1679
- padding[YGEdgeRight] + border[YGEdgeLeft] + border[YGEdgeRight];
1680
- const float paddingAndBorderAxisColumn = padding[YGEdgeTop] +
1681
- padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom];
1682
-
1683
- // We want to make sure we don't call measure with negative size
1684
- const float innerWidth = YGFloatIsUndefined(availableWidth)
1685
- ? availableWidth
1686
- : YGFloatMax(0, availableWidth - paddingAndBorderAxisRow);
1687
- const float innerHeight = YGFloatIsUndefined(availableHeight)
1688
- ? availableHeight
1689
- : YGFloatMax(0, availableHeight - paddingAndBorderAxisColumn);
1690
-
1691
- // Measure the text under the current constraints.
1692
- const YGSize measuredSize = node->measure(
1693
- innerWidth,
1694
- widthMeasureMode,
1695
- innerHeight,
1696
- heightMeasureMode,
1697
- layoutContext);
1698
-
1699
- if (widthMeasureMode == YGMeasureModeExactly &&
1700
- heightMeasureMode == YGMeasureModeExactly) {
1701
- // Don't bother sizing the text if both dimensions are already defined.
1702
- node->setLayoutMeasuredDimension(
1703
- YGNodeBoundAxis(
1704
- node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth),
1705
- YGDimensionWidth);
1706
- node->setLayoutMeasuredDimension(
1707
- YGNodeBoundAxis(
1708
- node,
1709
- YGFlexDirectionColumn,
1710
- availableHeight,
1711
- ownerHeight,
1712
- ownerWidth),
1713
- YGDimensionHeight);
1714
- } else {
1715
- Event::publish<Event::MeasureCallbackStart>(node);
1716
-
1717
- layoutMarkerData.measureCallbacks += 1;
1718
- layoutMarkerData.measureCallbackReasonsCount[static_cast<size_t>(reason)] +=
1719
- 1;
1720
-
1721
- Event::publish<Event::MeasureCallbackEnd>(
1722
- node,
1723
- {layoutContext,
1724
- innerWidth,
1725
- widthMeasureMode,
1726
- innerHeight,
1727
- heightMeasureMode,
1728
- measuredSize.width,
1729
- measuredSize.height,
1730
- reason});
1731
-
1732
- node->setLayoutMeasuredDimension(
1733
- YGNodeBoundAxis(
1734
- node,
1735
- YGFlexDirectionRow,
1736
- (widthMeasureMode == YGMeasureModeUndefined ||
1737
- widthMeasureMode == YGMeasureModeAtMost)
1738
- ? measuredSize.width + paddingAndBorderAxisRow
1739
- : availableWidth,
1740
- ownerWidth,
1741
- ownerWidth),
1742
- YGDimensionWidth);
1743
-
1744
- node->setLayoutMeasuredDimension(
1745
- YGNodeBoundAxis(
1746
- node,
1747
- YGFlexDirectionColumn,
1748
- (heightMeasureMode == YGMeasureModeUndefined ||
1749
- heightMeasureMode == YGMeasureModeAtMost)
1750
- ? measuredSize.height + paddingAndBorderAxisColumn
1751
- : availableHeight,
1752
- ownerHeight,
1753
- ownerWidth),
1754
- YGDimensionHeight);
1755
- }
790
+ float YGNodeLayoutGetLeft(const YGNodeConstRef node) {
791
+ return resolveRef(node)->getLayout().position[YGEdgeLeft];
1756
792
  }
1757
793
 
1758
- // For nodes with no children, use the available values if they were provided,
1759
- // or the minimum size as indicated by the padding and border sizes.
1760
- static void YGNodeEmptyContainerSetMeasuredDimensions(
1761
- const YGNodeRef node,
1762
- const float availableWidth,
1763
- const float availableHeight,
1764
- const YGMeasureMode widthMeasureMode,
1765
- const YGMeasureMode heightMeasureMode,
1766
- const float ownerWidth,
1767
- const float ownerHeight) {
1768
- const auto& padding = node->getLayout().padding;
1769
- const auto& border = node->getLayout().border;
1770
-
1771
- float width = availableWidth;
1772
- if (widthMeasureMode == YGMeasureModeUndefined ||
1773
- widthMeasureMode == YGMeasureModeAtMost) {
1774
- width = padding[YGEdgeLeft] + padding[YGEdgeRight] + border[YGEdgeLeft] +
1775
- border[YGEdgeRight];
1776
- }
1777
- node->setLayoutMeasuredDimension(
1778
- YGNodeBoundAxis(node, YGFlexDirectionRow, width, ownerWidth, ownerWidth),
1779
- YGDimensionWidth);
1780
-
1781
- float height = availableHeight;
1782
- if (heightMeasureMode == YGMeasureModeUndefined ||
1783
- heightMeasureMode == YGMeasureModeAtMost) {
1784
- height = padding[YGEdgeTop] + padding[YGEdgeBottom] + border[YGEdgeTop] +
1785
- border[YGEdgeBottom];
1786
- }
1787
- node->setLayoutMeasuredDimension(
1788
- YGNodeBoundAxis(
1789
- node, YGFlexDirectionColumn, height, ownerHeight, ownerWidth),
1790
- YGDimensionHeight);
794
+ float YGNodeLayoutGetTop(const YGNodeConstRef node) {
795
+ return resolveRef(node)->getLayout().position[YGEdgeTop];
1791
796
  }
1792
797
 
1793
- static bool YGNodeFixedSizeSetMeasuredDimensions(
1794
- const YGNodeRef node,
1795
- const float availableWidth,
1796
- const float availableHeight,
1797
- const YGMeasureMode widthMeasureMode,
1798
- const YGMeasureMode heightMeasureMode,
1799
- const float ownerWidth,
1800
- const float ownerHeight) {
1801
- if ((!YGFloatIsUndefined(availableWidth) &&
1802
- widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) ||
1803
- (!YGFloatIsUndefined(availableHeight) &&
1804
- heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) ||
1805
- (widthMeasureMode == YGMeasureModeExactly &&
1806
- heightMeasureMode == YGMeasureModeExactly)) {
1807
- node->setLayoutMeasuredDimension(
1808
- YGNodeBoundAxis(
1809
- node,
1810
- YGFlexDirectionRow,
1811
- YGFloatIsUndefined(availableWidth) ||
1812
- (widthMeasureMode == YGMeasureModeAtMost &&
1813
- availableWidth < 0.0f)
1814
- ? 0.0f
1815
- : availableWidth,
1816
- ownerWidth,
1817
- ownerWidth),
1818
- YGDimensionWidth);
1819
-
1820
- node->setLayoutMeasuredDimension(
1821
- YGNodeBoundAxis(
1822
- node,
1823
- YGFlexDirectionColumn,
1824
- YGFloatIsUndefined(availableHeight) ||
1825
- (heightMeasureMode == YGMeasureModeAtMost &&
1826
- availableHeight < 0.0f)
1827
- ? 0.0f
1828
- : availableHeight,
1829
- ownerHeight,
1830
- ownerWidth),
1831
- YGDimensionHeight);
1832
- return true;
1833
- }
1834
-
1835
- return false;
798
+ float YGNodeLayoutGetRight(const YGNodeConstRef node) {
799
+ return resolveRef(node)->getLayout().position[YGEdgeRight];
1836
800
  }
1837
801
 
1838
- static void YGZeroOutLayoutRecursivly(
1839
- const YGNodeRef node,
1840
- void *layoutContext) {
1841
- node->getLayout() = {};
1842
- node->setLayoutDimension(0, 0);
1843
- node->setLayoutDimension(0, 1);
1844
- node->setHasNewLayout(true);
1845
-
1846
- node->iterChildrenAfterCloningIfNeeded(
1847
- YGZeroOutLayoutRecursivly, layoutContext);
1848
- }
1849
-
1850
- static float YGNodeCalculateAvailableInnerDim(
1851
- const YGNodeConstRef node,
1852
- const YGDimension dimension,
1853
- const float availableDim,
1854
- const float paddingAndBorder,
1855
- const float ownerDim) {
1856
- float availableInnerDim = availableDim - paddingAndBorder;
1857
- // Max dimension overrides predefined dimension value; Min dimension in turn
1858
- // overrides both of the above
1859
- if (!YGFloatIsUndefined(availableInnerDim)) {
1860
- // We want to make sure our available height does not violate min and max
1861
- // constraints
1862
- const YGFloatOptional minDimensionOptional =
1863
- YGResolveValue(node->getStyle().minDimensions()[dimension], ownerDim);
1864
- const float minInnerDim = minDimensionOptional.isUndefined()
1865
- ? 0.0f
1866
- : minDimensionOptional.unwrap() - paddingAndBorder;
1867
-
1868
- const YGFloatOptional maxDimensionOptional =
1869
- YGResolveValue(node->getStyle().maxDimensions()[dimension], ownerDim);
1870
-
1871
- const float maxInnerDim = maxDimensionOptional.isUndefined()
1872
- ? FLT_MAX
1873
- : maxDimensionOptional.unwrap() - paddingAndBorder;
1874
- availableInnerDim =
1875
- YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim);
1876
- }
1877
-
1878
- return availableInnerDim;
802
+ float YGNodeLayoutGetBottom(const YGNodeConstRef node) {
803
+ return resolveRef(node)->getLayout().position[YGEdgeBottom];
1879
804
  }
1880
805
 
1881
- static float YGNodeComputeFlexBasisForChildren(
1882
- const YGNodeRef node,
1883
- const float availableInnerWidth,
1884
- const float availableInnerHeight,
1885
- YGMeasureMode widthMeasureMode,
1886
- YGMeasureMode heightMeasureMode,
1887
- YGDirection direction,
1888
- YGFlexDirection mainAxis,
1889
- const YGConfigRef config,
1890
- bool performLayout,
1891
- LayoutData &layoutMarkerData,
1892
- void *const layoutContext,
1893
- const uint32_t depth,
1894
- const uint32_t generationCount) {
1895
- float totalOuterFlexBasis = 0.0f;
1896
- YGNodeRef singleFlexChild = nullptr;
1897
- const YGVector& children = node->getChildren();
1898
- YGMeasureMode measureModeMainDim =
1899
- YGFlexDirectionIsRow(mainAxis) ? widthMeasureMode : heightMeasureMode;
1900
- // If there is only one child with flexGrow + flexShrink it means we can set
1901
- // the computedFlexBasis to 0 instead of measuring and shrinking / flexing the
1902
- // child to exactly match the remaining space
1903
- if (measureModeMainDim == YGMeasureModeExactly) {
1904
- for (auto child : children) {
1905
- if (child->isNodeFlexible()) {
1906
- if (singleFlexChild != nullptr ||
1907
- YGFloatsEqual(child->resolveFlexGrow(), 0.0f) ||
1908
- YGFloatsEqual(child->resolveFlexShrink(), 0.0f)) {
1909
- // There is already a flexible child, or this flexible child doesn't
1910
- // have flexGrow and flexShrink, abort
1911
- singleFlexChild = nullptr;
1912
- break;
1913
- } else {
1914
- singleFlexChild = child;
1915
- }
1916
- }
1917
- }
1918
- }
1919
-
1920
- for (auto child : children) {
1921
- child->resolveDimension();
1922
- if (child->getStyle().display() == YGDisplayNone) {
1923
- YGZeroOutLayoutRecursivly(child, layoutContext);
1924
- child->setHasNewLayout(true);
1925
- child->setDirty(false);
1926
- continue;
1927
- }
1928
- if (performLayout) {
1929
- // Set the initial position (relative to the owner).
1930
- const YGDirection childDirection = child->resolveDirection(direction);
1931
- const float mainDim = YGFlexDirectionIsRow(mainAxis)
1932
- ? availableInnerWidth
1933
- : availableInnerHeight;
1934
- const float crossDim = YGFlexDirectionIsRow(mainAxis)
1935
- ? availableInnerHeight
1936
- : availableInnerWidth;
1937
- child->setPosition(
1938
- childDirection, mainDim, crossDim, availableInnerWidth);
1939
- }
1940
-
1941
- if (child->getStyle().positionType() == YGPositionTypeAbsolute) {
1942
- continue;
1943
- }
1944
- if (child == singleFlexChild) {
1945
- child->setLayoutComputedFlexBasisGeneration(generationCount);
1946
- child->setLayoutComputedFlexBasis(YGFloatOptional(0));
1947
- } else {
1948
- YGNodeComputeFlexBasisForChild(
1949
- node,
1950
- child,
1951
- availableInnerWidth,
1952
- widthMeasureMode,
1953
- availableInnerHeight,
1954
- availableInnerWidth,
1955
- availableInnerHeight,
1956
- heightMeasureMode,
1957
- direction,
1958
- config,
1959
- layoutMarkerData,
1960
- layoutContext,
1961
- depth,
1962
- generationCount);
1963
- }
1964
-
1965
- totalOuterFlexBasis +=
1966
- (child->getLayout().computedFlexBasis +
1967
- child->getMarginForAxis(mainAxis, availableInnerWidth))
1968
- .unwrap();
1969
- }
1970
-
1971
- return totalOuterFlexBasis;
1972
- }
1973
-
1974
- // This function assumes that all the children of node have their
1975
- // computedFlexBasis properly computed(To do this use
1976
- // YGNodeComputeFlexBasisForChildren function). This function calculates
1977
- // YGCollectFlexItemsRowMeasurement
1978
- static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
1979
- const YGNodeRef &node,
1980
- const YGDirection ownerDirection,
1981
- const float mainAxisownerSize,
1982
- const float availableInnerWidth,
1983
- const float availableInnerMainDim,
1984
- const uint32_t startOfLineIndex,
1985
- const uint32_t lineCount) {
1986
- YGCollectFlexItemsRowValues flexAlgoRowMeasurement = {};
1987
- flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size());
1988
-
1989
- float sizeConsumedOnCurrentLineIncludingMinConstraint = 0;
1990
- const YGFlexDirection mainAxis = YGResolveFlexDirection(
1991
- node->getStyle().flexDirection(), node->resolveDirection(ownerDirection));
1992
- const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
1993
- const float gap = node->getGapForAxis(mainAxis, availableInnerWidth).unwrap();
1994
-
1995
- // Add items to the current line until it's full or we run out of items.
1996
- uint32_t endOfLineIndex = startOfLineIndex;
1997
- for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) {
1998
- const YGNodeRef child = node->getChild(endOfLineIndex);
1999
- if (child->getStyle().display() == YGDisplayNone ||
2000
- child->getStyle().positionType() == YGPositionTypeAbsolute) {
2001
- continue;
2002
- }
2003
-
2004
- const bool isFirstElementInLine = (endOfLineIndex - startOfLineIndex) == 0;
2005
-
2006
- child->setLineIndex(lineCount);
2007
- const float childMarginMainAxis =
2008
- child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap();
2009
- const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap;
2010
- const float flexBasisWithMinAndMaxConstraints =
2011
- YGNodeBoundAxisWithinMinAndMax(
2012
- child,
2013
- mainAxis,
2014
- child->getLayout().computedFlexBasis,
2015
- mainAxisownerSize)
2016
- .unwrap();
2017
-
2018
- // If this is a multi-line flow and this item pushes us over the available
2019
- // size, we've hit the end of the current line. Break out of the loop and
2020
- // lay out the current line.
2021
- if (sizeConsumedOnCurrentLineIncludingMinConstraint +
2022
- flexBasisWithMinAndMaxConstraints + childMarginMainAxis +
2023
- childLeadingGapMainAxis >
2024
- availableInnerMainDim &&
2025
- isNodeFlexWrap && flexAlgoRowMeasurement.itemsOnLine > 0) {
2026
- break;
2027
- }
2028
-
2029
- sizeConsumedOnCurrentLineIncludingMinConstraint +=
2030
- flexBasisWithMinAndMaxConstraints + childMarginMainAxis +
2031
- childLeadingGapMainAxis;
2032
- flexAlgoRowMeasurement.sizeConsumedOnCurrentLine +=
2033
- flexBasisWithMinAndMaxConstraints + childMarginMainAxis +
2034
- childLeadingGapMainAxis;
2035
- flexAlgoRowMeasurement.itemsOnLine++;
2036
-
2037
- if (child->isNodeFlexible()) {
2038
- flexAlgoRowMeasurement.totalFlexGrowFactors += child->resolveFlexGrow();
2039
-
2040
- // Unlike the grow factor, the shrink factor is scaled relative to the
2041
- // child dimension.
2042
- flexAlgoRowMeasurement.totalFlexShrinkScaledFactors +=
2043
- -child->resolveFlexShrink() *
2044
- child->getLayout().computedFlexBasis.unwrap();
2045
- }
2046
-
2047
- flexAlgoRowMeasurement.relativeChildren.push_back(child);
2048
- }
2049
-
2050
- // The total flex factor needs to be floored to 1.
2051
- if (flexAlgoRowMeasurement.totalFlexGrowFactors > 0 &&
2052
- flexAlgoRowMeasurement.totalFlexGrowFactors < 1) {
2053
- flexAlgoRowMeasurement.totalFlexGrowFactors = 1;
2054
- }
2055
-
2056
- // The total flex shrink factor needs to be floored to 1.
2057
- if (flexAlgoRowMeasurement.totalFlexShrinkScaledFactors > 0 &&
2058
- flexAlgoRowMeasurement.totalFlexShrinkScaledFactors < 1) {
2059
- flexAlgoRowMeasurement.totalFlexShrinkScaledFactors = 1;
2060
- }
2061
- flexAlgoRowMeasurement.endOfLineIndex = endOfLineIndex;
2062
- return flexAlgoRowMeasurement;
806
+ float YGNodeLayoutGetWidth(const YGNodeConstRef node) {
807
+ return resolveRef(node)->getLayout().dimension(YGDimensionWidth);
2063
808
  }
2064
809
 
2065
- // It distributes the free space to the flexible items and ensures that the size
2066
- // of the flex items abide the min and max constraints. At the end of this
2067
- // function the child nodes would have proper size. Prior using this function
2068
- // please ensure that YGDistributeFreeSpaceFirstPass is called.
2069
- static float YGDistributeFreeSpaceSecondPass(
2070
- YGCollectFlexItemsRowValues &collectedFlexItemsValues,
2071
- const YGNodeRef node,
2072
- const YGFlexDirection mainAxis,
2073
- const YGFlexDirection crossAxis,
2074
- const float mainAxisownerSize,
2075
- const float availableInnerMainDim,
2076
- const float availableInnerCrossDim,
2077
- const float availableInnerWidth,
2078
- const float availableInnerHeight,
2079
- const bool mainAxisOverflows,
2080
- const YGMeasureMode measureModeCrossDim,
2081
- const bool performLayout,
2082
- const YGConfigRef config,
2083
- LayoutData &layoutMarkerData,
2084
- void *const layoutContext,
2085
- const uint32_t depth,
2086
- const uint32_t generationCount) {
2087
- float childFlexBasis = 0;
2088
- float flexShrinkScaledFactor = 0;
2089
- float flexGrowFactor = 0;
2090
- float deltaFreeSpace = 0;
2091
- const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
2092
- const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
2093
-
2094
- for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
2095
- childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
2096
- currentRelativeChild,
2097
- mainAxis,
2098
- currentRelativeChild->getLayout().computedFlexBasis,
2099
- mainAxisownerSize)
2100
- .unwrap();
2101
- float updatedMainSize = childFlexBasis;
2102
-
2103
- if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
2104
- collectedFlexItemsValues.remainingFreeSpace < 0) {
2105
- flexShrinkScaledFactor =
2106
- -currentRelativeChild->resolveFlexShrink() * childFlexBasis;
2107
- // Is this child able to shrink?
2108
- if (flexShrinkScaledFactor != 0) {
2109
- float childSize;
2110
-
2111
- if (!YGFloatIsUndefined(
2112
- collectedFlexItemsValues.totalFlexShrinkScaledFactors) &&
2113
- collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
2114
- childSize = childFlexBasis + flexShrinkScaledFactor;
2115
- } else {
2116
- childSize = childFlexBasis +
2117
- (collectedFlexItemsValues.remainingFreeSpace /
2118
- collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
2119
- flexShrinkScaledFactor;
2120
- }
2121
-
2122
- updatedMainSize = YGNodeBoundAxis(
2123
- currentRelativeChild,
2124
- mainAxis,
2125
- childSize,
2126
- availableInnerMainDim,
2127
- availableInnerWidth);
2128
- }
2129
- } else if (
2130
- !YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
2131
- collectedFlexItemsValues.remainingFreeSpace > 0) {
2132
- flexGrowFactor = currentRelativeChild->resolveFlexGrow();
2133
-
2134
- // Is this child able to grow?
2135
- if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) {
2136
- updatedMainSize = YGNodeBoundAxis(
2137
- currentRelativeChild,
2138
- mainAxis,
2139
- childFlexBasis +
2140
- collectedFlexItemsValues.remainingFreeSpace /
2141
- collectedFlexItemsValues.totalFlexGrowFactors *
2142
- flexGrowFactor,
2143
- availableInnerMainDim,
2144
- availableInnerWidth);
2145
- }
2146
- }
2147
-
2148
- deltaFreeSpace += updatedMainSize - childFlexBasis;
2149
-
2150
- const float marginMain =
2151
- currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)
2152
- .unwrap();
2153
- const float marginCross =
2154
- currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)
2155
- .unwrap();
2156
-
2157
- float childCrossSize;
2158
- float childMainSize = updatedMainSize + marginMain;
2159
- YGMeasureMode childCrossMeasureMode;
2160
- YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
2161
-
2162
- const auto &childStyle = currentRelativeChild->getStyle();
2163
- if (!childStyle.aspectRatio().isUndefined()) {
2164
- childCrossSize = isMainAxisRow
2165
- ? (childMainSize - marginMain) / childStyle.aspectRatio().unwrap()
2166
- : (childMainSize - marginMain) * childStyle.aspectRatio().unwrap();
2167
- childCrossMeasureMode = YGMeasureModeExactly;
2168
-
2169
- childCrossSize += marginCross;
2170
- } else if (
2171
- !YGFloatIsUndefined(availableInnerCrossDim) &&
2172
- !YGNodeIsStyleDimDefined(
2173
- currentRelativeChild, crossAxis, availableInnerCrossDim) &&
2174
- measureModeCrossDim == YGMeasureModeExactly &&
2175
- !(isNodeFlexWrap && mainAxisOverflows) &&
2176
- YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
2177
- currentRelativeChild->marginLeadingValue(crossAxis).unit !=
2178
- YGUnitAuto &&
2179
- currentRelativeChild->marginTrailingValue(crossAxis).unit !=
2180
- YGUnitAuto) {
2181
- childCrossSize = availableInnerCrossDim;
2182
- childCrossMeasureMode = YGMeasureModeExactly;
2183
- } else if (!YGNodeIsStyleDimDefined(
2184
- currentRelativeChild, crossAxis, availableInnerCrossDim)) {
2185
- childCrossSize = availableInnerCrossDim;
2186
- childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
2187
- ? YGMeasureModeUndefined
2188
- : YGMeasureModeAtMost;
2189
- } else {
2190
- childCrossSize =
2191
- YGResolveValue(
2192
- currentRelativeChild->getResolvedDimension(dim[crossAxis]),
2193
- availableInnerCrossDim)
2194
- .unwrap() +
2195
- marginCross;
2196
- const bool isLoosePercentageMeasurement =
2197
- currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit ==
2198
- YGUnitPercent &&
2199
- measureModeCrossDim != YGMeasureModeExactly;
2200
- childCrossMeasureMode =
2201
- YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement
2202
- ? YGMeasureModeUndefined
2203
- : YGMeasureModeExactly;
2204
- }
2205
-
2206
- YGConstrainMaxSizeForMode(
2207
- currentRelativeChild,
2208
- mainAxis,
2209
- availableInnerMainDim,
2210
- availableInnerWidth,
2211
- &childMainMeasureMode,
2212
- &childMainSize);
2213
- YGConstrainMaxSizeForMode(
2214
- currentRelativeChild,
2215
- crossAxis,
2216
- availableInnerCrossDim,
2217
- availableInnerWidth,
2218
- &childCrossMeasureMode,
2219
- &childCrossSize);
2220
-
2221
- const bool requiresStretchLayout =
2222
- !YGNodeIsStyleDimDefined(
2223
- currentRelativeChild, crossAxis, availableInnerCrossDim) &&
2224
- YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
2225
- currentRelativeChild->marginLeadingValue(crossAxis).unit !=
2226
- YGUnitAuto &&
2227
- currentRelativeChild->marginTrailingValue(crossAxis).unit != YGUnitAuto;
2228
-
2229
- const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
2230
- const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize;
2231
-
2232
- const YGMeasureMode childWidthMeasureMode =
2233
- isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
2234
- const YGMeasureMode childHeightMeasureMode =
2235
- !isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
2236
-
2237
- const bool isLayoutPass = performLayout && !requiresStretchLayout;
2238
- // Recursively call the layout algorithm for this child with the updated
2239
- // main size.
2240
- YGLayoutNodeInternal(
2241
- currentRelativeChild,
2242
- childWidth,
2243
- childHeight,
2244
- node->getLayout().direction(),
2245
- childWidthMeasureMode,
2246
- childHeightMeasureMode,
2247
- availableInnerWidth,
2248
- availableInnerHeight,
2249
- isLayoutPass,
2250
- isLayoutPass ? LayoutPassReason::kFlexLayout
2251
- : LayoutPassReason::kFlexMeasure,
2252
- config,
2253
- layoutMarkerData,
2254
- layoutContext,
2255
- depth,
2256
- generationCount);
2257
- node->setLayoutHadOverflow(
2258
- node->getLayout().hadOverflow() ||
2259
- currentRelativeChild->getLayout().hadOverflow());
2260
- }
2261
- return deltaFreeSpace;
2262
- }
2263
-
2264
- // It distributes the free space to the flexible items.For those flexible items
2265
- // whose min and max constraints are triggered, those flex item's clamped size
2266
- // is removed from the remaingfreespace.
2267
- static void YGDistributeFreeSpaceFirstPass(
2268
- YGCollectFlexItemsRowValues &collectedFlexItemsValues,
2269
- const YGFlexDirection mainAxis,
2270
- const float mainAxisownerSize,
2271
- const float availableInnerMainDim,
2272
- const float availableInnerWidth) {
2273
- float flexShrinkScaledFactor = 0;
2274
- float flexGrowFactor = 0;
2275
- float baseMainSize = 0;
2276
- float boundMainSize = 0;
2277
- float deltaFreeSpace = 0;
2278
-
2279
- for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
2280
- float childFlexBasis =
2281
- YGNodeBoundAxisWithinMinAndMax(
2282
- currentRelativeChild,
2283
- mainAxis,
2284
- currentRelativeChild->getLayout().computedFlexBasis,
2285
- mainAxisownerSize)
2286
- .unwrap();
2287
-
2288
- if (collectedFlexItemsValues.remainingFreeSpace < 0) {
2289
- flexShrinkScaledFactor =
2290
- -currentRelativeChild->resolveFlexShrink() * childFlexBasis;
2291
-
2292
- // Is this child able to shrink?
2293
- if (!YGFloatIsUndefined(flexShrinkScaledFactor) &&
2294
- flexShrinkScaledFactor != 0) {
2295
- baseMainSize = childFlexBasis +
2296
- collectedFlexItemsValues.remainingFreeSpace /
2297
- collectedFlexItemsValues.totalFlexShrinkScaledFactors *
2298
- flexShrinkScaledFactor;
2299
- boundMainSize = YGNodeBoundAxis(
2300
- currentRelativeChild,
2301
- mainAxis,
2302
- baseMainSize,
2303
- availableInnerMainDim,
2304
- availableInnerWidth);
2305
- if (!YGFloatIsUndefined(baseMainSize) &&
2306
- !YGFloatIsUndefined(boundMainSize) &&
2307
- baseMainSize != boundMainSize) {
2308
- // By excluding this item's size and flex factor from remaining, this
2309
- // item's min/max constraints should also trigger in the second pass
2310
- // resulting in the item's size calculation being identical in the
2311
- // first and second passes.
2312
- deltaFreeSpace += boundMainSize - childFlexBasis;
2313
- collectedFlexItemsValues.totalFlexShrinkScaledFactors -=
2314
- (-currentRelativeChild->resolveFlexShrink() *
2315
- currentRelativeChild->getLayout().computedFlexBasis.unwrap());
2316
- }
2317
- }
2318
- } else if (
2319
- !YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
2320
- collectedFlexItemsValues.remainingFreeSpace > 0) {
2321
- flexGrowFactor = currentRelativeChild->resolveFlexGrow();
2322
-
2323
- // Is this child able to grow?
2324
- if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) {
2325
- baseMainSize = childFlexBasis +
2326
- collectedFlexItemsValues.remainingFreeSpace /
2327
- collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor;
2328
- boundMainSize = YGNodeBoundAxis(
2329
- currentRelativeChild,
2330
- mainAxis,
2331
- baseMainSize,
2332
- availableInnerMainDim,
2333
- availableInnerWidth);
2334
-
2335
- if (!YGFloatIsUndefined(baseMainSize) &&
2336
- !YGFloatIsUndefined(boundMainSize) &&
2337
- baseMainSize != boundMainSize) {
2338
- // By excluding this item's size and flex factor from remaining, this
2339
- // item's min/max constraints should also trigger in the second pass
2340
- // resulting in the item's size calculation being identical in the
2341
- // first and second passes.
2342
- deltaFreeSpace += boundMainSize - childFlexBasis;
2343
- collectedFlexItemsValues.totalFlexGrowFactors -= flexGrowFactor;
2344
- }
2345
- }
2346
- }
2347
- }
2348
- collectedFlexItemsValues.remainingFreeSpace -= deltaFreeSpace;
2349
- }
2350
-
2351
- // Do two passes over the flex items to figure out how to distribute the
2352
- // remaining space.
2353
- //
2354
- // The first pass finds the items whose min/max constraints trigger, freezes
2355
- // them at those sizes, and excludes those sizes from the remaining space.
2356
- //
2357
- // The second pass sets the size of each flexible item. It distributes the
2358
- // remaining space amongst the items whose min/max constraints didn't trigger in
2359
- // the first pass. For the other items, it sets their sizes by forcing their
2360
- // min/max constraints to trigger again.
2361
- //
2362
- // This two pass approach for resolving min/max constraints deviates from the
2363
- // spec. The spec
2364
- // (https://www.w3.org/TR/CSS-flexbox-1/#resolve-flexible-lengths) describes a
2365
- // process that needs to be repeated a variable number of times. The algorithm
2366
- // implemented here won't handle all cases but it was simpler to implement and
2367
- // it mitigates performance concerns because we know exactly how many passes
2368
- // it'll do.
2369
- //
2370
- // At the end of this function the child nodes would have the proper size
2371
- // assigned to them.
2372
- //
2373
- static void YGResolveFlexibleLength(
2374
- const YGNodeRef node,
2375
- YGCollectFlexItemsRowValues &collectedFlexItemsValues,
2376
- const YGFlexDirection mainAxis,
2377
- const YGFlexDirection crossAxis,
2378
- const float mainAxisownerSize,
2379
- const float availableInnerMainDim,
2380
- const float availableInnerCrossDim,
2381
- const float availableInnerWidth,
2382
- const float availableInnerHeight,
2383
- const bool mainAxisOverflows,
2384
- const YGMeasureMode measureModeCrossDim,
2385
- const bool performLayout,
2386
- const YGConfigRef config,
2387
- LayoutData &layoutMarkerData,
2388
- void *const layoutContext,
2389
- const uint32_t depth,
2390
- const uint32_t generationCount) {
2391
- const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace;
2392
- // First pass: detect the flex items whose min/max constraints trigger
2393
- YGDistributeFreeSpaceFirstPass(
2394
- collectedFlexItemsValues,
2395
- mainAxis,
2396
- mainAxisownerSize,
2397
- availableInnerMainDim,
2398
- availableInnerWidth);
2399
-
2400
- // Second pass: resolve the sizes of the flexible items
2401
- const float distributedFreeSpace = YGDistributeFreeSpaceSecondPass(
2402
- collectedFlexItemsValues,
2403
- node,
2404
- mainAxis,
2405
- crossAxis,
2406
- mainAxisownerSize,
2407
- availableInnerMainDim,
2408
- availableInnerCrossDim,
2409
- availableInnerWidth,
2410
- availableInnerHeight,
2411
- mainAxisOverflows,
2412
- measureModeCrossDim,
2413
- performLayout,
2414
- config,
2415
- layoutMarkerData,
2416
- layoutContext,
2417
- depth,
2418
- generationCount);
2419
-
2420
- collectedFlexItemsValues.remainingFreeSpace =
2421
- originalFreeSpace - distributedFreeSpace;
2422
- }
2423
-
2424
- static void YGJustifyMainAxis(
2425
- const YGNodeRef node,
2426
- YGCollectFlexItemsRowValues &collectedFlexItemsValues,
2427
- const uint32_t startOfLineIndex,
2428
- const YGFlexDirection mainAxis,
2429
- const YGFlexDirection crossAxis,
2430
- const YGMeasureMode measureModeMainDim,
2431
- const YGMeasureMode measureModeCrossDim,
2432
- const float mainAxisownerSize,
2433
- const float ownerWidth,
2434
- const float availableInnerMainDim,
2435
- const float availableInnerCrossDim,
2436
- const float availableInnerWidth,
2437
- const bool performLayout,
2438
- void *const layoutContext) {
2439
- const auto &style = node->getStyle();
2440
- const float leadingPaddingAndBorderMain =
2441
- node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap();
2442
- const float trailingPaddingAndBorderMain =
2443
- node->getTrailingPaddingAndBorder(mainAxis, ownerWidth).unwrap();
2444
- const float gap = node->getGapForAxis(mainAxis, ownerWidth).unwrap();
2445
- // If we are using "at most" rules in the main axis, make sure that
2446
- // remainingFreeSpace is 0 when min main dimension is not given
2447
- if (measureModeMainDim == YGMeasureModeAtMost &&
2448
- collectedFlexItemsValues.remainingFreeSpace > 0) {
2449
- if (!style.minDimensions()[dim[mainAxis]].isUndefined() &&
2450
- !YGResolveValue(style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
2451
- .isUndefined()) {
2452
- // This condition makes sure that if the size of main dimension(after
2453
- // considering child nodes main dim, leading and trailing padding etc)
2454
- // falls below min dimension, then the remainingFreeSpace is reassigned
2455
- // considering the min dimension
2456
-
2457
- // `minAvailableMainDim` denotes minimum available space in which child
2458
- // can be laid out, it will exclude space consumed by padding and border.
2459
- const float minAvailableMainDim =
2460
- YGResolveValue(
2461
- style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
2462
- .unwrap() -
2463
- leadingPaddingAndBorderMain - trailingPaddingAndBorderMain;
2464
- const float occupiedSpaceByChildNodes =
2465
- availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace;
2466
- collectedFlexItemsValues.remainingFreeSpace =
2467
- YGFloatMax(0, minAvailableMainDim - occupiedSpaceByChildNodes);
2468
- } else {
2469
- collectedFlexItemsValues.remainingFreeSpace = 0;
2470
- }
2471
- }
2472
-
2473
- int numberOfAutoMarginsOnCurrentLine = 0;
2474
- for (uint32_t i = startOfLineIndex;
2475
- i < collectedFlexItemsValues.endOfLineIndex;
2476
- i++) {
2477
- const YGNodeRef child = node->getChild(i);
2478
- if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
2479
- if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
2480
- numberOfAutoMarginsOnCurrentLine++;
2481
- }
2482
- if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) {
2483
- numberOfAutoMarginsOnCurrentLine++;
2484
- }
2485
- }
2486
- }
2487
-
2488
- // In order to position the elements in the main axis, we have two controls.
2489
- // The space between the beginning and the first element and the space between
2490
- // each two elements.
2491
- float leadingMainDim = 0;
2492
- float betweenMainDim = gap;
2493
- const YGJustify justifyContent = node->getStyle().justifyContent();
2494
-
2495
- if (numberOfAutoMarginsOnCurrentLine == 0) {
2496
- switch (justifyContent) {
2497
- case YGJustifyCenter:
2498
- leadingMainDim = collectedFlexItemsValues.remainingFreeSpace / 2;
2499
- break;
2500
- case YGJustifyFlexEnd:
2501
- leadingMainDim = collectedFlexItemsValues.remainingFreeSpace;
2502
- break;
2503
- case YGJustifySpaceBetween:
2504
- if (collectedFlexItemsValues.itemsOnLine > 1) {
2505
- betweenMainDim +=
2506
- YGFloatMax(collectedFlexItemsValues.remainingFreeSpace, 0) /
2507
- (collectedFlexItemsValues.itemsOnLine - 1);
2508
- }
2509
- break;
2510
- case YGJustifySpaceEvenly:
2511
- // Space is distributed evenly across all elements
2512
- leadingMainDim = collectedFlexItemsValues.remainingFreeSpace /
2513
- (collectedFlexItemsValues.itemsOnLine + 1);
2514
- betweenMainDim += leadingMainDim;
2515
- break;
2516
- case YGJustifySpaceAround:
2517
- // Space on the edges is half of the space between elements
2518
- leadingMainDim = 0.5f * collectedFlexItemsValues.remainingFreeSpace /
2519
- collectedFlexItemsValues.itemsOnLine;
2520
- betweenMainDim += leadingMainDim * 2;
2521
- break;
2522
- case YGJustifyFlexStart:
2523
- break;
2524
- }
2525
- }
2526
-
2527
- collectedFlexItemsValues.mainDim =
2528
- leadingPaddingAndBorderMain + leadingMainDim;
2529
- collectedFlexItemsValues.crossDim = 0;
2530
-
2531
- float maxAscentForCurrentLine = 0;
2532
- float maxDescentForCurrentLine = 0;
2533
- bool isNodeBaselineLayout = YGIsBaselineLayout(node);
2534
- for (uint32_t i = startOfLineIndex;
2535
- i < collectedFlexItemsValues.endOfLineIndex;
2536
- i++) {
2537
- const YGNodeRef child = node->getChild(i);
2538
- const YGStyle &childStyle = child->getStyle();
2539
- const YGLayout childLayout = child->getLayout();
2540
- const bool isLastChild = i == collectedFlexItemsValues.endOfLineIndex - 1;
2541
- // remove the gap if it is the last element of the line
2542
- if (isLastChild) {
2543
- betweenMainDim -= gap;
2544
- }
2545
- if (childStyle.display() == YGDisplayNone) {
2546
- continue;
2547
- }
2548
- if (childStyle.positionType() == YGPositionTypeAbsolute &&
2549
- child->isLeadingPositionDefined(mainAxis)) {
2550
- if (performLayout) {
2551
- // In case the child is position absolute and has left/top being
2552
- // defined, we override the position to whatever the user said (and
2553
- // margin/border).
2554
- child->setLayoutPosition(
2555
- child->getLeadingPosition(mainAxis, availableInnerMainDim)
2556
- .unwrap() +
2557
- node->getLeadingBorder(mainAxis) +
2558
- child->getLeadingMargin(mainAxis, availableInnerWidth).unwrap(),
2559
- pos[mainAxis]);
2560
- }
2561
- } else {
2562
- // Now that we placed the element, we need to update the variables.
2563
- // We need to do that only for relative elements. Absolute elements do not
2564
- // take part in that phase.
2565
- if (childStyle.positionType() != YGPositionTypeAbsolute) {
2566
- if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
2567
- collectedFlexItemsValues.mainDim +=
2568
- collectedFlexItemsValues.remainingFreeSpace /
2569
- numberOfAutoMarginsOnCurrentLine;
2570
- }
2571
-
2572
- if (performLayout) {
2573
- child->setLayoutPosition(
2574
- childLayout.position[pos[mainAxis]] +
2575
- collectedFlexItemsValues.mainDim,
2576
- pos[mainAxis]);
2577
- }
2578
-
2579
- if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) {
2580
- collectedFlexItemsValues.mainDim +=
2581
- collectedFlexItemsValues.remainingFreeSpace /
2582
- numberOfAutoMarginsOnCurrentLine;
2583
- }
2584
- bool canSkipFlex =
2585
- !performLayout && measureModeCrossDim == YGMeasureModeExactly;
2586
- if (canSkipFlex) {
2587
- // If we skipped the flex step, then we can't rely on the measuredDims
2588
- // because they weren't computed. This means we can't call
2589
- // YGNodeDimWithMargin.
2590
- collectedFlexItemsValues.mainDim += betweenMainDim +
2591
- child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap() +
2592
- childLayout.computedFlexBasis.unwrap();
2593
- collectedFlexItemsValues.crossDim = availableInnerCrossDim;
2594
- } else {
2595
- // The main dimension is the sum of all the elements dimension plus
2596
- // the spacing.
2597
- collectedFlexItemsValues.mainDim += betweenMainDim +
2598
- YGNodeDimWithMargin(child, mainAxis, availableInnerWidth);
2599
-
2600
- if (isNodeBaselineLayout) {
2601
- // If the child is baseline aligned then the cross dimension is
2602
- // calculated by adding maxAscent and maxDescent from the baseline.
2603
- const float ascent = YGBaseline(child, layoutContext) +
2604
- child
2605
- ->getLeadingMargin(
2606
- YGFlexDirectionColumn, availableInnerWidth)
2607
- .unwrap();
2608
- const float descent =
2609
- child->getLayout().measuredDimensions[YGDimensionHeight] +
2610
- child
2611
- ->getMarginForAxis(
2612
- YGFlexDirectionColumn, availableInnerWidth)
2613
- .unwrap() -
2614
- ascent;
2615
-
2616
- maxAscentForCurrentLine =
2617
- YGFloatMax(maxAscentForCurrentLine, ascent);
2618
- maxDescentForCurrentLine =
2619
- YGFloatMax(maxDescentForCurrentLine, descent);
2620
- } else {
2621
- // The cross dimension is the max of the elements dimension since
2622
- // there can only be one element in that cross dimension in the case
2623
- // when the items are not baseline aligned
2624
- collectedFlexItemsValues.crossDim = YGFloatMax(
2625
- collectedFlexItemsValues.crossDim,
2626
- YGNodeDimWithMargin(child, crossAxis, availableInnerWidth));
2627
- }
2628
- }
2629
- } else if (performLayout) {
2630
- child->setLayoutPosition(
2631
- childLayout.position[pos[mainAxis]] +
2632
- node->getLeadingBorder(mainAxis) + leadingMainDim,
2633
- pos[mainAxis]);
2634
- }
2635
- }
2636
- }
2637
- collectedFlexItemsValues.mainDim += trailingPaddingAndBorderMain;
2638
-
2639
- if (isNodeBaselineLayout) {
2640
- collectedFlexItemsValues.crossDim =
2641
- maxAscentForCurrentLine + maxDescentForCurrentLine;
2642
- }
810
+ float YGNodeLayoutGetHeight(const YGNodeConstRef node) {
811
+ return resolveRef(node)->getLayout().dimension(YGDimensionHeight);
2643
812
  }
2644
813
 
2645
- //
2646
- // This is the main routine that implements a subset of the flexbox layout
2647
- // algorithm described in the W3C CSS documentation:
2648
- // https://www.w3.org/TR/CSS3-flexbox/.
2649
- //
2650
- // Limitations of this algorithm, compared to the full standard:
2651
- // * Display property is always assumed to be 'flex' except for Text nodes,
2652
- // which are assumed to be 'inline-flex'.
2653
- // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes
2654
- // are stacked in document order.
2655
- // * The 'order' property is not supported. The order of flex items is always
2656
- // defined by document order.
2657
- // * The 'visibility' property is always assumed to be 'visible'. Values of
2658
- // 'collapse' and 'hidden' are not supported.
2659
- // * There is no support for forced breaks.
2660
- // * It does not support vertical inline directions (top-to-bottom or
2661
- // bottom-to-top text).
2662
- //
2663
- // Deviations from standard:
2664
- // * Section 4.5 of the spec indicates that all flex items have a default
2665
- // minimum main size. For text blocks, for example, this is the width of the
2666
- // widest word. Calculating the minimum width is expensive, so we forego it
2667
- // and assume a default minimum main size of 0.
2668
- // * Min/Max sizes in the main axis are not honored when resolving flexible
2669
- // lengths.
2670
- // * The spec indicates that the default value for 'flexDirection' is 'row',
2671
- // but the algorithm below assumes a default of 'column'.
2672
- //
2673
- // Input parameters:
2674
- // - node: current node to be sized and laid out
2675
- // - availableWidth & availableHeight: available size to be used for sizing
2676
- // the node or YGUndefined if the size is not available; interpretation
2677
- // depends on layout flags
2678
- // - ownerDirection: the inline (text) direction within the owner
2679
- // (left-to-right or right-to-left)
2680
- // - widthMeasureMode: indicates the sizing rules for the width (see below
2681
- // for explanation)
2682
- // - heightMeasureMode: indicates the sizing rules for the height (see below
2683
- // for explanation)
2684
- // - performLayout: specifies whether the caller is interested in just the
2685
- // dimensions of the node or it requires the entire node and its subtree to
2686
- // be laid out (with final positions)
2687
- //
2688
- // Details:
2689
- // This routine is called recursively to lay out subtrees of flexbox
2690
- // elements. It uses the information in node.style, which is treated as a
2691
- // read-only input. It is responsible for setting the layout.direction and
2692
- // layout.measuredDimensions fields for the input node as well as the
2693
- // layout.position and layout.lineIndex fields for its child nodes. The
2694
- // layout.measuredDimensions field includes any border or padding for the
2695
- // node but does not include margins.
2696
- //
2697
- // The spec describes four different layout modes: "fill available", "max
2698
- // content", "min content", and "fit content". Of these, we don't use "min
2699
- // content" because we don't support default minimum main sizes (see above
2700
- // for details). Each of our measure modes maps to a layout mode from the
2701
- // spec (https://www.w3.org/TR/CSS3-sizing/#terms):
2702
- // - YGMeasureModeUndefined: max content
2703
- // - YGMeasureModeExactly: fill available
2704
- // - YGMeasureModeAtMost: fit content
2705
- //
2706
- // When calling YGNodelayoutImpl and YGLayoutNodeInternal, if the caller
2707
- // passes an available size of undefined then it must also pass a measure
2708
- // mode of YGMeasureModeUndefined in that dimension.
2709
- //
2710
- static void YGNodelayoutImpl(
2711
- const YGNodeRef node,
2712
- const float availableWidth,
2713
- const float availableHeight,
2714
- const YGDirection ownerDirection,
2715
- const YGMeasureMode widthMeasureMode,
2716
- const YGMeasureMode heightMeasureMode,
2717
- const float ownerWidth,
2718
- const float ownerHeight,
2719
- const bool performLayout,
2720
- const YGConfigRef config,
2721
- LayoutData &layoutMarkerData,
2722
- void *const layoutContext,
2723
- const uint32_t depth,
2724
- const uint32_t generationCount,
2725
- const LayoutPassReason reason) {
2726
- YGAssertWithNode(
2727
- node,
2728
- YGFloatIsUndefined(availableWidth)
2729
- ? widthMeasureMode == YGMeasureModeUndefined
2730
- : true,
2731
- "availableWidth is indefinite so widthMeasureMode must be "
2732
- "YGMeasureModeUndefined");
2733
- YGAssertWithNode(
2734
- node,
2735
- YGFloatIsUndefined(availableHeight)
2736
- ? heightMeasureMode == YGMeasureModeUndefined
2737
- : true,
2738
- "availableHeight is indefinite so heightMeasureMode must be "
2739
- "YGMeasureModeUndefined");
2740
-
2741
- (performLayout ? layoutMarkerData.layouts : layoutMarkerData.measures) += 1;
2742
-
2743
- // Set the resolved resolution in the node's layout.
2744
- const YGDirection direction = node->resolveDirection(ownerDirection);
2745
- node->setLayoutDirection(direction);
2746
-
2747
- const YGFlexDirection flexRowDirection =
2748
- YGResolveFlexDirection(YGFlexDirectionRow, direction);
2749
- const YGFlexDirection flexColumnDirection =
2750
- YGResolveFlexDirection(YGFlexDirectionColumn, direction);
2751
-
2752
- const YGEdge startEdge =
2753
- direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight;
2754
- const YGEdge endEdge = direction == YGDirectionLTR ? YGEdgeRight : YGEdgeLeft;
2755
-
2756
- const float marginRowLeading =
2757
- node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap();
2758
- node->setLayoutMargin(marginRowLeading, startEdge);
2759
- const float marginRowTrailing =
2760
- node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap();
2761
- node->setLayoutMargin(marginRowTrailing, endEdge);
2762
- const float marginColumnLeading =
2763
- node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap();
2764
- node->setLayoutMargin(marginColumnLeading, YGEdgeTop);
2765
- const float marginColumnTrailing =
2766
- node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap();
2767
- node->setLayoutMargin(marginColumnTrailing, YGEdgeBottom);
2768
-
2769
- const float marginAxisRow = marginRowLeading + marginRowTrailing;
2770
- const float marginAxisColumn = marginColumnLeading + marginColumnTrailing;
2771
-
2772
- node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), startEdge);
2773
- node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), endEdge);
2774
- node->setLayoutBorder(node->getLeadingBorder(flexColumnDirection), YGEdgeTop);
2775
- node->setLayoutBorder(
2776
- node->getTrailingBorder(flexColumnDirection), YGEdgeBottom);
2777
-
2778
- node->setLayoutPadding(
2779
- node->getLeadingPadding(flexRowDirection, ownerWidth).unwrap(),
2780
- startEdge);
2781
- node->setLayoutPadding(
2782
- node->getTrailingPadding(flexRowDirection, ownerWidth).unwrap(), endEdge);
2783
- node->setLayoutPadding(
2784
- node->getLeadingPadding(flexColumnDirection, ownerWidth).unwrap(),
2785
- YGEdgeTop);
2786
- node->setLayoutPadding(
2787
- node->getTrailingPadding(flexColumnDirection, ownerWidth).unwrap(),
2788
- YGEdgeBottom);
2789
-
2790
- if (node->hasMeasureFunc()) {
2791
- YGNodeWithMeasureFuncSetMeasuredDimensions(
2792
- node,
2793
- availableWidth - marginAxisRow,
2794
- availableHeight - marginAxisColumn,
2795
- widthMeasureMode,
2796
- heightMeasureMode,
2797
- ownerWidth,
2798
- ownerHeight,
2799
- layoutMarkerData,
2800
- layoutContext,
2801
- reason);
2802
- return;
2803
- }
2804
-
2805
- const uint32_t childCount = YGNodeGetChildCount(node);
2806
- if (childCount == 0) {
2807
- YGNodeEmptyContainerSetMeasuredDimensions(
2808
- node,
2809
- availableWidth - marginAxisRow,
2810
- availableHeight - marginAxisColumn,
2811
- widthMeasureMode,
2812
- heightMeasureMode,
2813
- ownerWidth,
2814
- ownerHeight);
2815
- return;
2816
- }
2817
-
2818
- // If we're not being asked to perform a full layout we can skip the algorithm
2819
- // if we already know the size
2820
- if (!performLayout &&
2821
- YGNodeFixedSizeSetMeasuredDimensions(
2822
- node,
2823
- availableWidth - marginAxisRow,
2824
- availableHeight - marginAxisColumn,
2825
- widthMeasureMode,
2826
- heightMeasureMode,
2827
- ownerWidth,
2828
- ownerHeight)) {
2829
- return;
2830
- }
2831
-
2832
- // At this point we know we're going to perform work. Ensure that each child
2833
- // has a mutable copy.
2834
- node->cloneChildrenIfNeeded(layoutContext);
2835
- // Reset layout flags, as they could have changed.
2836
- node->setLayoutHadOverflow(false);
2837
-
2838
- // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
2839
- const YGFlexDirection mainAxis =
2840
- YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
2841
- const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
2842
- const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
2843
- const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
2844
-
2845
- const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
2846
- const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth;
2847
-
2848
- const float paddingAndBorderAxisMain =
2849
- YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth);
2850
- const float leadingPaddingAndBorderCross =
2851
- node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap();
2852
- const float trailingPaddingAndBorderCross =
2853
- node->getTrailingPaddingAndBorder(crossAxis, ownerWidth).unwrap();
2854
- const float paddingAndBorderAxisCross =
2855
- leadingPaddingAndBorderCross + trailingPaddingAndBorderCross;
2856
-
2857
- YGMeasureMode measureModeMainDim =
2858
- isMainAxisRow ? widthMeasureMode : heightMeasureMode;
2859
- YGMeasureMode measureModeCrossDim =
2860
- isMainAxisRow ? heightMeasureMode : widthMeasureMode;
2861
-
2862
- const float paddingAndBorderAxisRow =
2863
- isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross;
2864
- const float paddingAndBorderAxisColumn =
2865
- isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain;
2866
-
2867
- // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
2868
-
2869
- float availableInnerWidth = YGNodeCalculateAvailableInnerDim(
2870
- node,
2871
- YGDimensionWidth,
2872
- availableWidth - marginAxisRow,
2873
- paddingAndBorderAxisRow,
2874
- ownerWidth);
2875
- float availableInnerHeight = YGNodeCalculateAvailableInnerDim(
2876
- node,
2877
- YGDimensionHeight,
2878
- availableHeight - marginAxisColumn,
2879
- paddingAndBorderAxisColumn,
2880
- ownerHeight);
2881
-
2882
- float availableInnerMainDim =
2883
- isMainAxisRow ? availableInnerWidth : availableInnerHeight;
2884
- const float availableInnerCrossDim =
2885
- isMainAxisRow ? availableInnerHeight : availableInnerWidth;
2886
-
2887
- // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
2888
-
2889
- // Computed basis + margins + gap
2890
- float totalMainDim = 0;
2891
- totalMainDim += YGNodeComputeFlexBasisForChildren(
2892
- node,
2893
- availableInnerWidth,
2894
- availableInnerHeight,
2895
- widthMeasureMode,
2896
- heightMeasureMode,
2897
- direction,
2898
- mainAxis,
2899
- config,
2900
- performLayout,
2901
- layoutMarkerData,
2902
- layoutContext,
2903
- depth,
2904
- generationCount);
2905
-
2906
- if (childCount > 1) {
2907
- totalMainDim +=
2908
- node->getGapForAxis(mainAxis, availableInnerCrossDim).unwrap() *
2909
- (childCount - 1);
2910
- }
2911
-
2912
- const bool mainAxisOverflows =
2913
- (measureModeMainDim != YGMeasureModeUndefined) &&
2914
- totalMainDim > availableInnerMainDim;
2915
-
2916
- if (isNodeFlexWrap && mainAxisOverflows &&
2917
- measureModeMainDim == YGMeasureModeAtMost) {
2918
- measureModeMainDim = YGMeasureModeExactly;
2919
- }
2920
- // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES
2921
-
2922
- // Indexes of children that represent the first and last items in the line.
2923
- uint32_t startOfLineIndex = 0;
2924
- uint32_t endOfLineIndex = 0;
2925
-
2926
- // Number of lines.
2927
- uint32_t lineCount = 0;
2928
-
2929
- // Accumulated cross dimensions of all lines so far.
2930
- float totalLineCrossDim = 0;
2931
-
2932
- const float crossAxisGap =
2933
- node->getGapForAxis(crossAxis, availableInnerCrossDim).unwrap();
2934
-
2935
- // Max main dimension of all the lines.
2936
- float maxLineMainDim = 0;
2937
- YGCollectFlexItemsRowValues collectedFlexItemsValues;
2938
- for (; endOfLineIndex < childCount;
2939
- lineCount++, startOfLineIndex = endOfLineIndex) {
2940
- collectedFlexItemsValues = YGCalculateCollectFlexItemsRowValues(
2941
- node,
2942
- ownerDirection,
2943
- mainAxisownerSize,
2944
- availableInnerWidth,
2945
- availableInnerMainDim,
2946
- startOfLineIndex,
2947
- lineCount);
2948
- endOfLineIndex = collectedFlexItemsValues.endOfLineIndex;
2949
-
2950
- // If we don't need to measure the cross axis, we can skip the entire flex
2951
- // step.
2952
- const bool canSkipFlex =
2953
- !performLayout && measureModeCrossDim == YGMeasureModeExactly;
2954
-
2955
- // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS
2956
- // Calculate the remaining available space that needs to be allocated. If
2957
- // the main dimension size isn't known, it is computed based on the line
2958
- // length, so there's no more space left to distribute.
2959
-
2960
- bool sizeBasedOnContent = false;
2961
- // If we don't measure with exact main dimension we want to ensure we don't
2962
- // violate min and max
2963
- if (measureModeMainDim != YGMeasureModeExactly) {
2964
- const auto& minDimensions = node->getStyle().minDimensions();
2965
- const auto& maxDimensions = node->getStyle().maxDimensions();
2966
- const float minInnerWidth =
2967
- YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() -
2968
- paddingAndBorderAxisRow;
2969
- const float maxInnerWidth =
2970
- YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() -
2971
- paddingAndBorderAxisRow;
2972
- const float minInnerHeight =
2973
- YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight)
2974
- .unwrap() -
2975
- paddingAndBorderAxisColumn;
2976
- const float maxInnerHeight =
2977
- YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight)
2978
- .unwrap() -
2979
- paddingAndBorderAxisColumn;
2980
-
2981
- const float minInnerMainDim =
2982
- isMainAxisRow ? minInnerWidth : minInnerHeight;
2983
- const float maxInnerMainDim =
2984
- isMainAxisRow ? maxInnerWidth : maxInnerHeight;
2985
-
2986
- if (!YGFloatIsUndefined(minInnerMainDim) &&
2987
- collectedFlexItemsValues.sizeConsumedOnCurrentLine <
2988
- minInnerMainDim) {
2989
- availableInnerMainDim = minInnerMainDim;
2990
- } else if (
2991
- !YGFloatIsUndefined(maxInnerMainDim) &&
2992
- collectedFlexItemsValues.sizeConsumedOnCurrentLine >
2993
- maxInnerMainDim) {
2994
- availableInnerMainDim = maxInnerMainDim;
2995
- } else {
2996
- if (!node->getConfig()->useLegacyStretchBehaviour &&
2997
- ((!YGFloatIsUndefined(
2998
- collectedFlexItemsValues.totalFlexGrowFactors) &&
2999
- collectedFlexItemsValues.totalFlexGrowFactors == 0) ||
3000
- (!YGFloatIsUndefined(node->resolveFlexGrow()) &&
3001
- node->resolveFlexGrow() == 0))) {
3002
- // If we don't have any children to flex or we can't flex the node
3003
- // itself, space we've used is all space we need. Root node also
3004
- // should be shrunk to minimum
3005
- availableInnerMainDim =
3006
- collectedFlexItemsValues.sizeConsumedOnCurrentLine;
3007
- }
3008
-
3009
- sizeBasedOnContent = !node->getConfig()->useLegacyStretchBehaviour;
3010
- }
3011
- }
3012
-
3013
- if (!sizeBasedOnContent && !YGFloatIsUndefined(availableInnerMainDim)) {
3014
- collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim -
3015
- collectedFlexItemsValues.sizeConsumedOnCurrentLine;
3016
- } else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) {
3017
- // availableInnerMainDim is indefinite which means the node is being sized
3018
- // based on its content. sizeConsumedOnCurrentLine is negative which means
3019
- // the node will allocate 0 points for its content. Consequently,
3020
- // remainingFreeSpace is 0 - sizeConsumedOnCurrentLine.
3021
- collectedFlexItemsValues.remainingFreeSpace =
3022
- -collectedFlexItemsValues.sizeConsumedOnCurrentLine;
3023
- }
3024
-
3025
- if (!canSkipFlex) {
3026
- YGResolveFlexibleLength(
3027
- node,
3028
- collectedFlexItemsValues,
3029
- mainAxis,
3030
- crossAxis,
3031
- mainAxisownerSize,
3032
- availableInnerMainDim,
3033
- availableInnerCrossDim,
3034
- availableInnerWidth,
3035
- availableInnerHeight,
3036
- mainAxisOverflows,
3037
- measureModeCrossDim,
3038
- performLayout,
3039
- config,
3040
- layoutMarkerData,
3041
- layoutContext,
3042
- depth,
3043
- generationCount);
3044
- }
3045
-
3046
- node->setLayoutHadOverflow(
3047
- node->getLayout().hadOverflow() |
3048
- (collectedFlexItemsValues.remainingFreeSpace < 0));
3049
-
3050
- // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION
3051
-
3052
- // At this point, all the children have their dimensions set in the main
3053
- // axis. Their dimensions are also set in the cross axis with the exception
3054
- // of items that are aligned "stretch". We need to compute these stretch
3055
- // values and set the final positions.
3056
-
3057
- YGJustifyMainAxis(
3058
- node,
3059
- collectedFlexItemsValues,
3060
- startOfLineIndex,
3061
- mainAxis,
3062
- crossAxis,
3063
- measureModeMainDim,
3064
- measureModeCrossDim,
3065
- mainAxisownerSize,
3066
- ownerWidth,
3067
- availableInnerMainDim,
3068
- availableInnerCrossDim,
3069
- availableInnerWidth,
3070
- performLayout,
3071
- layoutContext);
3072
-
3073
- float containerCrossAxis = availableInnerCrossDim;
3074
- if (measureModeCrossDim == YGMeasureModeUndefined ||
3075
- measureModeCrossDim == YGMeasureModeAtMost) {
3076
- // Compute the cross axis from the max cross dimension of the children.
3077
- containerCrossAxis =
3078
- YGNodeBoundAxis(
3079
- node,
3080
- crossAxis,
3081
- collectedFlexItemsValues.crossDim + paddingAndBorderAxisCross,
3082
- crossAxisownerSize,
3083
- ownerWidth) -
3084
- paddingAndBorderAxisCross;
3085
- }
3086
-
3087
- // If there's no flex wrap, the cross dimension is defined by the container.
3088
- if (!isNodeFlexWrap && measureModeCrossDim == YGMeasureModeExactly) {
3089
- collectedFlexItemsValues.crossDim = availableInnerCrossDim;
3090
- }
3091
-
3092
- // Clamp to the min/max size specified on the container.
3093
- collectedFlexItemsValues.crossDim =
3094
- YGNodeBoundAxis(
3095
- node,
3096
- crossAxis,
3097
- collectedFlexItemsValues.crossDim + paddingAndBorderAxisCross,
3098
- crossAxisownerSize,
3099
- ownerWidth) -
3100
- paddingAndBorderAxisCross;
3101
-
3102
- // STEP 7: CROSS-AXIS ALIGNMENT
3103
- // We can skip child alignment if we're just measuring the container.
3104
- if (performLayout) {
3105
- for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) {
3106
- const YGNodeRef child = node->getChild(i);
3107
- if (child->getStyle().display() == YGDisplayNone) {
3108
- continue;
3109
- }
3110
- if (child->getStyle().positionType() == YGPositionTypeAbsolute) {
3111
- // If the child is absolutely positioned and has a
3112
- // top/left/bottom/right set, override all the previously computed
3113
- // positions to set it correctly.
3114
- const bool isChildLeadingPosDefined =
3115
- child->isLeadingPositionDefined(crossAxis);
3116
- if (isChildLeadingPosDefined) {
3117
- child->setLayoutPosition(
3118
- child->getLeadingPosition(crossAxis, availableInnerCrossDim)
3119
- .unwrap() +
3120
- node->getLeadingBorder(crossAxis) +
3121
- child->getLeadingMargin(crossAxis, availableInnerWidth)
3122
- .unwrap(),
3123
- pos[crossAxis]);
3124
- }
3125
- // If leading position is not defined or calculations result in Nan,
3126
- // default to border + margin
3127
- if (!isChildLeadingPosDefined ||
3128
- YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) {
3129
- child->setLayoutPosition(
3130
- node->getLeadingBorder(crossAxis) +
3131
- child->getLeadingMargin(crossAxis, availableInnerWidth)
3132
- .unwrap(),
3133
- pos[crossAxis]);
3134
- }
3135
- } else {
3136
- float leadingCrossDim = leadingPaddingAndBorderCross;
3137
-
3138
- // For a relative children, we're either using alignItems (owner) or
3139
- // alignSelf (child) in order to determine the position in the cross
3140
- // axis
3141
- const YGAlign alignItem = YGNodeAlignItem(node, child);
3142
-
3143
- // If the child uses align stretch, we need to lay it out one more
3144
- // time, this time forcing the cross-axis size to be the computed
3145
- // cross size for the current line.
3146
- if (alignItem == YGAlignStretch &&
3147
- child->marginLeadingValue(crossAxis).unit != YGUnitAuto &&
3148
- child->marginTrailingValue(crossAxis).unit != YGUnitAuto) {
3149
- // If the child defines a definite size for its cross axis, there's
3150
- // no need to stretch.
3151
- if (!YGNodeIsStyleDimDefined(
3152
- child, crossAxis, availableInnerCrossDim)) {
3153
- float childMainSize =
3154
- child->getLayout().measuredDimensions[dim[mainAxis]];
3155
- const auto &childStyle = child->getStyle();
3156
- float childCrossSize = !childStyle.aspectRatio().isUndefined()
3157
- ? child->getMarginForAxis(crossAxis, availableInnerWidth)
3158
- .unwrap() +
3159
- (isMainAxisRow
3160
- ? childMainSize / childStyle.aspectRatio().unwrap()
3161
- : childMainSize * childStyle.aspectRatio().unwrap())
3162
- : collectedFlexItemsValues.crossDim;
3163
-
3164
- childMainSize +=
3165
- child->getMarginForAxis(mainAxis, availableInnerWidth)
3166
- .unwrap();
3167
-
3168
- YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
3169
- YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly;
3170
- YGConstrainMaxSizeForMode(
3171
- child,
3172
- mainAxis,
3173
- availableInnerMainDim,
3174
- availableInnerWidth,
3175
- &childMainMeasureMode,
3176
- &childMainSize);
3177
- YGConstrainMaxSizeForMode(
3178
- child,
3179
- crossAxis,
3180
- availableInnerCrossDim,
3181
- availableInnerWidth,
3182
- &childCrossMeasureMode,
3183
- &childCrossSize);
3184
-
3185
- const float childWidth =
3186
- isMainAxisRow ? childMainSize : childCrossSize;
3187
- const float childHeight =
3188
- !isMainAxisRow ? childMainSize : childCrossSize;
3189
-
3190
- auto alignContent = node->getStyle().alignContent();
3191
- auto crossAxisDoesNotGrow =
3192
- alignContent != YGAlignStretch && isNodeFlexWrap;
3193
- const YGMeasureMode childWidthMeasureMode =
3194
- YGFloatIsUndefined(childWidth) ||
3195
- (!isMainAxisRow && crossAxisDoesNotGrow)
3196
- ? YGMeasureModeUndefined
3197
- : YGMeasureModeExactly;
3198
- const YGMeasureMode childHeightMeasureMode =
3199
- YGFloatIsUndefined(childHeight) ||
3200
- (isMainAxisRow && crossAxisDoesNotGrow)
3201
- ? YGMeasureModeUndefined
3202
- : YGMeasureModeExactly;
3203
-
3204
- YGLayoutNodeInternal(
3205
- child,
3206
- childWidth,
3207
- childHeight,
3208
- direction,
3209
- childWidthMeasureMode,
3210
- childHeightMeasureMode,
3211
- availableInnerWidth,
3212
- availableInnerHeight,
3213
- true,
3214
- LayoutPassReason::kStretch,
3215
- config,
3216
- layoutMarkerData,
3217
- layoutContext,
3218
- depth,
3219
- generationCount);
3220
- }
3221
- } else {
3222
- const float remainingCrossDim = containerCrossAxis -
3223
- YGNodeDimWithMargin(child, crossAxis, availableInnerWidth);
3224
-
3225
- if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto &&
3226
- child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
3227
- leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim / 2);
3228
- } else if (
3229
- child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
3230
- // No-Op
3231
- } else if (
3232
- child->marginLeadingValue(crossAxis).unit == YGUnitAuto) {
3233
- leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim);
3234
- } else if (alignItem == YGAlignFlexStart) {
3235
- // No-Op
3236
- } else if (alignItem == YGAlignCenter) {
3237
- leadingCrossDim += remainingCrossDim / 2;
3238
- } else {
3239
- leadingCrossDim += remainingCrossDim;
3240
- }
3241
- }
3242
- // And we apply the position
3243
- child->setLayoutPosition(
3244
- child->getLayout().position[pos[crossAxis]] + totalLineCrossDim +
3245
- leadingCrossDim,
3246
- pos[crossAxis]);
3247
- }
3248
- }
3249
- }
3250
-
3251
- const float appliedCrossGap = lineCount != 0 ? crossAxisGap : 0.0f;
3252
- totalLineCrossDim += collectedFlexItemsValues.crossDim + appliedCrossGap;
3253
- maxLineMainDim =
3254
- YGFloatMax(maxLineMainDim, collectedFlexItemsValues.mainDim);
3255
- }
3256
-
3257
- // STEP 8: MULTI-LINE CONTENT ALIGNMENT
3258
- // currentLead stores the size of the cross dim
3259
- if (performLayout && (isNodeFlexWrap || YGIsBaselineLayout(node))) {
3260
- float crossDimLead = 0;
3261
- float currentLead = leadingPaddingAndBorderCross;
3262
- if (!YGFloatIsUndefined(availableInnerCrossDim)) {
3263
- const float remainingAlignContentDim =
3264
- availableInnerCrossDim - totalLineCrossDim;
3265
- switch (node->getStyle().alignContent()) {
3266
- case YGAlignFlexEnd:
3267
- currentLead += remainingAlignContentDim;
3268
- break;
3269
- case YGAlignCenter:
3270
- currentLead += remainingAlignContentDim / 2;
3271
- break;
3272
- case YGAlignStretch:
3273
- if (availableInnerCrossDim > totalLineCrossDim) {
3274
- crossDimLead = remainingAlignContentDim / lineCount;
3275
- }
3276
- break;
3277
- case YGAlignSpaceAround:
3278
- if (availableInnerCrossDim > totalLineCrossDim) {
3279
- currentLead += remainingAlignContentDim / (2 * lineCount);
3280
- if (lineCount > 1) {
3281
- crossDimLead = remainingAlignContentDim / lineCount;
3282
- }
3283
- } else {
3284
- currentLead += remainingAlignContentDim / 2;
3285
- }
3286
- break;
3287
- case YGAlignSpaceBetween:
3288
- if (availableInnerCrossDim > totalLineCrossDim && lineCount > 1) {
3289
- crossDimLead = remainingAlignContentDim / (lineCount - 1);
3290
- }
3291
- break;
3292
- case YGAlignAuto:
3293
- case YGAlignFlexStart:
3294
- case YGAlignBaseline:
3295
- break;
3296
- }
3297
- }
3298
- uint32_t endIndex = 0;
3299
- for (uint32_t i = 0; i < lineCount; i++) {
3300
- const uint32_t startIndex = endIndex;
3301
- uint32_t ii;
3302
-
3303
- // compute the line's height and find the endIndex
3304
- float lineHeight = 0;
3305
- float maxAscentForCurrentLine = 0;
3306
- float maxDescentForCurrentLine = 0;
3307
- for (ii = startIndex; ii < childCount; ii++) {
3308
- const YGNodeRef child = node->getChild(ii);
3309
- if (child->getStyle().display() == YGDisplayNone) {
3310
- continue;
3311
- }
3312
- if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
3313
- if (child->getLineIndex() != i) {
3314
- break;
3315
- }
3316
- if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
3317
- lineHeight = YGFloatMax(
3318
- lineHeight,
3319
- child->getLayout().measuredDimensions[dim[crossAxis]] +
3320
- child->getMarginForAxis(crossAxis, availableInnerWidth)
3321
- .unwrap());
3322
- }
3323
- if (YGNodeAlignItem(node, child) == YGAlignBaseline) {
3324
- const float ascent = YGBaseline(child, layoutContext) +
3325
- child
3326
- ->getLeadingMargin(
3327
- YGFlexDirectionColumn, availableInnerWidth)
3328
- .unwrap();
3329
- const float descent =
3330
- child->getLayout().measuredDimensions[YGDimensionHeight] +
3331
- child
3332
- ->getMarginForAxis(
3333
- YGFlexDirectionColumn, availableInnerWidth)
3334
- .unwrap() -
3335
- ascent;
3336
- maxAscentForCurrentLine =
3337
- YGFloatMax(maxAscentForCurrentLine, ascent);
3338
- maxDescentForCurrentLine =
3339
- YGFloatMax(maxDescentForCurrentLine, descent);
3340
- lineHeight = YGFloatMax(
3341
- lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine);
3342
- }
3343
- }
3344
- }
3345
- endIndex = ii;
3346
- lineHeight += crossDimLead;
3347
- currentLead += i != 0 ? crossAxisGap : 0;
3348
-
3349
- if (performLayout) {
3350
- for (ii = startIndex; ii < endIndex; ii++) {
3351
- const YGNodeRef child = node->getChild(ii);
3352
- if (child->getStyle().display() == YGDisplayNone) {
3353
- continue;
3354
- }
3355
- if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
3356
- switch (YGNodeAlignItem(node, child)) {
3357
- case YGAlignFlexStart: {
3358
- child->setLayoutPosition(
3359
- currentLead +
3360
- child->getLeadingMargin(crossAxis, availableInnerWidth)
3361
- .unwrap(),
3362
- pos[crossAxis]);
3363
- break;
3364
- }
3365
- case YGAlignFlexEnd: {
3366
- child->setLayoutPosition(
3367
- currentLead + lineHeight -
3368
- child->getTrailingMargin(crossAxis, availableInnerWidth)
3369
- .unwrap() -
3370
- child->getLayout().measuredDimensions[dim[crossAxis]],
3371
- pos[crossAxis]);
3372
- break;
3373
- }
3374
- case YGAlignCenter: {
3375
- float childHeight =
3376
- child->getLayout().measuredDimensions[dim[crossAxis]];
3377
-
3378
- child->setLayoutPosition(
3379
- currentLead + (lineHeight - childHeight) / 2,
3380
- pos[crossAxis]);
3381
- break;
3382
- }
3383
- case YGAlignStretch: {
3384
- child->setLayoutPosition(
3385
- currentLead +
3386
- child->getLeadingMargin(crossAxis, availableInnerWidth)
3387
- .unwrap(),
3388
- pos[crossAxis]);
3389
-
3390
- // Remeasure child with the line height as it as been only
3391
- // measured with the owners height yet.
3392
- if (!YGNodeIsStyleDimDefined(
3393
- child, crossAxis, availableInnerCrossDim)) {
3394
- const float childWidth = isMainAxisRow
3395
- ? (child->getLayout()
3396
- .measuredDimensions[YGDimensionWidth] +
3397
- child->getMarginForAxis(mainAxis, availableInnerWidth)
3398
- .unwrap())
3399
- : lineHeight;
3400
-
3401
- const float childHeight = !isMainAxisRow
3402
- ? (child->getLayout()
3403
- .measuredDimensions[YGDimensionHeight] +
3404
- child->getMarginForAxis(crossAxis, availableInnerWidth)
3405
- .unwrap())
3406
- : lineHeight;
3407
-
3408
- if (!(YGFloatsEqual(
3409
- childWidth,
3410
- child->getLayout()
3411
- .measuredDimensions[YGDimensionWidth]) &&
3412
- YGFloatsEqual(
3413
- childHeight,
3414
- child->getLayout()
3415
- .measuredDimensions[YGDimensionHeight]))) {
3416
- YGLayoutNodeInternal(
3417
- child,
3418
- childWidth,
3419
- childHeight,
3420
- direction,
3421
- YGMeasureModeExactly,
3422
- YGMeasureModeExactly,
3423
- availableInnerWidth,
3424
- availableInnerHeight,
3425
- true,
3426
- LayoutPassReason::kMultilineStretch,
3427
- config,
3428
- layoutMarkerData,
3429
- layoutContext,
3430
- depth,
3431
- generationCount);
3432
- }
3433
- }
3434
- break;
3435
- }
3436
- case YGAlignBaseline: {
3437
- child->setLayoutPosition(
3438
- currentLead + maxAscentForCurrentLine -
3439
- YGBaseline(child, layoutContext) +
3440
- child
3441
- ->getLeadingPosition(
3442
- YGFlexDirectionColumn, availableInnerCrossDim)
3443
- .unwrap(),
3444
- YGEdgeTop);
3445
-
3446
- break;
3447
- }
3448
- case YGAlignAuto:
3449
- case YGAlignSpaceBetween:
3450
- case YGAlignSpaceAround:
3451
- break;
3452
- }
3453
- }
3454
- }
3455
- }
3456
- currentLead += lineHeight;
3457
- }
3458
- }
3459
-
3460
- // STEP 9: COMPUTING FINAL DIMENSIONS
3461
-
3462
- node->setLayoutMeasuredDimension(
3463
- YGNodeBoundAxis(
3464
- node,
3465
- YGFlexDirectionRow,
3466
- availableWidth - marginAxisRow,
3467
- ownerWidth,
3468
- ownerWidth),
3469
- YGDimensionWidth);
3470
-
3471
- node->setLayoutMeasuredDimension(
3472
- YGNodeBoundAxis(
3473
- node,
3474
- YGFlexDirectionColumn,
3475
- availableHeight - marginAxisColumn,
3476
- ownerHeight,
3477
- ownerWidth),
3478
- YGDimensionHeight);
3479
-
3480
- // If the user didn't specify a width or height for the node, set the
3481
- // dimensions based on the children.
3482
- if (measureModeMainDim == YGMeasureModeUndefined ||
3483
- (node->getStyle().overflow() != YGOverflowScroll &&
3484
- measureModeMainDim == YGMeasureModeAtMost)) {
3485
- // Clamp the size to the min/max size, if specified, and make sure it
3486
- // doesn't go below the padding and border amount.
3487
- node->setLayoutMeasuredDimension(
3488
- YGNodeBoundAxis(
3489
- node, mainAxis, maxLineMainDim, mainAxisownerSize, ownerWidth),
3490
- dim[mainAxis]);
3491
-
3492
- } else if (
3493
- measureModeMainDim == YGMeasureModeAtMost &&
3494
- node->getStyle().overflow() == YGOverflowScroll) {
3495
- node->setLayoutMeasuredDimension(
3496
- YGFloatMax(
3497
- YGFloatMin(
3498
- availableInnerMainDim + paddingAndBorderAxisMain,
3499
- YGNodeBoundAxisWithinMinAndMax(
3500
- node,
3501
- mainAxis,
3502
- YGFloatOptional{maxLineMainDim},
3503
- mainAxisownerSize)
3504
- .unwrap()),
3505
- paddingAndBorderAxisMain),
3506
- dim[mainAxis]);
3507
- }
3508
-
3509
- if (measureModeCrossDim == YGMeasureModeUndefined ||
3510
- (node->getStyle().overflow() != YGOverflowScroll &&
3511
- measureModeCrossDim == YGMeasureModeAtMost)) {
3512
- // Clamp the size to the min/max size, if specified, and make sure it
3513
- // doesn't go below the padding and border amount.
3514
- node->setLayoutMeasuredDimension(
3515
- YGNodeBoundAxis(
3516
- node,
3517
- crossAxis,
3518
- totalLineCrossDim + paddingAndBorderAxisCross,
3519
- crossAxisownerSize,
3520
- ownerWidth),
3521
- dim[crossAxis]);
3522
-
3523
- } else if (
3524
- measureModeCrossDim == YGMeasureModeAtMost &&
3525
- node->getStyle().overflow() == YGOverflowScroll) {
3526
- node->setLayoutMeasuredDimension(
3527
- YGFloatMax(
3528
- YGFloatMin(
3529
- availableInnerCrossDim + paddingAndBorderAxisCross,
3530
- YGNodeBoundAxisWithinMinAndMax(
3531
- node,
3532
- crossAxis,
3533
- YGFloatOptional{
3534
- totalLineCrossDim + paddingAndBorderAxisCross},
3535
- crossAxisownerSize)
3536
- .unwrap()),
3537
- paddingAndBorderAxisCross),
3538
- dim[crossAxis]);
3539
- }
3540
-
3541
- // As we only wrapped in normal direction yet, we need to reverse the
3542
- // positions on wrap-reverse.
3543
- if (performLayout && node->getStyle().flexWrap() == YGWrapWrapReverse) {
3544
- for (uint32_t i = 0; i < childCount; i++) {
3545
- const YGNodeRef child = YGNodeGetChild(node, i);
3546
- if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
3547
- child->setLayoutPosition(
3548
- node->getLayout().measuredDimensions[dim[crossAxis]] -
3549
- child->getLayout().position[pos[crossAxis]] -
3550
- child->getLayout().measuredDimensions[dim[crossAxis]],
3551
- pos[crossAxis]);
3552
- }
3553
- }
3554
- }
3555
-
3556
- if (performLayout) {
3557
- // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN
3558
- for (auto child : node->getChildren()) {
3559
- if (child->getStyle().display() == YGDisplayNone ||
3560
- child->getStyle().positionType() != YGPositionTypeAbsolute) {
3561
- continue;
3562
- }
3563
- YGNodeAbsoluteLayoutChild(
3564
- node,
3565
- child,
3566
- YGConfigIsExperimentalFeatureEnabled(
3567
- node->getConfig(),
3568
- YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge)
3569
- ? node->getLayout().measuredDimensions[YGDimensionWidth]
3570
- : availableInnerWidth,
3571
- isMainAxisRow ? measureModeMainDim : measureModeCrossDim,
3572
- YGConfigIsExperimentalFeatureEnabled(
3573
- node->getConfig(),
3574
- YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge)
3575
- ? node->getLayout().measuredDimensions[YGDimensionHeight]
3576
- : availableInnerHeight,
3577
- direction,
3578
- config,
3579
- layoutMarkerData,
3580
- layoutContext,
3581
- depth,
3582
- generationCount);
3583
- }
3584
-
3585
- // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
3586
- const bool needsMainTrailingPos = mainAxis == YGFlexDirectionRowReverse ||
3587
- mainAxis == YGFlexDirectionColumnReverse;
3588
- const bool needsCrossTrailingPos = crossAxis == YGFlexDirectionRowReverse ||
3589
- crossAxis == YGFlexDirectionColumnReverse;
3590
-
3591
- // Set trailing position if necessary.
3592
- if (needsMainTrailingPos || needsCrossTrailingPos) {
3593
- for (uint32_t i = 0; i < childCount; i++) {
3594
- const YGNodeRef child = node->getChild(i);
3595
- if (child->getStyle().display() == YGDisplayNone) {
3596
- continue;
3597
- }
3598
- if (needsMainTrailingPos) {
3599
- YGNodeSetChildTrailingPosition(node, child, mainAxis);
3600
- }
3601
-
3602
- if (needsCrossTrailingPos) {
3603
- YGNodeSetChildTrailingPosition(node, child, crossAxis);
3604
- }
3605
- }
3606
- }
3607
- }
814
+ YGDirection YGNodeLayoutGetDirection(const YGNodeConstRef node) {
815
+ return unscopedEnum(resolveRef(node)->getLayout().direction());
3608
816
  }
3609
817
 
3610
- bool gPrintChanges = false;
3611
- bool gPrintSkips = false;
3612
-
3613
- static const char *spacer =
3614
- " ";
3615
-
3616
- static const char *YGSpacer(const unsigned long level) {
3617
- const size_t spacerLen = strlen(spacer);
3618
- if (level > spacerLen) {
3619
- return &spacer[0];
3620
- } else {
3621
- return &spacer[spacerLen - level];
3622
- }
818
+ bool YGNodeLayoutGetHadOverflow(const YGNodeConstRef node) {
819
+ return resolveRef(node)->getLayout().hadOverflow();
3623
820
  }
3624
821
 
3625
- static const char *YGMeasureModeName(
3626
- const YGMeasureMode mode,
3627
- const bool performLayout) {
3628
- constexpr auto N = enums::count<YGMeasureMode>();
3629
- const char *kMeasureModeNames[N] = {"UNDEFINED", "EXACTLY", "AT_MOST"};
3630
- const char *kLayoutModeNames[N] = {
3631
- "LAY_UNDEFINED", "LAY_EXACTLY", "LAY_AT_MOST"};
3632
-
3633
- if (mode >= N) {
3634
- return "";
3635
- }
3636
-
3637
- return performLayout ? kLayoutModeNames[mode] : kMeasureModeNames[mode];
822
+ float YGNodeLayoutGetMargin(YGNodeConstRef node, YGEdge edge) {
823
+ return getResolvedLayoutProperty<&LayoutResults::margin>(node, edge);
3638
824
  }
3639
825
 
3640
- static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(
3641
- YGMeasureMode sizeMode,
3642
- float size,
3643
- float lastComputedSize) {
3644
- return sizeMode == YGMeasureModeExactly &&
3645
- YGFloatsEqual(size, lastComputedSize);
826
+ float YGNodeLayoutGetBorder(YGNodeConstRef node, YGEdge edge) {
827
+ return getResolvedLayoutProperty<&LayoutResults::border>(node, edge);
3646
828
  }
3647
829
 
3648
- static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits(
3649
- YGMeasureMode sizeMode,
3650
- float size,
3651
- YGMeasureMode lastSizeMode,
3652
- float lastComputedSize) {
3653
- return sizeMode == YGMeasureModeAtMost &&
3654
- lastSizeMode == YGMeasureModeUndefined &&
3655
- (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize));
830
+ float YGNodeLayoutGetPadding(YGNodeConstRef node, YGEdge edge) {
831
+ return getResolvedLayoutProperty<&LayoutResults::padding>(node, edge);
3656
832
  }
3657
833
 
3658
- static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
3659
- YGMeasureMode sizeMode,
3660
- float size,
3661
- YGMeasureMode lastSizeMode,
3662
- float lastSize,
3663
- float lastComputedSize) {
3664
- return lastSizeMode == YGMeasureModeAtMost &&
3665
- sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) &&
3666
- !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) &&
3667
- lastSize > size &&
3668
- (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize));
834
+ #ifdef DEBUG
835
+ void YGNodePrint(const YGNodeConstRef node, const YGPrintOptions options) {
836
+ yoga::print(resolveRef(node), scopedEnum(options));
3669
837
  }
838
+ #endif
3670
839
 
3671
- YOGA_EXPORT float YGRoundValueToPixelGrid(
3672
- const double value,
3673
- const double pointScaleFactor,
3674
- const bool forceCeil,
3675
- const bool forceFloor) {
3676
- double scaledValue = value * pointScaleFactor;
3677
- // We want to calculate `fractial` such that `floor(scaledValue) = scaledValue
3678
- // - fractial`.
3679
- double fractial = fmod(scaledValue, 1.0);
3680
- if (fractial < 0) {
3681
- // This branch is for handling negative numbers for `value`.
3682
- //
3683
- // Regarding `floor` and `ceil`. Note that for a number x, `floor(x) <= x <=
3684
- // ceil(x)` even for negative numbers. Here are a couple of examples:
3685
- // - x = 2.2: floor( 2.2) = 2, ceil( 2.2) = 3
3686
- // - x = -2.2: floor(-2.2) = -3, ceil(-2.2) = -2
3687
- //
3688
- // Regarding `fmodf`. For fractional negative numbers, `fmodf` returns a
3689
- // negative number. For example, `fmodf(-2.2) = -0.2`. However, we want
3690
- // `fractial` to be the number such that subtracting it from `value` will
3691
- // give us `floor(value)`. In the case of negative numbers, adding 1 to
3692
- // `fmodf(value)` gives us this. Let's continue the example from above:
3693
- // - fractial = fmodf(-2.2) = -0.2
3694
- // - Add 1 to the fraction: fractial2 = fractial + 1 = -0.2 + 1 = 0.8
3695
- // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3
3696
- ++fractial;
3697
- }
3698
- if (YGDoubleEqual(fractial, 0)) {
3699
- // First we check if the value is already rounded
3700
- scaledValue = scaledValue - fractial;
3701
- } else if (YGDoubleEqual(fractial, 1.0)) {
3702
- scaledValue = scaledValue - fractial + 1.0;
3703
- } else if (forceCeil) {
3704
- // Next we check if we need to use forced rounding
3705
- scaledValue = scaledValue - fractial + 1.0;
3706
- } else if (forceFloor) {
3707
- scaledValue = scaledValue - fractial;
3708
- } else {
3709
- // Finally we just round the value
3710
- scaledValue = scaledValue - fractial +
3711
- (!YGDoubleIsUndefined(fractial) &&
3712
- (fractial > 0.5 || YGDoubleEqual(fractial, 0.5))
3713
- ? 1.0
3714
- : 0.0);
3715
- }
3716
- return (YGDoubleIsUndefined(scaledValue) ||
3717
- YGDoubleIsUndefined(pointScaleFactor))
3718
- ? YGUndefined
3719
- : (float) (scaledValue / pointScaleFactor);
3720
- }
3721
-
3722
- YOGA_EXPORT bool YGNodeCanUseCachedMeasurement(
3723
- const YGMeasureMode widthMode,
3724
- const float width,
3725
- const YGMeasureMode heightMode,
3726
- const float height,
3727
- const YGMeasureMode lastWidthMode,
3728
- const float lastWidth,
3729
- const YGMeasureMode lastHeightMode,
3730
- const float lastHeight,
3731
- const float lastComputedWidth,
3732
- const float lastComputedHeight,
3733
- const float marginRow,
3734
- const float marginColumn,
3735
- const YGConfigRef config) {
3736
- if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) ||
3737
- (!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) {
3738
- return false;
3739
- }
3740
- bool useRoundedComparison =
3741
- config != nullptr && config->pointScaleFactor != 0;
3742
- const float effectiveWidth = useRoundedComparison
3743
- ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false)
3744
- : width;
3745
- const float effectiveHeight = useRoundedComparison
3746
- ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false)
3747
- : height;
3748
- const float effectiveLastWidth = useRoundedComparison
3749
- ? YGRoundValueToPixelGrid(
3750
- lastWidth, config->pointScaleFactor, false, false)
3751
- : lastWidth;
3752
- const float effectiveLastHeight = useRoundedComparison
3753
- ? YGRoundValueToPixelGrid(
3754
- lastHeight, config->pointScaleFactor, false, false)
3755
- : lastHeight;
3756
-
3757
- const bool hasSameWidthSpec = lastWidthMode == widthMode &&
3758
- YGFloatsEqual(effectiveLastWidth, effectiveWidth);
3759
- const bool hasSameHeightSpec = lastHeightMode == heightMode &&
3760
- YGFloatsEqual(effectiveLastHeight, effectiveHeight);
3761
-
3762
- const bool widthIsCompatible =
3763
- hasSameWidthSpec ||
3764
- YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(
3765
- widthMode, width - marginRow, lastComputedWidth) ||
3766
- YGMeasureModeOldSizeIsUnspecifiedAndStillFits(
3767
- widthMode, width - marginRow, lastWidthMode, lastComputedWidth) ||
3768
- YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
3769
- widthMode,
3770
- width - marginRow,
3771
- lastWidthMode,
3772
- lastWidth,
3773
- lastComputedWidth);
3774
-
3775
- const bool heightIsCompatible =
3776
- hasSameHeightSpec ||
3777
- YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(
3778
- heightMode, height - marginColumn, lastComputedHeight) ||
3779
- YGMeasureModeOldSizeIsUnspecifiedAndStillFits(
3780
- heightMode,
3781
- height - marginColumn,
3782
- lastHeightMode,
3783
- lastComputedHeight) ||
3784
- YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
3785
- heightMode,
3786
- height - marginColumn,
3787
- lastHeightMode,
3788
- lastHeight,
3789
- lastComputedHeight);
3790
-
3791
- return widthIsCompatible && heightIsCompatible;
3792
- }
3793
-
3794
- //
3795
- // This is a wrapper around the YGNodelayoutImpl function. It determines whether
3796
- // the layout request is redundant and can be skipped.
3797
- //
3798
- // Parameters:
3799
- // Input parameters are the same as YGNodelayoutImpl (see above)
3800
- // Return parameter is true if layout was performed, false if skipped
3801
- //
3802
- bool YGLayoutNodeInternal(
3803
- const YGNodeRef node,
3804
- const float availableWidth,
3805
- const float availableHeight,
3806
- const YGDirection ownerDirection,
3807
- const YGMeasureMode widthMeasureMode,
3808
- const YGMeasureMode heightMeasureMode,
3809
- const float ownerWidth,
3810
- const float ownerHeight,
3811
- const bool performLayout,
3812
- const LayoutPassReason reason,
3813
- const YGConfigRef config,
3814
- LayoutData &layoutMarkerData,
3815
- void *const layoutContext,
3816
- uint32_t depth,
3817
- const uint32_t generationCount) {
3818
- YGLayout *layout = &node->getLayout();
3819
-
3820
- depth++;
3821
-
3822
- const bool needToVisitNode =
3823
- (node->isDirty() && layout->generationCount != generationCount) ||
3824
- layout->lastOwnerDirection != ownerDirection;
3825
-
3826
- if (needToVisitNode) {
3827
- // Invalidate the cached results.
3828
- layout->nextCachedMeasurementsIndex = 0;
3829
- layout->cachedLayout.availableWidth = -1;
3830
- layout->cachedLayout.availableHeight = -1;
3831
- layout->cachedLayout.widthMeasureMode = YGMeasureModeUndefined;
3832
- layout->cachedLayout.heightMeasureMode = YGMeasureModeUndefined;
3833
- layout->cachedLayout.computedWidth = -1;
3834
- layout->cachedLayout.computedHeight = -1;
3835
- }
3836
-
3837
- YGCachedMeasurement *cachedResults = nullptr;
3838
-
3839
- // Determine whether the results are already cached. We maintain a separate
3840
- // cache for layouts and measurements. A layout operation modifies the
3841
- // positions and dimensions for nodes in the subtree. The algorithm assumes
3842
- // that each node gets laid out a maximum of one time per tree layout, but
3843
- // multiple measurements may be required to resolve all of the flex
3844
- // dimensions. We handle nodes with measure functions specially here because
3845
- // they are the most expensive to measure, so it's worth avoiding redundant
3846
- // measurements if at all possible.
3847
- if (node->hasMeasureFunc()) {
3848
- const float marginAxisRow =
3849
- node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap();
3850
- const float marginAxisColumn =
3851
- node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap();
3852
-
3853
- // First, try to use the layout cache.
3854
- if (YGNodeCanUseCachedMeasurement(
3855
- widthMeasureMode,
3856
- availableWidth,
3857
- heightMeasureMode,
3858
- availableHeight,
3859
- layout->cachedLayout.widthMeasureMode,
3860
- layout->cachedLayout.availableWidth,
3861
- layout->cachedLayout.heightMeasureMode,
3862
- layout->cachedLayout.availableHeight,
3863
- layout->cachedLayout.computedWidth,
3864
- layout->cachedLayout.computedHeight,
3865
- marginAxisRow,
3866
- marginAxisColumn,
3867
- config)) {
3868
- cachedResults = &layout->cachedLayout;
3869
- } else {
3870
- // Try to use the measurement cache.
3871
- for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) {
3872
- if (YGNodeCanUseCachedMeasurement(
3873
- widthMeasureMode,
3874
- availableWidth,
3875
- heightMeasureMode,
3876
- availableHeight,
3877
- layout->cachedMeasurements[i].widthMeasureMode,
3878
- layout->cachedMeasurements[i].availableWidth,
3879
- layout->cachedMeasurements[i].heightMeasureMode,
3880
- layout->cachedMeasurements[i].availableHeight,
3881
- layout->cachedMeasurements[i].computedWidth,
3882
- layout->cachedMeasurements[i].computedHeight,
3883
- marginAxisRow,
3884
- marginAxisColumn,
3885
- config)) {
3886
- cachedResults = &layout->cachedMeasurements[i];
3887
- break;
3888
- }
3889
- }
3890
- }
3891
- } else if (performLayout) {
3892
- if (YGFloatsEqual(layout->cachedLayout.availableWidth, availableWidth) &&
3893
- YGFloatsEqual(layout->cachedLayout.availableHeight, availableHeight) &&
3894
- layout->cachedLayout.widthMeasureMode == widthMeasureMode &&
3895
- layout->cachedLayout.heightMeasureMode == heightMeasureMode) {
3896
- cachedResults = &layout->cachedLayout;
3897
- }
3898
- } else {
3899
- for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) {
3900
- if (YGFloatsEqual(
3901
- layout->cachedMeasurements[i].availableWidth, availableWidth) &&
3902
- YGFloatsEqual(
3903
- layout->cachedMeasurements[i].availableHeight, availableHeight) &&
3904
- layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode &&
3905
- layout->cachedMeasurements[i].heightMeasureMode ==
3906
- heightMeasureMode) {
3907
- cachedResults = &layout->cachedMeasurements[i];
3908
- break;
3909
- }
3910
- }
3911
- }
3912
-
3913
- if (!needToVisitNode && cachedResults != nullptr) {
3914
- layout->measuredDimensions[YGDimensionWidth] = cachedResults->computedWidth;
3915
- layout->measuredDimensions[YGDimensionHeight] =
3916
- cachedResults->computedHeight;
3917
-
3918
- (performLayout ? layoutMarkerData.cachedLayouts
3919
- : layoutMarkerData.cachedMeasures) += 1;
3920
-
3921
- if (gPrintChanges && gPrintSkips) {
3922
- Log::log(
3923
- node,
3924
- YGLogLevelVerbose,
3925
- nullptr,
3926
- "%s%d.{[skipped] ",
3927
- YGSpacer(depth),
3928
- depth);
3929
- node->print(layoutContext);
3930
- Log::log(
3931
- node,
3932
- YGLogLevelVerbose,
3933
- nullptr,
3934
- "wm: %s, hm: %s, aw: %f ah: %f => d: (%f, %f) %s\n",
3935
- YGMeasureModeName(widthMeasureMode, performLayout),
3936
- YGMeasureModeName(heightMeasureMode, performLayout),
3937
- availableWidth,
3938
- availableHeight,
3939
- cachedResults->computedWidth,
3940
- cachedResults->computedHeight,
3941
- LayoutPassReasonToString(reason));
3942
- }
3943
- } else {
3944
- if (gPrintChanges) {
3945
- Log::log(
3946
- node,
3947
- YGLogLevelVerbose,
3948
- nullptr,
3949
- "%s%d.{%s",
3950
- YGSpacer(depth),
3951
- depth,
3952
- needToVisitNode ? "*" : "");
3953
- node->print(layoutContext);
3954
- Log::log(
3955
- node,
3956
- YGLogLevelVerbose,
3957
- nullptr,
3958
- "wm: %s, hm: %s, aw: %f ah: %f %s\n",
3959
- YGMeasureModeName(widthMeasureMode, performLayout),
3960
- YGMeasureModeName(heightMeasureMode, performLayout),
3961
- availableWidth,
3962
- availableHeight,
3963
- LayoutPassReasonToString(reason));
3964
- }
3965
-
3966
- YGNodelayoutImpl(
3967
- node,
3968
- availableWidth,
3969
- availableHeight,
3970
- ownerDirection,
3971
- widthMeasureMode,
3972
- heightMeasureMode,
3973
- ownerWidth,
3974
- ownerHeight,
3975
- performLayout,
3976
- config,
3977
- layoutMarkerData,
3978
- layoutContext,
3979
- depth,
3980
- generationCount,
3981
- reason);
3982
-
3983
- if (gPrintChanges) {
3984
- Log::log(
3985
- node,
3986
- YGLogLevelVerbose,
3987
- nullptr,
3988
- "%s%d.}%s",
3989
- YGSpacer(depth),
3990
- depth,
3991
- needToVisitNode ? "*" : "");
3992
- node->print(layoutContext);
3993
- Log::log(
3994
- node,
3995
- YGLogLevelVerbose,
3996
- nullptr,
3997
- "wm: %s, hm: %s, d: (%f, %f) %s\n",
3998
- YGMeasureModeName(widthMeasureMode, performLayout),
3999
- YGMeasureModeName(heightMeasureMode, performLayout),
4000
- layout->measuredDimensions[YGDimensionWidth],
4001
- layout->measuredDimensions[YGDimensionHeight],
4002
- LayoutPassReasonToString(reason));
4003
- }
4004
-
4005
- layout->lastOwnerDirection = ownerDirection;
4006
-
4007
- if (cachedResults == nullptr) {
4008
- if (layout->nextCachedMeasurementsIndex + 1 >
4009
- (uint32_t)layoutMarkerData.maxMeasureCache) {
4010
- layoutMarkerData.maxMeasureCache =
4011
- layout->nextCachedMeasurementsIndex + 1;
4012
- }
4013
- if (layout->nextCachedMeasurementsIndex == YG_MAX_CACHED_RESULT_COUNT) {
4014
- if (gPrintChanges) {
4015
- Log::log(node, YGLogLevelVerbose, nullptr, "Out of cache entries!\n");
4016
- }
4017
- layout->nextCachedMeasurementsIndex = 0;
4018
- }
4019
-
4020
- YGCachedMeasurement *newCacheEntry;
4021
- if (performLayout) {
4022
- // Use the single layout cache entry.
4023
- newCacheEntry = &layout->cachedLayout;
4024
- } else {
4025
- // Allocate a new measurement cache entry.
4026
- newCacheEntry =
4027
- &layout->cachedMeasurements[layout->nextCachedMeasurementsIndex];
4028
- layout->nextCachedMeasurementsIndex++;
4029
- }
4030
-
4031
- newCacheEntry->availableWidth = availableWidth;
4032
- newCacheEntry->availableHeight = availableHeight;
4033
- newCacheEntry->widthMeasureMode = widthMeasureMode;
4034
- newCacheEntry->heightMeasureMode = heightMeasureMode;
4035
- newCacheEntry->computedWidth =
4036
- layout->measuredDimensions[YGDimensionWidth];
4037
- newCacheEntry->computedHeight =
4038
- layout->measuredDimensions[YGDimensionHeight];
4039
- }
4040
- }
4041
-
4042
- if (performLayout) {
4043
- node->setLayoutDimension(
4044
- node->getLayout().measuredDimensions[YGDimensionWidth],
4045
- YGDimensionWidth);
4046
- node->setLayoutDimension(
4047
- node->getLayout().measuredDimensions[YGDimensionHeight],
4048
- YGDimensionHeight);
4049
-
4050
- node->setHasNewLayout(true);
4051
- node->setDirty(false);
4052
- }
4053
-
4054
- layout->generationCount = generationCount;
4055
-
4056
- LayoutType layoutType;
4057
- if (performLayout) {
4058
- layoutType = !needToVisitNode && cachedResults == &layout->cachedLayout
4059
- ? LayoutType::kCachedLayout
4060
- : LayoutType::kLayout;
840
+ void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) {
841
+ if (logger != nullptr) {
842
+ resolveRef(config)->setLogger(logger);
4061
843
  } else {
4062
- layoutType = cachedResults != nullptr ? LayoutType::kCachedMeasure
4063
- : LayoutType::kMeasure;
844
+ resolveRef(config)->setLogger(getDefaultLogger());
4064
845
  }
4065
- Event::publish<Event::NodeLayout>(node, {layoutType, layoutContext});
4066
-
4067
- return (needToVisitNode || cachedResults == nullptr);
4068
846
  }
4069
847
 
4070
- YOGA_EXPORT void YGConfigSetPointScaleFactor(
848
+ void YGConfigSetPointScaleFactor(
4071
849
  const YGConfigRef config,
4072
850
  const float pixelsInPoint) {
4073
- YGAssertWithConfig(
4074
- config,
851
+ yoga::assertFatalWithConfig(
852
+ resolveRef(config),
4075
853
  pixelsInPoint >= 0.0f,
4076
854
  "Scale factor should not be less than zero");
4077
855
 
4078
856
  // We store points for Pixel as we will use it for rounding
4079
857
  if (pixelsInPoint == 0.0f) {
4080
858
  // Zero is used to skip rounding
4081
- config->pointScaleFactor = 0.0f;
859
+ resolveRef(config)->setPointScaleFactor(0.0f);
4082
860
  } else {
4083
- config->pointScaleFactor = pixelsInPoint;
861
+ resolveRef(config)->setPointScaleFactor(pixelsInPoint);
4084
862
  }
4085
863
  }
4086
864
 
4087
- static void YGRoundToPixelGrid(
4088
- const YGNodeRef node,
4089
- const double pointScaleFactor,
4090
- const double absoluteLeft,
4091
- const double absoluteTop) {
4092
- if (pointScaleFactor == 0.0f) {
4093
- return;
4094
- }
4095
-
4096
- const double nodeLeft = node->getLayout().position[YGEdgeLeft];
4097
- const double nodeTop = node->getLayout().position[YGEdgeTop];
4098
-
4099
- const double nodeWidth = node->getLayout().dimensions[YGDimensionWidth];
4100
- const double nodeHeight = node->getLayout().dimensions[YGDimensionHeight];
4101
-
4102
- const double absoluteNodeLeft = absoluteLeft + nodeLeft;
4103
- const double absoluteNodeTop = absoluteTop + nodeTop;
4104
-
4105
- const double absoluteNodeRight = absoluteNodeLeft + nodeWidth;
4106
- const double absoluteNodeBottom = absoluteNodeTop + nodeHeight;
4107
-
4108
- // If a node has a custom measure function we never want to round down its
4109
- // size as this could lead to unwanted text truncation.
4110
- const bool textRounding = node->getNodeType() == YGNodeTypeText;
4111
-
4112
- node->setLayoutPosition(
4113
- YGRoundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding),
4114
- YGEdgeLeft);
4115
-
4116
- node->setLayoutPosition(
4117
- YGRoundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding),
4118
- YGEdgeTop);
4119
-
4120
- // We multiply dimension by scale factor and if the result is close to the
4121
- // whole number, we don't have any fraction To verify if the result is close
4122
- // to whole number we want to check both floor and ceil numbers
4123
- const bool hasFractionalWidth =
4124
- !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) &&
4125
- !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0);
4126
- const bool hasFractionalHeight =
4127
- !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) &&
4128
- !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0);
4129
-
4130
- node->setLayoutDimension(
4131
- YGRoundValueToPixelGrid(
4132
- absoluteNodeRight,
4133
- pointScaleFactor,
4134
- (textRounding && hasFractionalWidth),
4135
- (textRounding && !hasFractionalWidth)) -
4136
- YGRoundValueToPixelGrid(
4137
- absoluteNodeLeft, pointScaleFactor, false, textRounding),
4138
- YGDimensionWidth);
4139
-
4140
- node->setLayoutDimension(
4141
- YGRoundValueToPixelGrid(
4142
- absoluteNodeBottom,
4143
- pointScaleFactor,
4144
- (textRounding && hasFractionalHeight),
4145
- (textRounding && !hasFractionalHeight)) -
4146
- YGRoundValueToPixelGrid(
4147
- absoluteNodeTop, pointScaleFactor, false, textRounding),
4148
- YGDimensionHeight);
4149
-
4150
- const uint32_t childCount = YGNodeGetChildCount(node);
4151
- for (uint32_t i = 0; i < childCount; i++) {
4152
- YGRoundToPixelGrid(
4153
- YGNodeGetChild(node, i),
4154
- pointScaleFactor,
4155
- absoluteNodeLeft,
4156
- absoluteNodeTop);
4157
- }
4158
- }
4159
-
4160
- YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
4161
- const YGNodeRef node,
4162
- const float ownerWidth,
4163
- const float ownerHeight,
4164
- const YGDirection ownerDirection,
4165
- void *layoutContext) {
4166
- Event::publish<Event::LayoutPassStart>(node, {layoutContext});
4167
- LayoutData markerData = {};
4168
-
4169
- // Increment the generation count. This will force the recursive routine to
4170
- // visit all dirty nodes at least once. Subsequent visits will be skipped if
4171
- // the input parameters don't change.
4172
- gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed);
4173
- node->resolveDimension();
4174
- float width = YGUndefined;
4175
- YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
4176
- const auto &maxDimensions = node->getStyle().maxDimensions();
4177
- if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) {
4178
- width =
4179
- (YGResolveValue(
4180
- node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) +
4181
- node->getMarginForAxis(YGFlexDirectionRow, ownerWidth))
4182
- .unwrap();
4183
- widthMeasureMode = YGMeasureModeExactly;
4184
- } else if (!YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth)
4185
- .isUndefined()) {
4186
- width =
4187
- YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap();
4188
- widthMeasureMode = YGMeasureModeAtMost;
4189
- } else {
4190
- width = ownerWidth;
4191
- widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined
4192
- : YGMeasureModeExactly;
4193
- }
4194
-
4195
- float height = YGUndefined;
4196
- YGMeasureMode heightMeasureMode = YGMeasureModeUndefined;
4197
- if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) {
4198
- height = (YGResolveValue(
4199
- node->getResolvedDimension(dim[YGFlexDirectionColumn]),
4200
- ownerHeight) +
4201
- node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth))
4202
- .unwrap();
4203
- heightMeasureMode = YGMeasureModeExactly;
4204
- } else if (!YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight)
4205
- .isUndefined()) {
4206
- height =
4207
- YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap();
4208
- heightMeasureMode = YGMeasureModeAtMost;
4209
- } else {
4210
- height = ownerHeight;
4211
- heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined
4212
- : YGMeasureModeExactly;
4213
- }
4214
- if (YGLayoutNodeInternal(
4215
- node,
4216
- width,
4217
- height,
4218
- ownerDirection,
4219
- widthMeasureMode,
4220
- heightMeasureMode,
4221
- ownerWidth,
4222
- ownerHeight,
4223
- true,
4224
- LayoutPassReason::kInitial,
4225
- node->getConfig(),
4226
- markerData,
4227
- layoutContext,
4228
- 0, // tree root
4229
- gCurrentGenerationCount.load(std::memory_order_relaxed))) {
4230
- node->setPosition(
4231
- node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth);
4232
- YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f);
4233
-
4234
- #ifdef DEBUG
4235
- if (node->getConfig()->printTree) {
4236
- YGNodePrint(
4237
- node,
4238
- (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
4239
- }
4240
- #endif
4241
- }
4242
-
4243
- Event::publish<Event::LayoutPassEnd>(node, {layoutContext, &markerData});
4244
- }
4245
-
4246
- YOGA_EXPORT void YGNodeCalculateLayout(
4247
- const YGNodeRef node,
4248
- const float ownerWidth,
4249
- const float ownerHeight,
4250
- const YGDirection ownerDirection) {
4251
- YGNodeCalculateLayoutWithContext(
4252
- node, ownerWidth, ownerHeight, ownerDirection, nullptr);
4253
- }
4254
-
4255
- YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) {
4256
- if (logger != nullptr) {
4257
- config->setLogger(logger);
4258
- } else {
4259
- #ifdef ANDROID
4260
- config->setLogger(&YGAndroidLog);
4261
- #else
4262
- config->setLogger(&YGDefaultLog);
4263
- #endif
4264
- }
4265
- }
4266
-
4267
- void YGAssert(const bool condition, const char *message) {
4268
- if (!condition) {
4269
- Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message);
4270
- throwLogicalErrorWithMessage(message);
4271
- }
865
+ float YGConfigGetPointScaleFactor(const YGConfigConstRef config) {
866
+ return resolveRef(config)->getPointScaleFactor();
4272
867
  }
4273
868
 
4274
- void YGAssertWithNode(
4275
- const YGNodeRef node,
4276
- const bool condition,
4277
- const char *message) {
4278
- if (!condition) {
4279
- Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message);
4280
- throwLogicalErrorWithMessage(message);
4281
- }
4282
- }
4283
-
4284
- void YGAssertWithConfig(
4285
- const YGConfigRef config,
4286
- const bool condition,
4287
- const char *message) {
4288
- if (!condition) {
4289
- Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message);
4290
- throwLogicalErrorWithMessage(message);
4291
- }
869
+ float YGRoundValueToPixelGrid(
870
+ const double value,
871
+ const double pointScaleFactor,
872
+ const bool forceCeil,
873
+ const bool forceFloor) {
874
+ return yoga::roundValueToPixelGrid(
875
+ value, pointScaleFactor, forceCeil, forceFloor);
4292
876
  }
4293
877
 
4294
- YOGA_EXPORT void YGConfigSetExperimentalFeatureEnabled(
878
+ void YGConfigSetExperimentalFeatureEnabled(
4295
879
  const YGConfigRef config,
4296
880
  const YGExperimentalFeature feature,
4297
881
  const bool enabled) {
4298
- config->experimentalFeatures[feature] = enabled;
882
+ resolveRef(config)->setExperimentalFeatureEnabled(
883
+ scopedEnum(feature), enabled);
4299
884
  }
4300
885
 
4301
- YOGA_EXPORT bool YGConfigIsExperimentalFeatureEnabled(
4302
- const YGConfigRef config,
886
+ bool YGConfigIsExperimentalFeatureEnabled(
887
+ const YGConfigConstRef config,
4303
888
  const YGExperimentalFeature feature) {
4304
- return config->experimentalFeatures[feature];
889
+ return resolveRef(config)->isExperimentalFeatureEnabled(scopedEnum(feature));
4305
890
  }
4306
891
 
4307
- YOGA_EXPORT void YGConfigSetUseWebDefaults(
4308
- const YGConfigRef config,
4309
- const bool enabled) {
4310
- config->useWebDefaults = enabled;
892
+ void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled) {
893
+ resolveRef(config)->setUseWebDefaults(enabled);
4311
894
  }
4312
895
 
4313
- YOGA_EXPORT bool YGConfigGetUseLegacyStretchBehaviour(
4314
- const YGConfigRef config) {
4315
- return config->useLegacyStretchBehaviour;
896
+ bool YGConfigGetUseWebDefaults(const YGConfigConstRef config) {
897
+ return resolveRef(config)->useWebDefaults();
4316
898
  }
4317
899
 
4318
- YOGA_EXPORT void YGConfigSetUseLegacyStretchBehaviour(
4319
- const YGConfigRef config,
4320
- const bool useLegacyStretchBehaviour) {
4321
- config->useLegacyStretchBehaviour = useLegacyStretchBehaviour;
900
+ void YGConfigSetContext(const YGConfigRef config, void* context) {
901
+ resolveRef(config)->setContext(context);
4322
902
  }
4323
903
 
4324
- bool YGConfigGetUseWebDefaults(const YGConfigRef config) {
4325
- return config->useWebDefaults;
904
+ void* YGConfigGetContext(const YGConfigConstRef config) {
905
+ return resolveRef(config)->getContext();
4326
906
  }
4327
907
 
4328
- YOGA_EXPORT void YGConfigSetContext(const YGConfigRef config, void* context) {
4329
- config->context = context;
908
+ void YGConfigSetErrata(YGConfigRef config, YGErrata errata) {
909
+ resolveRef(config)->setErrata(scopedEnum(errata));
4330
910
  }
4331
911
 
4332
- YOGA_EXPORT void* YGConfigGetContext(const YGConfigRef config) {
4333
- return config->context;
912
+ YGErrata YGConfigGetErrata(YGConfigConstRef config) {
913
+ return unscopedEnum(resolveRef(config)->getErrata());
4334
914
  }
4335
915
 
4336
- YOGA_EXPORT void YGConfigSetCloneNodeFunc(
916
+ void YGConfigSetCloneNodeFunc(
4337
917
  const YGConfigRef config,
4338
918
  const YGCloneNodeFunc callback) {
4339
- config->setCloneNodeCallback(callback);
919
+ resolveRef(config)->setCloneNodeCallback(callback);
4340
920
  }
4341
921
 
4342
- static void YGTraverseChildrenPreOrder(
4343
- const YGVector &children,
4344
- const std::function<void(YGNodeRef node)> &f) {
4345
- for (YGNodeRef node : children) {
4346
- f(node);
4347
- YGTraverseChildrenPreOrder(node->getChildren(), f);
4348
- }
4349
- }
4350
-
4351
- void YGTraversePreOrder(
4352
- YGNodeRef const node,
4353
- std::function<void(YGNodeRef node)> &&f) {
4354
- if (!node) {
4355
- return;
4356
- }
4357
- f(node);
4358
- YGTraverseChildrenPreOrder(node->getChildren(), f);
922
+ // TODO: This should not be part of the public API. Remove after removing
923
+ // ComponentKit usage of it.
924
+ bool YGNodeCanUseCachedMeasurement(
925
+ YGMeasureMode widthMode,
926
+ float availableWidth,
927
+ YGMeasureMode heightMode,
928
+ float availableHeight,
929
+ YGMeasureMode lastWidthMode,
930
+ float lastAvailableWidth,
931
+ YGMeasureMode lastHeightMode,
932
+ float lastAvailableHeight,
933
+ float lastComputedWidth,
934
+ float lastComputedHeight,
935
+ float marginRow,
936
+ float marginColumn,
937
+ YGConfigRef config) {
938
+ return yoga::canUseCachedMeasurement(
939
+ scopedEnum(widthMode),
940
+ availableWidth,
941
+ scopedEnum(heightMode),
942
+ availableHeight,
943
+ scopedEnum(lastWidthMode),
944
+ lastAvailableWidth,
945
+ scopedEnum(lastHeightMode),
946
+ lastAvailableHeight,
947
+ lastComputedWidth,
948
+ lastComputedHeight,
949
+ marginRow,
950
+ marginColumn,
951
+ resolveRef(config));
952
+ }
953
+
954
+ void YGNodeCalculateLayout(
955
+ const YGNodeRef node,
956
+ const float ownerWidth,
957
+ const float ownerHeight,
958
+ const YGDirection ownerDirection) {
959
+ yoga::calculateLayout(
960
+ resolveRef(node), ownerWidth, ownerHeight, scopedEnum(ownerDirection));
4359
961
  }