react-native-windows 0.81.13 → 0.81.18

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 (49) hide show
  1. package/Common/Common.vcxproj +1 -1
  2. package/Folly/Folly.vcxproj +1 -1
  3. package/Libraries/Modal/Modal.windows.js +1 -7
  4. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +73 -97
  5. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +4 -1
  6. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +58 -21
  7. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +253 -58
  8. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +18 -4
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +149 -27
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +10 -0
  11. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +5 -0
  12. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +2 -0
  13. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +3 -1
  14. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +4 -6
  15. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +101 -44
  16. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -2
  17. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +3 -3
  18. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.h +3 -1
  19. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +0 -1
  20. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +3 -0
  21. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +2 -7
  22. package/Microsoft.ReactNative/IReactPackageBuilder.idl +5 -0
  23. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +2 -2
  24. package/Microsoft.ReactNative/Modules/Animated/AnimatedNode.cpp +3 -3
  25. package/Microsoft.ReactNative/Modules/Animated/AnimatedNode.h +3 -2
  26. package/Microsoft.ReactNative/Modules/Timing.h +2 -1
  27. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +2 -0
  28. package/Microsoft.ReactNative/ReactPackageBuilder.cpp +7 -0
  29. package/Microsoft.ReactNative/ReactPackageBuilder.h +1 -0
  30. package/Microsoft.ReactNative/TurboModulesProvider.cpp +5 -10
  31. package/Microsoft.ReactNative/TurboModulesProvider.h +2 -0
  32. package/Microsoft.ReactNative.Cxx/ModuleRegistration.cpp +8 -2
  33. package/Microsoft.ReactNative.Cxx/ModuleRegistration.h +17 -4
  34. package/Microsoft.ReactNative.Cxx/NativeModules.h +5 -0
  35. package/PropertySheets/External/Microsoft.ReactNative.Composition.CppApp.targets +2 -2
  36. package/PropertySheets/External/Microsoft.ReactNative.Composition.CppLib.targets +2 -2
  37. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
  38. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
  39. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  40. package/PropertySheets/JSEngine.props +2 -1
  41. package/PropertySheets/WinUI.props +3 -3
  42. package/ReactCommon/ReactCommon.vcxproj +1 -1
  43. package/Scripts/OfficeReact.Win32.nuspec +44 -44
  44. package/Scripts/Tfs/Invoke-WebRequestWithRetry.ps1 +40 -0
  45. package/Scripts/Tfs/Layout-Desktop-Headers.ps1 +1 -15
  46. package/Shared/Shared.vcxitems.filters +2 -2
  47. package/package.json +1 -1
  48. package/Scripts/OpenSSL.nuspec +0 -39
  49. package/Scripts/OpenSSL.targets +0 -36
@@ -94,7 +94,7 @@
94
94
  </ItemGroup>
95
95
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
96
96
  <ItemGroup>
97
- <PackageReference Include="boost" Version="1.83.0.0" />
97
+ <PackageReference Include="boost" Version="1.84.0.0" />
98
98
  <PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
99
99
  </ItemGroup>
100
100
  <ImportGroup Label="ExtensionTargets">
@@ -364,7 +364,7 @@
364
364
  <TemporaryFollyPatchFiles Include="$(MSBuildThisFileDirectory)\TEMP_UntilFollyUpdate\**\*.*" />
365
365
  </ItemGroup>
366
366
  <ItemGroup>
367
- <PackageReference Include="boost" Version="1.83.0.0" />
367
+ <PackageReference Include="boost" Version="1.84.0.0" />
368
368
  </ItemGroup>
369
369
  <Target Name="Deploy" />
370
370
  <!-- Reenable this task if we need to temporarily replace any folly files for fixes, while we wait for PRs to land in folly -->
@@ -41,13 +41,7 @@ export type PublicModalInstance = HostInstance;
41
41
  const ModalEventEmitter =
42
42
  (Platform.OS === 'ios' || Platform.OS === 'windows') && // [Windows]
43
43
  NativeModalManager != null
44
- ? new NativeEventEmitter<ModalEventDefinitions>(
45
- // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior
46
- // If you want to use the native module on other platforms, please remove this condition and test its behavior
47
- Platform.OS !== 'ios' && Platform.OS !== 'windows' // [Windows]
48
- ? null
49
- : NativeModalManager,
50
- )
44
+ ? new NativeEventEmitter<ModalEventDefinitions>(NativeModalManager)
51
45
  : null;
52
46
 
