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.
- package/LICENSE +21 -0
- package/cli/runWindows.js +35 -0
- package/cli/shared.js +75 -0
- package/native/CMakeLists.txt +398 -0
- package/native/tests/test_win32_accessibility.cpp +271 -0
- package/native/tests/test_win32_clipboard.cpp +121 -0
- package/native/tests/test_win32_focus.cpp +195 -0
- package/native/tests/test_win32_hittest.cpp +410 -0
- package/native/tests/test_win32_image.cpp +239 -0
- package/native/tests/test_win32_imageloader.cpp +208 -0
- package/native/tests/test_win32_input.cpp +361 -0
- package/native/tests/test_win32_key_events.cpp +84 -0
- package/native/tests/test_win32_mounting.cpp +410 -0
- package/native/tests/test_win32_paint.cpp +505 -0
- package/native/tests/test_win32_scrollview.cpp +385 -0
- package/native/tests/test_win32_text.cpp +258 -0
- package/native/tests/test_win32_textinput.cpp +609 -0
- package/native/tests/test_win32_titlebar.cpp +111 -0
- package/native/tests/test_win32_titlebar_actions.cpp +62 -0
- package/native/tests/test_win32_view.cpp +222 -0
- package/native/win32/ColorSchemeWin32.cpp +56 -0
- package/native/win32/ComponentRegistryWin32.cpp +124 -0
- package/native/win32/DirectWriteLayout.cpp +116 -0
- package/native/win32/DirectWriteLayout.h +36 -0
- package/native/win32/DirectWriteLayoutManager.cpp +124 -0
- package/native/win32/FontRegistryDirectWrite.cpp +117 -0
- package/native/win32/PlatformServicesWin32.cpp +643 -0
- package/native/win32/RnWin32Accessible.cpp +258 -0
- package/native/win32/RnWin32Accessible.h +91 -0
- package/native/win32/RnWin32Image.cpp +265 -0
- package/native/win32/RnWin32Image.h +93 -0
- package/native/win32/RnWin32TextLayout.cpp +310 -0
- package/native/win32/RnWin32TextLayout.h +160 -0
- package/native/win32/RnWin32View.cpp +1281 -0
- package/native/win32/RnWin32View.h +506 -0
- package/native/win32/Win32AnimationChoreographer.cpp +76 -0
- package/native/win32/Win32AnimationChoreographer.h +61 -0
- package/native/win32/Win32Clip.h +173 -0
- package/native/win32/Win32DropTarget.cpp +567 -0
- package/native/win32/Win32DropTarget.h +42 -0
- package/native/win32/Win32Focus.cpp +262 -0
- package/native/win32/Win32Focus.h +109 -0
- package/native/win32/Win32ImageLoader.cpp +167 -0
- package/native/win32/Win32ImageLoader.h +104 -0
- package/native/win32/Win32KeyEvents.cpp +126 -0
- package/native/win32/Win32KeyEvents.h +20 -0
- package/native/win32/Win32MenuBar.cpp +352 -0
- package/native/win32/Win32MenuBar.h +16 -0
- package/native/win32/Win32MountingManager.cpp +727 -0
- package/native/win32/Win32MountingManager.h +203 -0
- package/native/win32/Win32Packaging.cpp +161 -0
- package/native/win32/Win32Packaging.h +56 -0
- package/native/win32/Win32RunLoopObserver.cpp +48 -0
- package/native/win32/Win32RunLoopObserver.h +42 -0
- package/native/win32/Win32ScrollView.cpp +515 -0
- package/native/win32/Win32ScrollView.h +208 -0
- package/native/win32/Win32SkiaContext.cpp +221 -0
- package/native/win32/Win32SkiaContext.h +53 -0
- package/native/win32/Win32SkiaModule.cpp +80 -0
- package/native/win32/Win32SkiaModule.h +50 -0
- package/native/win32/Win32SkiaPeer.cpp +358 -0
- package/native/win32/Win32SkiaPeer.h +66 -0
- package/native/win32/Win32SkiaUnicode.cpp +42 -0
- package/native/win32/Win32Snapshot.cpp +201 -0
- package/native/win32/Win32Snapshot.h +66 -0
- package/native/win32/Win32Strings.h +54 -0
- package/native/win32/Win32TextInput.cpp +811 -0
- package/native/win32/Win32TextInput.h +232 -0
- package/native/win32/Win32TitleBar.cpp +562 -0
- package/native/win32/Win32TitleBar.h +146 -0
- package/native/win32/Win32TitleBarLayout.cpp +46 -0
- package/native/win32/Win32TitleBarLayout.h +58 -0
- package/native/win32/Win32TouchDispatcher.cpp +443 -0
- package/native/win32/Win32TouchDispatcher.h +153 -0
- package/native/win32/Win32UiThread.h +27 -0
- package/native/win32/Win32WindowControl.cpp +329 -0
- package/native/win32/Win32WindowModule.cpp +209 -0
- package/native/win32/Win32WindowModule.h +72 -0
- package/native/win32/demo_layout_win32.cpp +232 -0
- package/native/win32/main_win32.cpp +2481 -0
- package/native/win32/mount_harness_win32.cpp +316 -0
- package/package.json +26 -0
- 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
|