basalt-core 0.0.0-rc5 → 0.1.0
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/dist/cli/basalt.d.ts.map +1 -1
- package/dist/cli/basalt.js +18 -1
- package/dist/cli/basalt.js.map +1 -1
- package/dist/cli/bundle-cli.js +0 -0
- package/dist/cli/packageApp.d.ts.map +1 -1
- package/dist/cli/packageApp.js +7 -1
- package/dist/cli/packageApp.js.map +1 -1
- package/dist/metro-config.d.ts.map +1 -1
- package/dist/metro-config.js +53 -5
- package/dist/metro-config.js.map +1 -1
- package/dist/src/KeyHandler.d.ts +1 -1
- package/dist/src/KeyHandler.d.ts.map +1 -1
- package/dist/src/KeyHandler.js.map +1 -1
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/overrides/Alert.d.ts +1 -1
- package/dist/src/overrides/Alert.js +1 -1
- package/dist/src/overrides/BaseViewConfig.d.ts +10 -3
- package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -1
- package/dist/src/overrides/BaseViewConfig.js +21 -3
- package/dist/src/overrides/BaseViewConfig.js.map +1 -1
- package/dist/src/overrides/Button.d.ts +81 -0
- package/dist/src/overrides/Button.d.ts.map +1 -0
- package/dist/src/overrides/Button.js +109 -0
- package/dist/src/overrides/Button.js.map +1 -0
- package/dist/src/overrides/ScrollView.d.ts +25 -2
- package/dist/src/overrides/ScrollView.d.ts.map +1 -1
- package/dist/src/overrides/ScrollView.js +64 -7
- package/dist/src/overrides/ScrollView.js.map +1 -1
- package/dist/src/overrides/Settings.d.ts +81 -0
- package/dist/src/overrides/Settings.d.ts.map +1 -0
- package/dist/src/overrides/Settings.js +120 -0
- package/dist/src/overrides/Settings.js.map +1 -0
- package/dist/src/overrides/processDecelerationRate.d.ts +20 -0
- package/dist/src/overrides/processDecelerationRate.d.ts.map +1 -0
- package/dist/src/overrides/processDecelerationRate.js +31 -0
- package/dist/src/overrides/processDecelerationRate.js.map +1 -0
- package/dist/src/useContextMenu.d.ts +57 -6
- package/dist/src/useContextMenu.d.ts.map +1 -1
- package/dist/src/useContextMenu.js +34 -1
- package/dist/src/useContextMenu.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/native/CMakeLists.txt +51 -0
- package/native/core/ActionSheet.cpp +75 -0
- package/native/core/ActionSheet.h +90 -0
- package/native/core/AppStateHost.cpp +76 -0
- package/native/core/AppStateHost.h +68 -0
- package/native/core/BackgroundLayers.h +282 -0
- package/native/core/BlendModes.h +67 -0
- package/native/core/CoreModules.cpp +380 -11
- package/native/core/CoreModules.h +140 -4
- package/native/core/CrashHandler.cpp +246 -0
- package/native/core/CrashHandler.h +65 -0
- package/native/core/CursorNames.h +110 -0
- package/native/core/DevMenu.cpp +6 -5
- package/native/core/DeviceMetrics.cpp +87 -0
- package/native/core/DeviceMetrics.h +80 -0
- package/native/core/Filters.h +336 -0
- package/native/core/FontFitting.h +183 -0
- package/native/core/FontScaling.h +153 -0
- package/native/core/FontVariants.h +148 -0
- package/native/core/Gradients.h +523 -0
- package/native/core/ImageAnimation.h +109 -0
- package/native/core/ImageBytes.cpp +28 -1
- package/native/core/ImageBytes.h +17 -1
- package/native/core/ImageProgress.h +85 -0
- package/native/core/LabelRegistry.h +189 -0
- package/native/core/LegacyShadow.h +90 -0
- package/native/core/LiveRegions.h +114 -0
- package/native/core/MenuModule.cpp +35 -4
- package/native/core/MountingWalk.h +125 -2
- package/native/core/PlatformServices.h +187 -3
- package/native/core/SafeAreaComponent.cpp +115 -0
- package/native/core/SafeAreaComponent.h +105 -0
- package/native/core/ScreensComponent.cpp +201 -0
- package/native/core/ScreensComponent.h +216 -0
- package/native/core/ScrollBounds.cpp +8 -0
- package/native/core/ScrollBounds.h +14 -0
- package/native/core/ScrollIndicator.h +67 -0
- package/native/core/ScrollMomentum.cpp +24 -0
- package/native/core/ScrollMomentum.h +14 -0
- package/native/core/ScrollSnap.cpp +121 -12
- package/native/core/ScrollSnap.h +45 -0
- package/native/core/ScrollVisiblePosition.cpp +68 -0
- package/native/core/ScrollVisiblePosition.h +101 -0
- package/native/core/SettingsStore.cpp +199 -0
- package/native/core/SettingsStore.h +127 -0
- package/native/core/ShadowShape.h +38 -0
- package/native/core/SystemLocale.cpp +103 -0
- package/native/core/SystemLocale.h +86 -0
- package/native/core/TestDialog.cpp +45 -6
- package/native/core/TestDialog.h +15 -0
- package/native/core/TextAlignments.h +240 -0
- package/native/core/TextChecking.h +133 -0
- package/native/core/TextColors.h +83 -0
- package/native/core/TextDecorations.h +101 -0
- package/native/core/TextDirection.cpp +242 -0
- package/native/core/TextDirection.h +88 -0
- package/native/core/TextHighlight.h +30 -0
- package/native/core/TextSelection.cpp +97 -0
- package/native/core/TextSelection.h +161 -0
- package/native/core/TextShadows.h +96 -0
- package/native/core/TextVerticalAlign.h +33 -0
- package/native/core/UIManagerAccess.cpp +36 -0
- package/native/core/UIManagerAccess.h +28 -0
- package/native/core/WindowBoundsCache.cpp +58 -1
- package/native/core/WindowControl.h +24 -0
- package/native/core/WritingDirections.h +52 -0
- package/native/core/portability_probe.cpp +7 -0
- package/native/tests/RenamedFontFile.h +161 -0
- package/native/tests/TestHarness.cpp +18 -0
- package/native/tests/test_action_sheet.cpp +157 -0
- package/native/tests/test_app_state.cpp +60 -0
- package/native/tests/test_background_layers.cpp +281 -0
- package/native/tests/test_blend_modes.cpp +79 -0
- package/native/tests/test_blobs.cpp +1 -1
- package/native/tests/test_device_metrics.cpp +126 -0
- package/native/tests/test_filters.cpp +271 -0
- package/native/tests/test_font_fitting.cpp +172 -0
- package/native/tests/test_font_scaling.cpp +127 -0
- package/native/tests/test_font_variants.cpp +84 -0
- package/native/tests/test_gradients.cpp +390 -0
- package/native/tests/test_image_animation.cpp +105 -0
- package/native/tests/test_image_progress.cpp +94 -0
- package/native/tests/test_label_registry.cpp +262 -0
- package/native/tests/test_legacy_shadow.cpp +165 -0
- package/native/tests/test_live_regions.cpp +108 -0
- package/native/tests/test_menu_entries.cpp +192 -0
- package/native/tests/test_momentum.cpp +45 -0
- package/native/tests/test_scroll_bounds.cpp +42 -0
- package/native/tests/test_scroll_indicator.cpp +61 -0
- package/native/tests/test_scroll_snap.cpp +129 -0
- package/native/tests/test_scroll_visible_position.cpp +121 -0
- package/native/tests/test_settings_store.cpp +257 -0
- package/native/tests/test_shadow_shape.cpp +47 -0
- package/native/tests/test_system_locale.cpp +36 -0
- package/native/tests/test_text_alignment.cpp +299 -0
- package/native/tests/test_text_checking.cpp +31 -0
- package/native/tests/test_text_colors.cpp +92 -0
- package/native/tests/test_text_decorations.cpp +100 -0
- package/native/tests/test_text_selection.cpp +168 -0
- package/native/tests/test_text_shadows.cpp +132 -0
- package/package.json +4 -2
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// Where a `backgroundImage` is painted, how big it is, and how it tiles.
|
|
2
|
+
//
|
|
3
|
+
// `backgroundSize`, `backgroundPosition` and `backgroundRepeat` reach every host
|
|
4
|
+
// and were ignored by all three, on a note that said they had "nothing to act on
|
|
5
|
+
// until an image can be a background". That was wrong: CSS treats a gradient as
|
|
6
|
+
// an image, so all three apply to the gradients both desktops already draw, and
|
|
7
|
+
// React Native's iOS half applies them to exactly those.
|
|
8
|
+
//
|
|
9
|
+
// ## The two areas, which is the part that is easy to get wrong
|
|
10
|
+
//
|
|
11
|
+
// CSS gives a background two rectangles. The *positioning area* is what a size
|
|
12
|
+
// and a position are resolved against, and it is the padding box --
|
|
13
|
+
// `background-origin: padding-box`, which is CSS's default and what iOS passes.
|
|
14
|
+
// The *painting area* is what the result is clipped to, and it is the border box
|
|
15
|
+
// -- `background-clip: border-box`, also the default. They differ on any view
|
|
16
|
+
// with a border, and a gradient that ignores the difference paints under the
|
|
17
|
+
// border when it should tile into it.
|
|
18
|
+
//
|
|
19
|
+
// ## Why this is shared
|
|
20
|
+
//
|
|
21
|
+
// Every number here is specified and none is obvious: percentages resolve
|
|
22
|
+
// against the area and not the image, `right: 25%` is not `left: 25%` because
|
|
23
|
+
// the available space is the area minus the image, `round` changes the tile size
|
|
24
|
+
// before anything tiles, and `space` changes the step and the anchor but not the
|
|
25
|
+
// size. It is ported from `RCTBackgroundImageUtils.mm`, so the same stylesheet is
|
|
26
|
+
// the same picture on all three platforms, and asserted against the spec's own
|
|
27
|
+
// numbers in core's tests.
|
|
28
|
+
//
|
|
29
|
+
// Header-only, like core/Gradients.h, and included by the mounting managers.
|
|
30
|
+
|
|
31
|
+
#pragma once
|
|
32
|
+
|
|
33
|
+
#include <react/renderer/graphics/BackgroundPosition.h>
|
|
34
|
+
#include <react/renderer/graphics/BackgroundRepeat.h>
|
|
35
|
+
#include <react/renderer/graphics/BackgroundSize.h>
|
|
36
|
+
|
|
37
|
+
#include <cmath>
|
|
38
|
+
#include <cstddef>
|
|
39
|
+
#include <variant>
|
|
40
|
+
#include <vector>
|
|
41
|
+
|
|
42
|
+
namespace basalt {
|
|
43
|
+
|
|
44
|
+
// One entry of each of the three lists, for an image at `index`.
|
|
45
|
+
//
|
|
46
|
+
// CSS repeats a list that is shorter than the image list, so the lists are
|
|
47
|
+
// indexed modulo their own length -- which is what iOS does. An empty list is
|
|
48
|
+
// the prop's default: the whole positioning area, the top left corner, and
|
|
49
|
+
// repeat in both axes, all of which come from React Native's own constructors.
|
|
50
|
+
inline facebook::react::BackgroundSize backgroundSizeAt(
|
|
51
|
+
const std::vector<facebook::react::BackgroundSize> &sizes, size_t index) {
|
|
52
|
+
if (sizes.empty()) {
|
|
53
|
+
return facebook::react::BackgroundSizeLengthPercentage{};
|
|
54
|
+
}
|
|
55
|
+
return sizes[index % sizes.size()];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
inline facebook::react::BackgroundPosition backgroundPositionAt(
|
|
59
|
+
const std::vector<facebook::react::BackgroundPosition> &positions, size_t index) {
|
|
60
|
+
if (positions.empty()) {
|
|
61
|
+
return facebook::react::BackgroundPosition{};
|
|
62
|
+
}
|
|
63
|
+
return positions[index % positions.size()];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
inline facebook::react::BackgroundRepeat backgroundRepeatAt(
|
|
67
|
+
const std::vector<facebook::react::BackgroundRepeat> &repeats, size_t index) {
|
|
68
|
+
if (repeats.empty()) {
|
|
69
|
+
return facebook::react::BackgroundRepeat{};
|
|
70
|
+
}
|
|
71
|
+
return repeats[index % repeats.size()];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A rectangle in the view's own coordinates, y down.
|
|
75
|
+
struct BackgroundArea {
|
|
76
|
+
float x{0.0F};
|
|
77
|
+
float y{0.0F};
|
|
78
|
+
float width{0.0F};
|
|
79
|
+
float height{0.0F};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// One resolved background image: the rectangle the image itself fills, and the
|
|
83
|
+
// tile it repeats in.
|
|
84
|
+
//
|
|
85
|
+
// The tile is what a host repeats: its origin is the first tile's, and its size
|
|
86
|
+
// is the period -- the image's size for `repeat` and `round`, the image plus the
|
|
87
|
+
// gap for `space`. On an axis that does not repeat, the tile is the painting
|
|
88
|
+
// area's extent on that axis, so a host that tiles in both directions at once --
|
|
89
|
+
// which is what `gtk_snapshot_push_repeat` does -- gets one row or one column
|
|
90
|
+
// without a special case, and a host that loops gets one iteration.
|
|
91
|
+
struct BackgroundLayer {
|
|
92
|
+
float x{0.0F};
|
|
93
|
+
float y{0.0F};
|
|
94
|
+
float width{0.0F};
|
|
95
|
+
float height{0.0F};
|
|
96
|
+
|
|
97
|
+
float tileX{0.0F};
|
|
98
|
+
float tileY{0.0F};
|
|
99
|
+
float tileWidth{0.0F};
|
|
100
|
+
float tileHeight{0.0F};
|
|
101
|
+
|
|
102
|
+
bool repeatsX{false};
|
|
103
|
+
bool repeatsY{false};
|
|
104
|
+
|
|
105
|
+
bool repeats() const { return repeatsX || repeatsY; }
|
|
106
|
+
// Nothing to paint: an empty area, or a size resolved to nothing.
|
|
107
|
+
bool empty() const { return width <= 0.0F || height <= 0.0F; }
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
namespace detail {
|
|
111
|
+
|
|
112
|
+
// One axis of `background-size`: a length as itself, a percentage of the area,
|
|
113
|
+
// and `auto` as the area. A gradient has no intrinsic size of its own, so CSS's
|
|
114
|
+
// answer for `auto` is the positioning area -- which is also why `cover` and
|
|
115
|
+
// `contain` come to the same thing here and are left alone, as iOS leaves them.
|
|
116
|
+
inline float backgroundExtent(
|
|
117
|
+
const std::variant<std::monostate, facebook::react::ValueUnit> &value, float area) {
|
|
118
|
+
if (!std::holds_alternative<facebook::react::ValueUnit>(value)) {
|
|
119
|
+
return area;
|
|
120
|
+
}
|
|
121
|
+
const auto unit = std::get<facebook::react::ValueUnit>(value);
|
|
122
|
+
if (unit.unit == facebook::react::UnitType::Percent) {
|
|
123
|
+
return unit.value * area / 100.0F;
|
|
124
|
+
}
|
|
125
|
+
return unit.value;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// `round` divides the area into a whole number of tiles, nearest to the size
|
|
129
|
+
// that was asked for. Applied before the position, because it changes the size.
|
|
130
|
+
inline float roundedExtent(float item, float area) {
|
|
131
|
+
if (item <= 0.0F || area <= 0.0F) {
|
|
132
|
+
return item;
|
|
133
|
+
}
|
|
134
|
+
if (std::fmod(area, item) == 0.0F) {
|
|
135
|
+
return item;
|
|
136
|
+
}
|
|
137
|
+
const float divisor = std::round(area / item);
|
|
138
|
+
return divisor > 0.0F ? area / divisor : item;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Where the image sits on one axis. The offsets resolve against the *available*
|
|
142
|
+
// space, which is the area minus the image: that is what makes `left: 100%` the
|
|
143
|
+
// right edge rather than off the end, and `right: 25%` a quarter in from the
|
|
144
|
+
// other side.
|
|
145
|
+
//
|
|
146
|
+
// **The far edge wins when it is present, which is deliberately not what iOS
|
|
147
|
+
// does.** `BackgroundPosition`'s constructor sets `top` and `left` to zero, and
|
|
148
|
+
// React Native's prop parser only *writes* the keys the style sent -- so
|
|
149
|
+
// `background-position: right 25% bottom 10%` arrives as right and bottom set
|
|
150
|
+
// *and* top and left still at their defaults. iOS asks for `top` and `left`
|
|
151
|
+
// first, finds the defaults, and draws the image in the corner: the far-edge
|
|
152
|
+
// syntax cannot be expressed on that platform. See backlog/upstream.md.
|
|
153
|
+
//
|
|
154
|
+
// Preferring the far edge is right for every case the JavaScript side can
|
|
155
|
+
// produce, because `processBackgroundPosition.js` emits exactly one of each pair
|
|
156
|
+
// -- `{top, left}`, `{bottom, right}`, `{top, right}` or `{bottom, left}` -- so a
|
|
157
|
+
// `right` in the map means the `left` beside it is React Native's default and
|
|
158
|
+
// not the author's.
|
|
159
|
+
//
|
|
160
|
+
// `nearEdge` and `farEdge` rather than `near` and `far`, which is not a style
|
|
161
|
+
// choice: `windows.h` defines both of those as empty macros, left over from the
|
|
162
|
+
// 16-bit memory model, so the obvious names turn into nothing at all wherever
|
|
163
|
+
// this header is used from a Windows translation unit. That cost a red build
|
|
164
|
+
// the day the Win32 host started drawing gradients -- the two other hosts had
|
|
165
|
+
// compiled it for days -- and the error is `expected expression` on a line that
|
|
166
|
+
// looks perfectly ordinary.
|
|
167
|
+
inline float backgroundOffset(const std::optional<facebook::react::ValueUnit> &nearEdge,
|
|
168
|
+
const std::optional<facebook::react::ValueUnit> &farEdge,
|
|
169
|
+
float areaOrigin,
|
|
170
|
+
float available) {
|
|
171
|
+
if (farEdge.has_value()) {
|
|
172
|
+
return areaOrigin + (available - farEdge->resolve(available));
|
|
173
|
+
}
|
|
174
|
+
if (nearEdge.has_value()) {
|
|
175
|
+
return areaOrigin + nearEdge->resolve(available);
|
|
176
|
+
}
|
|
177
|
+
return areaOrigin;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// One axis of the tiling: the period, the first tile's origin, and whether it
|
|
181
|
+
// repeats at all. `space` is the one that moves the anchor, because the first
|
|
182
|
+
// and last tiles touch the edges of the area with the gaps shared between them.
|
|
183
|
+
struct AxisTiling {
|
|
184
|
+
float origin;
|
|
185
|
+
float period;
|
|
186
|
+
bool repeats;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
inline AxisTiling axisTiling(facebook::react::BackgroundRepeatStyle style,
|
|
190
|
+
float imageOrigin,
|
|
191
|
+
float imageExtent,
|
|
192
|
+
float areaOrigin,
|
|
193
|
+
float areaExtent,
|
|
194
|
+
float paintingOrigin,
|
|
195
|
+
float paintingExtent) {
|
|
196
|
+
using facebook::react::BackgroundRepeatStyle;
|
|
197
|
+
if (style == BackgroundRepeatStyle::NoRepeat || imageExtent <= 0.0F) {
|
|
198
|
+
return AxisTiling{paintingOrigin, paintingExtent, false};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
float period = imageExtent;
|
|
202
|
+
float origin = imageOrigin;
|
|
203
|
+
|
|
204
|
+
if (style == BackgroundRepeatStyle::Space) {
|
|
205
|
+
const float fits = std::floor(areaExtent / imageExtent);
|
|
206
|
+
if (fits <= 1.0F) {
|
|
207
|
+
// One tile does not leave a gap to share, so there is nothing to space.
|
|
208
|
+
return AxisTiling{paintingOrigin, paintingExtent, false};
|
|
209
|
+
}
|
|
210
|
+
// The gaps are shared between the tiles, and the first tile is flush with
|
|
211
|
+
// the area rather than wherever the position put it: that is what `space`
|
|
212
|
+
// means, and it is why the position is overridden here.
|
|
213
|
+
period = imageExtent + (areaExtent - fits * imageExtent) / (fits - 1.0F);
|
|
214
|
+
origin = areaOrigin;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Back up to the first tile that can reach the painting area, so a host that
|
|
218
|
+
// steps forward covers everything rather than starting mid-pattern.
|
|
219
|
+
const float before = std::ceil((origin - paintingOrigin) / period);
|
|
220
|
+
origin -= before * period;
|
|
221
|
+
return AxisTiling{origin, period, true};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
} // namespace detail
|
|
225
|
+
|
|
226
|
+
// The whole thing: an image's rectangle and its tile, from the three props and
|
|
227
|
+
// the two areas.
|
|
228
|
+
inline BackgroundLayer resolveBackgroundLayer(
|
|
229
|
+
const BackgroundArea &positioning,
|
|
230
|
+
const BackgroundArea &painting,
|
|
231
|
+
const facebook::react::BackgroundSize &size,
|
|
232
|
+
const facebook::react::BackgroundPosition &position,
|
|
233
|
+
const facebook::react::BackgroundRepeat &repeat) {
|
|
234
|
+
BackgroundLayer layer;
|
|
235
|
+
if (positioning.width <= 0.0F || positioning.height <= 0.0F || painting.width <= 0.0F ||
|
|
236
|
+
painting.height <= 0.0F) {
|
|
237
|
+
return layer;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// The size, which is the area unless the stylesheet said otherwise.
|
|
241
|
+
float width = positioning.width;
|
|
242
|
+
float height = positioning.height;
|
|
243
|
+
if (std::holds_alternative<facebook::react::BackgroundSizeLengthPercentage>(size)) {
|
|
244
|
+
const auto &lengths = std::get<facebook::react::BackgroundSizeLengthPercentage>(size);
|
|
245
|
+
width = detail::backgroundExtent(lengths.x, positioning.width);
|
|
246
|
+
height = detail::backgroundExtent(lengths.y, positioning.height);
|
|
247
|
+
}
|
|
248
|
+
if (repeat.x == facebook::react::BackgroundRepeatStyle::Round) {
|
|
249
|
+
width = detail::roundedExtent(width, positioning.width);
|
|
250
|
+
}
|
|
251
|
+
if (repeat.y == facebook::react::BackgroundRepeatStyle::Round) {
|
|
252
|
+
height = detail::roundedExtent(height, positioning.height);
|
|
253
|
+
}
|
|
254
|
+
if (width <= 0.0F || height <= 0.0F) {
|
|
255
|
+
return layer;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// The position, against the space the image leaves.
|
|
259
|
+
const float x = detail::backgroundOffset(
|
|
260
|
+
position.left, position.right, positioning.x, positioning.width - width);
|
|
261
|
+
const float y = detail::backgroundOffset(
|
|
262
|
+
position.top, position.bottom, positioning.y, positioning.height - height);
|
|
263
|
+
|
|
264
|
+
const detail::AxisTiling across = detail::axisTiling(
|
|
265
|
+
repeat.x, x, width, positioning.x, positioning.width, painting.x, painting.width);
|
|
266
|
+
const detail::AxisTiling down = detail::axisTiling(
|
|
267
|
+
repeat.y, y, height, positioning.y, positioning.height, painting.y, painting.height);
|
|
268
|
+
|
|
269
|
+
layer.x = across.repeats ? across.origin : x;
|
|
270
|
+
layer.y = down.repeats ? down.origin : y;
|
|
271
|
+
layer.width = width;
|
|
272
|
+
layer.height = height;
|
|
273
|
+
layer.tileX = across.origin;
|
|
274
|
+
layer.tileY = down.origin;
|
|
275
|
+
layer.tileWidth = across.period;
|
|
276
|
+
layer.tileHeight = down.period;
|
|
277
|
+
layer.repeatsX = across.repeats;
|
|
278
|
+
layer.repeatsY = down.repeats;
|
|
279
|
+
return layer;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
} // namespace basalt
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// What a React Native `mixBlendMode` value is called, in CSS's own words.
|
|
2
|
+
//
|
|
3
|
+
// ## Why a name rather than a per-host enum
|
|
4
|
+
//
|
|
5
|
+
// The same reason `cursor` crosses the seam as a keyword, in core/CursorNames.h:
|
|
6
|
+
// React Native's `BlendMode` is CSS's list, and so is every host's. GSK has a
|
|
7
|
+
// `GskBlendMode` per CSS mode bar one; Core Image has a `CI<Name>BlendMode`
|
|
8
|
+
// filter per CSS mode, including that one. Keeping the keyword as the thing that
|
|
9
|
+
// crosses means one place says what `mixBlendMode: 'color-dodge'` is called, and
|
|
10
|
+
// each view layer answers for its own compositor.
|
|
11
|
+
//
|
|
12
|
+
// The names are the CSS property's values, hyphenated as CSS writes them, which
|
|
13
|
+
// is also how React Native's own `blendModeFromString` spells them.
|
|
14
|
+
//
|
|
15
|
+
// Header-only and in core because both mounting managers need it and both know
|
|
16
|
+
// React Native; the view layers do not, and they take a string.
|
|
17
|
+
|
|
18
|
+
#pragma once
|
|
19
|
+
|
|
20
|
+
#include <react/renderer/graphics/BlendMode.h>
|
|
21
|
+
|
|
22
|
+
namespace basalt {
|
|
23
|
+
|
|
24
|
+
// The CSS keyword, or nullptr for "nothing to apply", which is `normal`: the
|
|
25
|
+
// default, and the only value that asks for ordinary source-over compositing.
|
|
26
|
+
inline const char *blendModeName(facebook::react::BlendMode mode) {
|
|
27
|
+
using facebook::react::BlendMode;
|
|
28
|
+
switch (mode) {
|
|
29
|
+
case BlendMode::Normal:
|
|
30
|
+
return nullptr;
|
|
31
|
+
case BlendMode::Multiply:
|
|
32
|
+
return "multiply";
|
|
33
|
+
case BlendMode::Screen:
|
|
34
|
+
return "screen";
|
|
35
|
+
case BlendMode::Overlay:
|
|
36
|
+
return "overlay";
|
|
37
|
+
case BlendMode::Darken:
|
|
38
|
+
return "darken";
|
|
39
|
+
case BlendMode::Lighten:
|
|
40
|
+
return "lighten";
|
|
41
|
+
case BlendMode::ColorDodge:
|
|
42
|
+
return "color-dodge";
|
|
43
|
+
case BlendMode::ColorBurn:
|
|
44
|
+
return "color-burn";
|
|
45
|
+
case BlendMode::HardLight:
|
|
46
|
+
return "hard-light";
|
|
47
|
+
case BlendMode::SoftLight:
|
|
48
|
+
return "soft-light";
|
|
49
|
+
case BlendMode::Difference:
|
|
50
|
+
return "difference";
|
|
51
|
+
case BlendMode::Exclusion:
|
|
52
|
+
return "exclusion";
|
|
53
|
+
case BlendMode::Hue:
|
|
54
|
+
return "hue";
|
|
55
|
+
case BlendMode::Saturation:
|
|
56
|
+
return "saturation";
|
|
57
|
+
case BlendMode::Color:
|
|
58
|
+
return "color";
|
|
59
|
+
case BlendMode::Luminosity:
|
|
60
|
+
return "luminosity";
|
|
61
|
+
case BlendMode::PlusLighter:
|
|
62
|
+
return "plus-lighter";
|
|
63
|
+
}
|
|
64
|
+
return nullptr;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
} // namespace basalt
|