53
47
  /**
@@ -9,51 +9,39 @@
9
9
 
10
10
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
11
11
 
12
- // Ideally isColorMeaningful would be sufficient here. But it appears to detect platformColors as not meaningful
13
- // https://github.com/microsoft/react-native-windows/issues/14006
14
- bool isColorMeaningful(
15
- const facebook::react::SharedColor &color,
16
- winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme) noexcept {
17
- if (!color) {
18
- return false;
19
- }
20
-
21
- return theme->Color(*color).A > 0;
22
- }
23
-
24
12
  // We don't want half pixel borders, or border radii - they lead to blurry borders
25
13
  // Also apply scale factor to the radii at this point
26
14
  void pixelRoundBorderRadii(facebook::react::BorderRadii &borderRadii, float scaleFactor) noexcept {
27
15
  // Always round radii down to avoid spikey circles
28
16
  borderRadii.topLeft = {
29
- std::floor(borderRadii.topLeft.horizontal * scaleFactor), std::floor(borderRadii.topLeft.vertical * scaleFactor)};
17
+ .vertical = std::floor(borderRadii.topLeft.vertical * scaleFactor),
18
+ .horizontal = std::floor(borderRadii.topLeft.horizontal * scaleFactor)};
30
19
  borderRadii.topRight = {
31
- std::floor(borderRadii.topRight.horizontal * scaleFactor),
32
- std::floor(borderRadii.topRight.vertical * scaleFactor)};
20
+ .vertical = std::floor(borderRadii.topRight.vertical * scaleFactor),
21
+ .horizontal = std::floor(borderRadii.topRight.horizontal * scaleFactor)};
33
22
  borderRadii.bottomLeft = {
34
- std::floor(borderRadii.bottomLeft.horizontal * scaleFactor),
35
- std::floor(borderRadii.bottomLeft.vertical * scaleFactor)};
23
+ .vertical = std::floor(borderRadii.bottomLeft.vertical * scaleFactor),
24
+ .horizontal = std::floor(borderRadii.bottomLeft.horizontal * scaleFactor)};
36
25
  borderRadii.bottomRight = {
37
- std::floor(borderRadii.bottomRight.horizontal * scaleFactor),
38
- std::floor(borderRadii.bottomRight.vertical * scaleFactor)};
26
+ .vertical = std::floor(borderRadii.bottomRight.vertical * scaleFactor),
27
+ .horizontal = std::floor(borderRadii.bottomRight.horizontal * scaleFactor),
28
+ };
29
+ }
30
+
31
+ float pixelRoundAndScaleBorderWidth(float width, float scaleFactor) noexcept {
32
+ if (width == 0)
33
+ return width = 0;
34
+ return std::max(1.f, std::round(width * scaleFactor));
39
35
  }
40
36
 
41
37
  void scaleAndPixelRoundBorderWidths(
42
38
  facebook::react::LayoutMetrics const &layoutMetrics,
43
39
  facebook::react::BorderMetrics &borderMetrics,
44
40
  float scaleFactor) noexcept {
45
- borderMetrics.borderWidths.left = (borderMetrics.borderWidths.left == 0)
46
- ? 0.f
47
- : std::max(1.f, std::round(borderMetrics.borderWidths.left * scaleFactor));
48
- borderMetrics.borderWidths.top = (borderMetrics.borderWidths.top == 0)
49
- ? 0.f
50
- : std::max(1.f, std::round(borderMetrics.borderWidths.top * scaleFactor));
51
- borderMetrics.borderWidths.right = (borderMetrics.borderWidths.right == 0)
52
- ? 0.f
53
- : std::max(1.f, std::round(borderMetrics.borderWidths.right * scaleFactor));
54
- borderMetrics.borderWidths.bottom = (borderMetrics.borderWidths.bottom == 0)
55
- ? 0.f
56
- : std::max(1.f, std::round(borderMetrics.borderWidths.bottom * scaleFactor));
41
+ borderMetrics.borderWidths.left = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.left, scaleFactor);
42
+ borderMetrics.borderWidths.top = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.top, scaleFactor);
43
+ borderMetrics.borderWidths.right = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.right, scaleFactor);
44
+ borderMetrics.borderWidths.bottom = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.bottom, scaleFactor);
57
45
 
58
46
  // If we rounded both sides of the borderWidths up, we may have made the borderWidths larger than the total
59
47
  if (layoutMetrics.frame.size.width * scaleFactor <
@@ -268,30 +256,14 @@ RoundedPathParameters GenerateRoundedPathParameters(
268
256
  return result;
269
257
  }
270
258
 
271
- float totalTopRadius = baseRadius.topLeft.horizontal + baseRadius.topRight.horizontal;
272
- float totalRightRadius = baseRadius.topRight.vertical + baseRadius.bottomRight.vertical;
273
- float totalBottomRadius = baseRadius.bottomRight.horizontal + baseRadius.bottomLeft.horizontal;
274
- float totalLeftRadius = baseRadius.bottomLeft.vertical + baseRadius.topLeft.vertical;
275
-
276
- float maxHorizontalRadius = std::max(totalTopRadius, totalBottomRadius);
277
- float maxVerticalRadius = std::max(totalLeftRadius, totalRightRadius);
278
-
279
- double totalWidth = inset.left + inset.right + pathSize.width;
280
- double totalHeight = inset.top + inset.bottom + pathSize.height;
281
-
282
- float scaleHoriz = static_cast<float>(maxHorizontalRadius / totalWidth);
283
- float scaleVert = static_cast<float>(maxVerticalRadius / totalHeight);
284
-
285
- float maxScale = std::max(1.0f, std::max(scaleHoriz, scaleVert));
286
-
287
- result.topLeftRadiusX = std::max(0.0f, baseRadius.topLeft.horizontal / maxScale - inset.left);
288
- result.topLeftRadiusY = std::max(0.0f, baseRadius.topLeft.vertical / maxScale - inset.top);
289
- result.topRightRadiusX = std::max(0.0f, baseRadius.topRight.horizontal / maxScale - inset.right);
290
- result.topRightRadiusY = std::max(0.0f, baseRadius.topRight.vertical / maxScale - inset.top);
291
- result.bottomRightRadiusX = std::max(0.0f, baseRadius.bottomRight.horizontal / maxScale - inset.right);
292
- result.bottomRightRadiusY = std::max(0.0f, baseRadius.bottomRight.vertical / maxScale - inset.bottom);
293
- result.bottomLeftRadiusX = std::max(0.0f, baseRadius.bottomLeft.horizontal / maxScale - inset.left);
294
- result.bottomLeftRadiusY = std::max(0.0f, baseRadius.bottomLeft.vertical / maxScale - inset.bottom);
259
+ result.topLeftRadiusX = std::max(0.0f, baseRadius.topLeft.horizontal - inset.left);
260
+ result.topLeftRadiusY = std::max(0.0f, baseRadius.topLeft.vertical - inset.top);
261
+ result.topRightRadiusX = std::max(0.0f, baseRadius.topRight.horizontal - inset.right);
262
+ result.topRightRadiusY = std::max(0.0f, baseRadius.topRight.vertical - inset.top);
263
+ result.bottomRightRadiusX = std::max(0.0f, baseRadius.bottomRight.horizontal - inset.right);
264
+ result.bottomRightRadiusY = std::max(0.0f, baseRadius.bottomRight.vertical - inset.bottom);
265
+ result.bottomLeftRadiusX = std::max(0.0f, baseRadius.bottomLeft.horizontal - inset.left);
266
+ result.bottomLeftRadiusY = std::max(0.0f, baseRadius.bottomLeft.vertical - inset.bottom);
295
267
 
296
268
  return result;
297
269
  }
@@ -370,7 +342,7 @@ void SetBorderLayerPropertiesCommon(
370
342
  // Clear with transparency
371
343
  pRT->Clear();
372
344
 
373
- if (!isColorMeaningful(borderColor, theme)) {
345
+ if (!facebook::react::isColorMeaningful(borderColor)) {
374
346
  return;
375
347
  }
376
348
 
@@ -473,8 +445,8 @@ void SetBorderLayerProperties(
473
445
  /*
474
446
  else
475
447
  {
476
- SetBorderLayerPropertiesCommon(theme, comContext, layer, shape, borderTexture, textureRect,
477
- anchorPoint, anchorOffset, strokeWidth, borderColor, borderStyle);
448
+ SetBorderLayerPropertiesCommon(theme, compContext, layer, shape, borderTexture, textureRect,
449
+ anchorPoint, anchorOffset, size, relativeSizeAdjustment, strokeWidth, borderColor, borderStyle);
478
450
  }
479
451
  */
