basalt-win32 0.0.0-rc5

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/cli/runWindows.js +35 -0
  3. package/cli/shared.js +75 -0
  4. package/native/CMakeLists.txt +398 -0
  5. package/native/tests/test_win32_accessibility.cpp +271 -0
  6. package/native/tests/test_win32_clipboard.cpp +121 -0
  7. package/native/tests/test_win32_focus.cpp +195 -0
  8. package/native/tests/test_win32_hittest.cpp +410 -0
  9. package/native/tests/test_win32_image.cpp +239 -0
  10. package/native/tests/test_win32_imageloader.cpp +208 -0
  11. package/native/tests/test_win32_input.cpp +361 -0
  12. package/native/tests/test_win32_key_events.cpp +84 -0
  13. package/native/tests/test_win32_mounting.cpp +410 -0
  14. package/native/tests/test_win32_paint.cpp +505 -0
  15. package/native/tests/test_win32_scrollview.cpp +385 -0
  16. package/native/tests/test_win32_text.cpp +258 -0
  17. package/native/tests/test_win32_textinput.cpp +609 -0
  18. package/native/tests/test_win32_titlebar.cpp +111 -0
  19. package/native/tests/test_win32_titlebar_actions.cpp +62 -0
  20. package/native/tests/test_win32_view.cpp +222 -0
  21. package/native/win32/ColorSchemeWin32.cpp +56 -0
  22. package/native/win32/ComponentRegistryWin32.cpp +124 -0
  23. package/native/win32/DirectWriteLayout.cpp +116 -0
  24. package/native/win32/DirectWriteLayout.h +36 -0
  25. package/native/win32/DirectWriteLayoutManager.cpp +124 -0
  26. package/native/win32/FontRegistryDirectWrite.cpp +117 -0
  27. package/native/win32/PlatformServicesWin32.cpp +643 -0
  28. package/native/win32/RnWin32Accessible.cpp +258 -0
  29. package/native/win32/RnWin32Accessible.h +91 -0
  30. package/native/win32/RnWin32Image.cpp +265 -0
  31. package/native/win32/RnWin32Image.h +93 -0
  32. package/native/win32/RnWin32TextLayout.cpp +310 -0
  33. package/native/win32/RnWin32TextLayout.h +160 -0
  34. package/native/win32/RnWin32View.cpp +1281 -0
  35. package/native/win32/RnWin32View.h +506 -0
  36. package/native/win32/Win32AnimationChoreographer.cpp +76 -0
  37. package/native/win32/Win32AnimationChoreographer.h +61 -0
  38. package/native/win32/Win32Clip.h +173 -0
  39. package/native/win32/Win32DropTarget.cpp +567 -0
  40. package/native/win32/Win32DropTarget.h +42 -0
  41. package/native/win32/Win32Focus.cpp +262 -0
  42. package/native/win32/Win32Focus.h +109 -0
  43. package/native/win32/Win32ImageLoader.cpp +167 -0
  44. package/native/win32/Win32ImageLoader.h +104 -0
  45. package/native/win32/Win32KeyEvents.cpp +126 -0
  46. package/native/win32/Win32KeyEvents.h +20 -0
  47. package/native/win32/Win32MenuBar.cpp +352 -0
  48. package/native/win32/Win32MenuBar.h +16 -0
  49. package/native/win32/Win32MountingManager.cpp +727 -0
  50. package/native/win32/Win32MountingManager.h +203 -0
  51. package/native/win32/Win32Packaging.cpp +161 -0
  52. package/native/win32/Win32Packaging.h +56 -0
  53. package/native/win32/Win32RunLoopObserver.cpp +48 -0
  54. package/native/win32/Win32RunLoopObserver.h +42 -0
  55. package/native/win32/Win32ScrollView.cpp +515 -0
  56. package/native/win32/Win32ScrollView.h +208 -0
  57. package/native/win32/Win32SkiaContext.cpp +221 -0
  58. package/native/win32/Win32SkiaContext.h +53 -0
  59. package/native/win32/Win32SkiaModule.cpp +80 -0
  60. package/native/win32/Win32SkiaModule.h +50 -0
  61. package/native/win32/Win32SkiaPeer.cpp +358 -0
  62. package/native/win32/Win32SkiaPeer.h +66 -0
  63. package/native/win32/Win32SkiaUnicode.cpp +42 -0
  64. package/native/win32/Win32Snapshot.cpp +201 -0
  65. package/native/win32/Win32Snapshot.h +66 -0
  66. package/native/win32/Win32Strings.h +54 -0
  67. package/native/win32/Win32TextInput.cpp +811 -0
  68. package/native/win32/Win32TextInput.h +232 -0
  69. package/native/win32/Win32TitleBar.cpp +562 -0
  70. package/native/win32/Win32TitleBar.h +146 -0
  71. package/native/win32/Win32TitleBarLayout.cpp +46 -0
  72. package/native/win32/Win32TitleBarLayout.h +58 -0
  73. package/native/win32/Win32TouchDispatcher.cpp +443 -0
  74. package/native/win32/Win32TouchDispatcher.h +153 -0
  75. package/native/win32/Win32UiThread.h +27 -0
  76. package/native/win32/Win32WindowControl.cpp +329 -0
  77. package/native/win32/Win32WindowModule.cpp +209 -0
  78. package/native/win32/Win32WindowModule.h +72 -0
  79. package/native/win32/demo_layout_win32.cpp +232 -0
  80. package/native/win32/main_win32.cpp +2481 -0
  81. package/native/win32/mount_harness_win32.cpp +316 -0
  82. package/package.json +26 -0
  83. package/react-native.config.js +22 -0
@@ -0,0 +1,173 @@
1
+ // A scoped clip that survives a rotation.
2
+ //
3
+ // PushAxisAlignedClip is the cheap way to clip and it is wrong wherever a
4
+ // transform is in play: it clips to the rectangle's *bounding box* under the
5
+ // current transform, so inside a rotated view the clip is a larger upright box
6
+ // and content escapes at the corners. A layer with a geometric mask is correct
7
+ // under any transform.
8
+ //
9
+ // Shared because there are two places that clip -- `overflow: hidden` on a view
10
+ // and an <Image> that must not paint outside its own frame -- and a platform
11
+ // where one of them handles rotation and the other does not is worse than one
12
+ // where neither does: the difference only shows up in a picture, on a screen
13
+ // nobody is looking at.
14
+
15
+ #pragma once
16
+
17
+ #include <windows.h>
18
+
19
+ #include <d2d1.h>
20
+ #include <wrl/client.h>
21
+
22
+ namespace basalt::win32 {
23
+
24
+ // A box with its own horizontal and vertical radius at each corner -- what
25
+ // React Native resolves every border-radius prop to -- as a geometry.
26
+ //
27
+ // `radii` is eight numbers in the order describeTree prints them: top-left,
28
+ // top-right, bottom-right, bottom-left, each horizontal then vertical. They are
29
+ // taken as already clamped so that opposite corners do not overlap, which
30
+ // resolveBorderMetrics does before they get here.
31
+ //
32
+ // D2D1_ROUNDED_RECT has one radius pair for all four corners, which is why
33
+ // this host drew a single circular radius for as long as it did. A path with
34
+ // an arc per corner is the general case; the two cheaper shapes are kept for
35
+ // the boxes that are exactly them, which is nearly every box.
36
+ inline Microsoft::WRL::ComPtr<ID2D1Geometry>
37
+ roundedBoxGeometry(ID2D1Factory *factory, const D2D1_RECT_F &rect, const float radii[8]) {
38
+ Microsoft::WRL::ComPtr<ID2D1Geometry> result;
39
+ if (factory == nullptr) {
40
+ return result;
41
+ }
42
+
43
+ bool any = false;
44
+ bool uniform = true;
45
+ for (int i = 0; i < 8; i++) {
46
+ if (radii[i] > 0.0f) {
47
+ any = true;
48
+ }
49
+ if (radii[i] != radii[0]) {
50
+ uniform = false;
51
+ }
52
+ }
53
+
54
+ if (!any) {
55
+ Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> plain;
56
+ if (SUCCEEDED(factory->CreateRectangleGeometry(rect, plain.GetAddressOf()))) {
57
+ result = plain;
58
+ }
59
+ return result;
60
+ }
61
+ if (uniform) {
62
+ Microsoft::WRL::ComPtr<ID2D1RoundedRectangleGeometry> rounded;
63
+ if (SUCCEEDED(factory->CreateRoundedRectangleGeometry(
64
+ D2D1::RoundedRect(rect, radii[0], radii[0]), rounded.GetAddressOf()))) {
65
+ result = rounded;
66
+ }
67
+ return result;
68
+ }
69
+
70
+ Microsoft::WRL::ComPtr<ID2D1PathGeometry> path;
71
+ Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink;
72
+ if (FAILED(factory->CreatePathGeometry(path.GetAddressOf())) ||
73
+ FAILED(path->Open(sink.GetAddressOf()))) {
74
+ return result;
75
+ }
76
+
77
+ const float left = rect.left;
78
+ const float top = rect.top;
79
+ const float right = rect.right;
80
+ const float bottom = rect.bottom;
81
+ // A corner with either radius zero is square: the line runs on to the
82
+ // corner's end point along the edge, which is the same point.
83
+ const auto corner = [&sink](float x, float y, float rx, float ry) {
84
+ if (rx <= 0.0f || ry <= 0.0f) {
85
+ sink->AddLine(D2D1::Point2F(x, y));
86
+ return;
87
+ }
88
+ sink->AddArc(D2D1::ArcSegment(D2D1::Point2F(x, y),
89
+ D2D1::SizeF(rx, ry),
90
+ 0.0f,
91
+ D2D1_SWEEP_DIRECTION_CLOCKWISE,
92
+ D2D1_ARC_SIZE_SMALL));
93
+ };
94
+
95
+ // Clockwise from the end of the top-left corner.
96
+ sink->BeginFigure(D2D1::Point2F(left + radii[0], top), D2D1_FIGURE_BEGIN_FILLED);
97
+ sink->AddLine(D2D1::Point2F(right - radii[2], top));
98
+ corner(right, top + radii[3], radii[2], radii[3]);
99
+ sink->AddLine(D2D1::Point2F(right, bottom - radii[5]));
100
+ corner(right - radii[4], bottom, radii[4], radii[5]);
101
+ sink->AddLine(D2D1::Point2F(left + radii[6], bottom));
102
+ corner(left, bottom - radii[7], radii[6], radii[7]);
103
+ sink->AddLine(D2D1::Point2F(left, top + radii[1]));
104
+ corner(left + radii[0], top, radii[0], radii[1]);
105
+ sink->EndFigure(D2D1_FIGURE_END_CLOSED);
106
+ if (SUCCEEDED(sink->Close())) {
107
+ result = path;
108
+ }
109
+ return result;
110
+ }
111
+
112
+ class ScopedGeometryClip {
113
+ public:
114
+ // A null target means "no clip"; the caller then does not have to choose
115
+ // between an if and a scope.
116
+ //
117
+ // One circular radius on every corner: what an <Image> clips to.
118
+ ScopedGeometryClip(ID2D1RenderTarget *target, const D2D1_RECT_F &rect, float radius)
119
+ : target_(target) {
120
+ const float radii[8] = {radius, radius, radius, radius, radius, radius, radius, radius};
121
+ push(rect, radii);
122
+ }
123
+
124
+ // Per corner, in roundedBoxGeometry's order: what a view with
125
+ // `overflow: hidden` clips its children to.
126
+ ScopedGeometryClip(ID2D1RenderTarget *target, const D2D1_RECT_F &rect, const float radii[8])
127
+ : target_(target) {
128
+ push(rect, radii);
129
+ }
130
+
131
+ ~ScopedGeometryClip() {
132
+ if (pushed_) {
133
+ target_->PopLayer();
134
+ }
135
+ }
136
+
137
+ ScopedGeometryClip(const ScopedGeometryClip &) = delete;
138
+ ScopedGeometryClip &operator=(const ScopedGeometryClip &) = delete;
139
+
140
+ private:
141
+ void push(const D2D1_RECT_F &rect, const float radii[8]) {
142
+ if (target_ == nullptr) {
143
+ return;
144
+ }
145
+
146
+ Microsoft::WRL::ComPtr<ID2D1Factory> factory;
147
+ target_->GetFactory(factory.GetAddressOf());
148
+ const Microsoft::WRL::ComPtr<ID2D1Geometry> mask =
149
+ roundedBoxGeometry(factory.Get(), rect, radii);
150
+ if (!mask) {
151
+ return;
152
+ }
153
+
154
+ // One layer object per push. Direct2D pools the backing surfaces itself, so
155
+ // this costs an allocation rather than a render target; caching one per
156
+ // view is the optimisation to make if a profile ever asks for it.
157
+ if (FAILED(target_->CreateLayer(nullptr, layer_.GetAddressOf()))) {
158
+ return;
159
+ }
160
+
161
+ auto parameters = D2D1::LayerParameters();
162
+ parameters.contentBounds = D2D1::InfiniteRect();
163
+ parameters.geometricMask = mask.Get();
164
+ target_->PushLayer(parameters, layer_.Get());
165
+ pushed_ = true;
166
+ }
167
+
168
+ ID2D1RenderTarget *target_;
169
+ Microsoft::WRL::ComPtr<ID2D1Layer> layer_;
170
+ bool pushed_ = false;
171
+ };
172
+
173
+ } // namespace basalt::win32