480
452
  }
@@ -516,11 +488,11 @@ void DrawAllBorderLayers(
516
488
  spTextures[0], // Target Layer, Source Texture, Target Texture
517
489
  {0,
518
490
  0,
519
- borderRadii.topLeft.vertical + borderWidths.left,
520
- borderRadii.topLeft.horizontal + borderWidths.top}, // Texture Left, Top, Width, Height
491
+ borderRadii.topLeft.horizontal + borderWidths.left,
492
+ borderRadii.topLeft.vertical + borderWidths.top}, // Texture Left, Top, Width, Height
521
493
  {AnchorPosition::Left, AnchorPosition::Top}, // Layer Anchor Point
522
494
  {0, 0}, // Layer Anchor Offset
523
- {borderRadii.topLeft.vertical + borderWidths.left, borderRadii.topLeft.horizontal + borderWidths.top}, // size
495
+ {borderRadii.topLeft.horizontal + borderWidths.left, borderRadii.topLeft.vertical + borderWidths.top}, // size
524
496
  {0.0f, 0.0f}, // relativeSize
525
497
  std::max(borderWidths.left, borderWidths.top),
526
498
  borderColors.left ? borderColors.left : borderColors.top,
@@ -533,13 +505,13 @@ void DrawAllBorderLayers(
533
505
  spBorderLayers[1],
534
506
  shape,
535
507
  spTextures[1],
536
- {borderRadii.topLeft.vertical + borderWidths.left,
508
+ {borderRadii.topLeft.horizontal + borderWidths.left,
537
509
  0,
538
- textureWidth - (borderRadii.topRight.vertical + borderWidths.right),
510
+ textureWidth - (borderRadii.topRight.horizontal + borderWidths.right),
539
511
  borderWidths.top},
540
512
  {AnchorPosition::Left, AnchorPosition::Top},
541
- {borderRadii.topLeft.vertical + borderWidths.left, 0},
542
- {-(borderRadii.topLeft.vertical + borderWidths.left + borderRadii.topRight.vertical + borderWidths.right),
513
+ {borderRadii.topLeft.horizontal + borderWidths.left, 0},
514
+ {-(borderRadii.topLeft.horizontal + borderWidths.left + borderRadii.topRight.horizontal + borderWidths.right),
543
515
  borderWidths.top}, // size
544
516
  {1.0f, 0.0f}, // relativeSize
545
517
  borderWidths.top,
@@ -553,13 +525,13 @@ void DrawAllBorderLayers(
553
525
  spBorderLayers[2],
554
526
  shape,
555
527
  spTextures[2],
556
- {textureWidth - (borderRadii.topRight.vertical + borderWidths.right),
528
+ {textureWidth - (borderRadii.topRight.horizontal + borderWidths.right),
557
529
  0,
558
530
  textureWidth,
559
- borderRadii.topRight.horizontal + borderWidths.top},
531
+ borderRadii.topRight.vertical + borderWidths.top},
560
532
  {AnchorPosition::Right, AnchorPosition::Top},
561
- {-(borderRadii.topRight.vertical + borderWidths.right), 0},
562
- {borderRadii.topRight.vertical + borderWidths.right, borderRadii.topRight.horizontal + borderWidths.top},
533
+ {-(borderRadii.topRight.horizontal + borderWidths.right), 0},
534
+ {borderRadii.topRight.horizontal + borderWidths.right, borderRadii.topRight.vertical + borderWidths.top},
563
535
  {0.0f, 0.0f},
564
536
  std::max(borderWidths.right, borderWidths.top),
565
537
  borderColors.right ? borderColors.right : borderColors.top,
@@ -573,14 +545,14 @@ void DrawAllBorderLayers(
573
545
  shape,
574
546
  spTextures[3],
575
547
  {textureWidth - borderWidths.right,
576
- borderWidths.top + borderRadii.topRight.horizontal,
548
+ borderWidths.top + borderRadii.topRight.vertical,
577
549
  textureWidth,
578
- textureHeight - (borderWidths.bottom + borderRadii.bottomRight.horizontal)},
550
+ textureHeight - (borderWidths.bottom + borderRadii.bottomRight.vertical)},
579
551
  {AnchorPosition::Right, AnchorPosition::Top},
580
- {-borderWidths.right, borderWidths.top + borderRadii.topRight.horizontal},
552
+ {-borderWidths.right, borderWidths.top + borderRadii.topRight.vertical},
581
553
  {borderWidths.right,
582
- -(borderWidths.top + borderRadii.topRight.horizontal + borderWidths.bottom +
583
- borderRadii.bottomRight.horizontal)}, // size
554
+ -(borderWidths.top + borderRadii.topRight.vertical + borderWidths.bottom +
555
+ borderRadii.bottomRight.vertical)}, // size
584
556
  {0.0f, 1.0f},
585
557
  borderWidths.right,
586
558
  borderColors.right,
@@ -593,14 +565,14 @@ void DrawAllBorderLayers(
593
565
  spBorderLayers[4],
594
566
  shape,
595
567
  spTextures[4],
596
- {textureWidth - (borderWidths.right + borderRadii.bottomRight.vertical),
597
- textureHeight - (borderWidths.bottom + borderRadii.bottomRight.horizontal),
568
+ {textureWidth - (borderWidths.right + borderRadii.bottomRight.horizontal),
569
+ textureHeight - (borderWidths.bottom + borderRadii.bottomRight.vertical),
598
570
  textureWidth,
599
571
  textureHeight},
600
572
  {AnchorPosition::Right, AnchorPosition::Bottom},
601
- {-(borderWidths.right + borderRadii.bottomRight.vertical),
602
- -(borderWidths.bottom + borderRadii.bottomRight.horizontal)},
603
- {borderWidths.right + borderRadii.bottomRight.vertical, borderWidths.bottom + borderRadii.bottomRight.horizontal},
573
+ {-(borderWidths.right + borderRadii.bottomRight.horizontal),
574
+ -(borderWidths.bottom + borderRadii.bottomRight.vertical)},
575
+ {borderWidths.right + borderRadii.bottomRight.horizontal, borderWidths.bottom + borderRadii.bottomRight.vertical},
604
576
  {0, 0},
605
577
  std::max(borderWidths.right, borderWidths.bottom),
606
578
  borderColors.right ? borderColors.right : borderColors.bottom,
@@ -613,13 +585,14 @@ void DrawAllBorderLayers(
613
585
  spBorderLayers[5],
614
586
  shape,
615
587
  spTextures[5],
616
- {borderWidths.left + borderRadii.bottomLeft.vertical,
588
+ {borderWidths.left + borderRadii.bottomLeft.horizontal,
617
589
  textureHeight - borderWidths.bottom,
618
- textureWidth - (borderWidths.right + borderRadii.bottomRight.vertical),
590
+ textureWidth - (borderWidths.right + borderRadii.bottomRight.horizontal),
619
591
  textureHeight},
620
592
  {AnchorPosition::Left, AnchorPosition::Bottom},
621
- {borderWidths.left + borderRadii.bottomLeft.vertical, -borderWidths.bottom},
622
- {-(borderWidths.right + borderRadii.bottomLeft.vertical + borderWidths.left + borderRadii.bottomRight.vertical),
593
+ {borderWidths.left + borderRadii.bottomLeft.horizontal, -borderWidths.bottom},
594
+ {-(borderWidths.right + borderRadii.bottomLeft.horizontal + borderWidths.left +
595
+ borderRadii.bottomRight.horizontal),
623
596
  borderWidths.bottom},
624
597
  {1.0f, 0.0f},
625
598
  borderWidths.bottom,
@@ -634,12 +607,12 @@ void DrawAllBorderLayers(
634
607
  shape,
635
608
  spTextures[6],
636
609
  {0,
637
- textureHeight - (borderWidths.bottom + borderRadii.bottomLeft.horizontal),
638
- borderWidths.left + borderRadii.bottomLeft.vertical,
610
+ textureHeight - (borderWidths.bottom + borderRadii.bottomLeft.vertical),
611
+ borderWidths.left + borderRadii.bottomLeft.horizontal,
639
612
  textureHeight},
640
613
  {AnchorPosition::Left, AnchorPosition::Bottom},
641
- {0, -(borderWidths.bottom + borderRadii.bottomLeft.horizontal)},
642
- {borderWidths.left + borderRadii.bottomLeft.vertical, borderWidths.bottom + borderRadii.bottomLeft.horizontal},
614
+ {0, -(borderWidths.bottom + borderRadii.bottomLeft.vertical)},
615
+ {borderWidths.left + borderRadii.bottomLeft.horizontal, borderWidths.bottom + borderRadii.bottomLeft.vertical},
643
616
  {0, 0},
644
617
  std::max(borderWidths.left, borderWidths.bottom),
645
618
  borderColors.left ? borderColors.left : borderColors.bottom,
@@ -653,13 +626,13 @@ void DrawAllBorderLayers(
653
626
  shape,
654
627
  spTextures[7],
655
628
  {0,
656
- borderWidths.top + borderRadii.topLeft.horizontal,
629
+ borderWidths.top + borderRadii.topLeft.vertical,
657
630
  borderWidths.left,
658
- textureHeight - (borderWidths.bottom + borderRadii.bottomLeft.horizontal)},
631
+ textureHeight - (borderWidths.bottom + borderRadii.bottomLeft.vertical)},
659
632
  {AnchorPosition::Left, AnchorPosition::Top},
660
- {0, borderWidths.top + borderRadii.topLeft.horizontal},
633
+ {0, borderWidths.top + borderRadii.topLeft.vertical},
661
634
  {borderWidths.left,
662
- -(borderWidths.top + borderRadii.topLeft.horizontal + borderWidths.bottom + borderRadii.bottomLeft.horizontal)},
635
+ -(borderWidths.top + borderRadii.topLeft.vertical + borderWidths.bottom + borderRadii.bottomLeft.vertical)},
663
636
  {0, 1},
664
637
  borderWidths.left,
665
638
  borderColors.left,
@@ -737,7 +710,7 @@ winrt::com_ptr<ID2D1GeometryGroup> GetGeometryForRoundedBorder(
737
710
  BorderPrimitive::BorderPrimitive(
738
711
  winrt::Microsoft::ReactNative::Composition::implementation::ComponentView &outer,
739
712
  const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &rootVisual)
740
- : m_outer(&outer), m_rootVisual(rootVisual) {}
713
+ : m_outer(&outer), m_rootVisual(rootVisual), m_ownsRootVisual(false) {}
741
714
 
742
715
  BorderPrimitive::BorderPrimitive(winrt::Microsoft::ReactNative::Composition::implementation::ComponentView &outer)
743
716
  : m_outer(&outer), m_rootVisual(outer.CompositionContext().CreateSpriteVisual()) {}
@@ -753,9 +726,9 @@ bool BorderPrimitive::requiresBorder(
753
726
  auto borderStyle = borderMetrics.borderStyles.left;
754
727
 
755
728
  bool hasMeaningfulColor =
756
- !borderMetrics.borderColors.isUniform() || !isColorMeaningful(borderMetrics.borderColors.left, theme);
729
+ !borderMetrics.borderColors.isUniform() || facebook::react::isColorMeaningful(borderMetrics.borderColors.left);
757
730
  bool hasMeaningfulWidth = !borderMetrics.borderWidths.isUniform() || (borderMetrics.borderWidths.left != 0);
758
- if (!hasMeaningfulColor && !hasMeaningfulWidth) {
731
+ if (!hasMeaningfulColor || !hasMeaningfulWidth) {
759
732
  return false;
760
733
  }
761
734
  return true;
@@ -815,8 +788,10 @@ BorderPrimitive::FindSpecialBorderLayers() const noexcept {
815
788
  nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
816
789
 
817
790
  if (m_numBorderVisuals) {
791
+ auto borderInsertAtIndex = m_ownsRootVisual ? 0 : m_outer->borderInsertAtIndex();
792
+
818
793
  for (uint8_t i = 0; i < m_numBorderVisuals; i++) {
819
- auto visual = m_rootVisual.GetAt(i);
794
+ auto visual = m_rootVisual.GetAt(i + borderInsertAtIndex);
820
795
  layers[i] = visual.as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>();
821
796
  }
822
797
  }
@@ -843,7 +818,7 @@ bool BorderPrimitive::TryUpdateSpecialBorderLayers(
843
818
  auto borderStyle = borderMetrics.borderStyles.left;
844
819
 
845
820
  bool hasMeaningfulColor =
846
- !borderMetrics.borderColors.isUniform() || !isColorMeaningful(borderMetrics.borderColors.left, theme);
821
+ !borderMetrics.borderColors.isUniform() || !facebook::react::isColorMeaningful(borderMetrics.borderColors.left);
847
822
  bool hasMeaningfulWidth = !borderMetrics.borderWidths.isUniform() || (borderMetrics.borderWidths.left != 0);
848
823
  if (!hasMeaningfulColor && !hasMeaningfulWidth) {
849
824
  return false;
@@ -851,9 +826,10 @@ bool BorderPrimitive::TryUpdateSpecialBorderLayers(
851
826
 
852
827
  // Create the special border layers if they don't exist yet
853
828
  if (!spBorderVisuals[0]) {
829
+ auto borderInsertAtIndex = m_ownsRootVisual ? 0 : m_outer->borderInsertAtIndex();
854
830
  for (uint8_t i = 0; i < SpecialBorderLayerCount; i++) {
855
831
  auto visual = m_outer->CompositionContext().CreateSpriteVisual();
856
- m_rootVisual.InsertAt(visual, i);
832
+ m_rootVisual.InsertAt(visual, i + borderInsertAtIndex);
857
833
  spBorderVisuals[i] = std::move(visual);
858
834
  m_numBorderVisuals++;
859
835
  }
@@ -14,6 +14,8 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
14
14
 
15
15
  struct ComponentView;
16
16
 
17
+ float pixelRoundAndScaleBorderWidth(float width, float scaleFactor) noexcept;
18
+
17
19
  // Controls adding/removing appropriate visuals to a parent to render a specific border without requiring
18
20
  struct BorderPrimitive {
19
21
  static constexpr size_t SpecialBorderLayerCount = 8;
@@ -74,7 +76,8 @@ struct BorderPrimitive {
74
76
  uint8_t m_numBorderVisuals{0};
75
77
  winrt::Microsoft::ReactNative::Composition::implementation::ComponentView *m_outer;
76
78
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_rootVisual{nullptr};
77
- bool m_needsUpdate{true};
79
+ bool m_needsUpdate : 1 {true};
80
+ bool m_ownsRootVisual : 1 {false};
78
81
  };
79
82
 
80
83
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -2,6 +2,9 @@
2
2
  #include "pch.h"
3
3
  #include "CompositionContextHelper.h"
4
4
  #include <algorithm>
5
+ #include <cassert>
6
+ #include <exception>
7
+ #include <vector>
5
8
  #if __has_include("Composition.Experimental.SystemCompositionContextHelper.g.cpp")
6
9
  #include "Composition.Experimental.SystemCompositionContextHelper.g.cpp"
7
10
  #endif
@@ -443,30 +446,43 @@ struct CompVisualImpl {
443
446
  void InsertAt(
444
447
  const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual,
445
448
  uint32_t index) noexcept {
449
+ if (index > m_childrenCache.size()) {
450
+ std::terminate();
451
+ }
446
452
  auto containerChildren = InnerVisual().as<typename TTypeRedirects::ContainerVisual>().Children();
447
453
  auto compVisual = TTypeRedirects::CompositionContextHelper::InnerVisual(visual);
448
454
  if (index == 0) {
449
455
  containerChildren.InsertAtBottom(compVisual);
450
- return;
456
+ } else {
457
+ auto insertAfter = containerChildren.First();
458
+ for (uint32_t i = 1; i < index; i++)
459
+ insertAfter.MoveNext();
460
+ containerChildren.InsertAbove(compVisual, insertAfter.Current());
461
+ }
462
+ if (index >= m_childrenCache.size()) {
463
+ m_childrenCache.push_back(visual);
464
+ } else {
465
+ m_childrenCache.insert(m_childrenCache.begin() + index, visual);
451
466
  }
452
- auto insertAfter = containerChildren.First();
453
- for (uint32_t i = 1; i < index; i++)
454
- insertAfter.MoveNext();
455
- containerChildren.InsertAbove(compVisual, insertAfter.Current());
456
467
  }
457
468
 
458
469
  void Remove(const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept {
459
470
  auto compVisual = TTypeRedirects::CompositionContextHelper::InnerVisual(visual);
460
471
  auto containerChildren = InnerVisual().as<typename TTypeRedirects::ContainerVisual>().Children();
461
472
  containerChildren.Remove(compVisual);
473
+ auto it = std::find_if(
474
+ m_childrenCache.begin(), m_childrenCache.end(), [&visual](const auto &cached) { return cached == visual; });
475
+ if (it != m_childrenCache.end()) {
476
+ m_childrenCache.erase(it);
477
+ }
462
478
  }
463
479
 
464
480
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual GetAt(uint32_t index) noexcept {
465
- auto containerChildren = m_visual.as<typename TTypeRedirects::ContainerVisual>().Children();
466
- auto it = containerChildren.First();
467
- for (uint32_t i = 0; i < index; i++)
468
- it.MoveNext();
469
- return TTypeRedirects::CompositionContextHelper::CreateVisual(it.Current());
481
+ if (index < m_childrenCache.size()) {
482
+ return m_childrenCache[index];
483
+ }
484
+ assert(false && "GetAt called with out-of-range index");
485
+ return nullptr;
470
486
  }
471
487
 
472
488
  void SetClippingPath(ID2D1Geometry *clippingPath) noexcept {
@@ -546,6 +562,7 @@ struct CompVisualImpl {
546
562
 
547
563
  protected:
548
564
  TVisual m_visual;
565
+ std::vector<winrt::Microsoft::ReactNative::Composition::Experimental::IVisual> m_childrenCache;
549
566
  };
550
567
 
551
568
  template <typename TTypeRedirects>
@@ -866,30 +883,43 @@ struct CompScrollerVisual : winrt::implements<
866
883
  void InsertAt(
867
884
  const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual,
868
885
  uint32_t index) noexcept {
886
+ if (index > m_childrenCache.size()) {
887
+ std::terminate();
888
+ }
869
889
  auto containerChildren = m_contentVisual.Children();
870
890
  auto compVisual = TTypeRedirects::CompositionContextHelper::InnerVisual(visual);
871
891
  if (index == 0) {
872
892
  containerChildren.InsertAtBottom(compVisual);
873
- return;
893
+ } else {
894
+ auto insertAfter = containerChildren.First();
895
+ for (uint32_t i = 1; i < index; i++)
896
+ insertAfter.MoveNext();
897
+ containerChildren.InsertAbove(compVisual, insertAfter.Current());
898
+ }
899
+ if (index >= m_childrenCache.size()) {
900
+ m_childrenCache.push_back(visual);
901
+ } else {
902
+ m_childrenCache.insert(m_childrenCache.begin() + index, visual);
874
903
  }
875
- auto insertAfter = containerChildren.First();
876
- for (uint32_t i = 1; i < index; i++)
877
- insertAfter.MoveNext();
878
- containerChildren.InsertAbove(compVisual, insertAfter.Current());
879
904
  }
880
905
 
881
906
  void Remove(const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept {
882
907
  auto compVisual = TTypeRedirects::CompositionContextHelper::InnerVisual(visual);
883
908
  auto containerChildren = m_contentVisual.Children();
884
909
  containerChildren.Remove(compVisual);
910
+ auto it = std::find_if(
911
+ m_childrenCache.begin(), m_childrenCache.end(), [&visual](const auto &cached) { return cached == visual; });
912
+ if (it != m_childrenCache.end()) {
913
+ m_childrenCache.erase(it);
914
+ }
885
915
  }
886
916
 
887
917
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual GetAt(uint32_t index) noexcept {
888
- auto containerChildren = m_visual.as<typename TTypeRedirects::ContainerVisual>().Children();
889
- auto it = containerChildren.First();
890
- for (uint32_t i = 0; i < index; i++)
891
- it.MoveNext();
892
- return TTypeRedirects::CompositionContextHelper::CreateVisual(it.Current());
918
+ if (index < m_childrenCache.size()) {
919
+ return m_childrenCache[index];
920
+ }
921
+ assert(false && "GetAt called with out-of-range index");
922
+ return nullptr;
893
923
  }
894
924
 
895
925
  void Brush(const winrt::Microsoft::ReactNative::Composition::Experimental::IBrush &brush) noexcept {
@@ -1273,6 +1303,12 @@ struct CompScrollerVisual : winrt::implements<
1273
1303
  std::sort(snapPositions.begin(), snapPositions.end());
1274
1304
  snapPositions.erase(std::unique(snapPositions.begin(), snapPositions.end()), snapPositions.end());
1275
1305
 
1306
+ // Skip reconfiguration if snap points haven't changed
1307
+ if (snapPositions == m_previousSnapPositions) {
1308
+ return;
1309
+ }
1310
+ m_previousSnapPositions = snapPositions;
1311
+
1276
1312
  std::vector<typename TTypeRedirects::InteractionTrackerInertiaRestingValue> restingValues;
1277
1313
 
1278
1314
  for (size_t i = 0; i < snapPositions.size(); ++i) {
@@ -1402,6 +1438,7 @@ struct CompScrollerVisual : winrt::implements<
1402
1438
  winrt::Microsoft::ReactNative::Composition::Experimental::SnapPointsAlignment m_snapToAlignment{
1403
1439
  winrt::Microsoft::ReactNative::Composition::Experimental::SnapPointsAlignment::Near};
1404
1440
  std::vector<float> m_snapToOffsets;
1441
+ std::vector<float> m_previousSnapPositions;
1405
1442
  bool m_inertia{false};
1406
1443
  bool m_custom{false};
1407
1444
  bool m_interacting{false};
@@ -1428,6 +1465,7 @@ struct CompScrollerVisual : winrt::implements<
1428
1465
  typename TTypeRedirects::SpriteVisual m_contentVisual{nullptr};
1429
1466
  typename TTypeRedirects::InteractionTracker m_interactionTracker{nullptr};
1430
1467
  typename TTypeRedirects::VisualInteractionSource m_visualInteractionSource{nullptr};
1468
+ std::vector<winrt::Microsoft::ReactNative::Composition::Experimental::IVisual> m_childrenCache;
1431
1469
  };
1432
1470
  using WindowsCompScrollerVisual = CompScrollerVisual<WindowsTypeRedirects>;
1433
1471
  #ifdef USE_WINUI3
@@ -2196,7 +2234,6 @@ struct CompContext : winrt::implements<
2196
2234
  winrt::com_ptr<ID3D11Device> m_d3dDevice;
2197
2235
  winrt::com_ptr<ID2D1Device> m_d2dDevice;
2198
2236
  typename TTypeRedirects::CompositionGraphicsDevice m_compositionGraphicsDevice{nullptr};
2199
- winrt::com_ptr<ID3D11DeviceContext> m_d3dDeviceContext;
2200
2237
  };
2201
2238
 
2202
2239
  winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual