@shopify/react-native-skia 0.1.120 → 0.1.123

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 (111) hide show
  1. package/android/CMakeLists.txt +33 -17
  2. package/android/build.gradle +81 -34
  3. package/android/cpp/jni/JniSkiaDrawView.cpp +14 -71
  4. package/android/cpp/jni/JniSkiaManager.cpp +1 -1
  5. package/android/cpp/jni/include/JniSkiaDrawView.h +18 -22
  6. package/android/cpp/jni/include/JniSkiaManager.h +4 -4
  7. package/android/cpp/rnskia-android/RNSkDrawViewImpl.cpp +68 -0
  8. package/android/cpp/rnskia-android/RNSkDrawViewImpl.h +48 -0
  9. package/android/cpp/{jni/include/JniPlatformContextWrapper.h → rnskia-android/RNSkPlatformContextImpl.h} +4 -4
  10. package/android/cpp/{jni → rnskia-android}/SkiaOpenGLRenderer.cpp +39 -54
  11. package/android/cpp/{jni/include → rnskia-android}/SkiaOpenGLRenderer.h +2 -31
  12. package/android/src/main/java/com/shopify/reactnative/skia/PlatformContext.java +1 -1
  13. package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaViewManager.java +1 -1
  14. package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java +21 -28
  15. package/cpp/api/JsiSkApi.h +2 -0
  16. package/cpp/api/JsiSkColor.h +49 -0
  17. package/cpp/api/JsiSkPath.h +31 -2
  18. package/cpp/api/JsiSkPathFactory.h +96 -1
  19. package/cpp/api/third_party/CSSColorParser.h +324 -0
  20. package/cpp/rnskia/RNSkAnimation.h +4 -7
  21. package/cpp/rnskia/RNSkDrawView.cpp +77 -116
  22. package/cpp/rnskia/RNSkDrawView.h +5 -35
  23. package/cpp/rnskia/RNSkJsiViewApi.h +8 -5
  24. package/cpp/rnskia/RNSkManager.cpp +2 -2
  25. package/cpp/rnskia/RNSkManager.h +2 -2
  26. package/cpp/rnskia/RNSkPlatformContext.h +1 -1
  27. package/cpp/rnskia/values/RNSkClockValue.h +19 -11
  28. package/cpp/rnskia/values/RNSkDerivedValue.h +1 -1
  29. package/cpp/rnskia/values/RNSkReadonlyValue.h +15 -15
  30. package/cpp/utils/RNSkTimingInfo.h +13 -1
  31. package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +5 -7
  32. package/ios/RNSkia-iOS/RNSkDrawViewImpl.mm +25 -10
  33. package/ios/RNSkia-iOS/SkiaDrawView.mm +21 -15
  34. package/lib/commonjs/renderer/Canvas.js +3 -3
  35. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  36. package/lib/commonjs/renderer/components/Paint.js +1 -1
  37. package/lib/commonjs/renderer/components/Paint.js.map +1 -1
  38. package/lib/commonjs/renderer/components/shapes/Path.js +10 -2
  39. package/lib/commonjs/renderer/components/shapes/Path.js.map +1 -1
  40. package/lib/commonjs/renderer/nodes/Node.js +3 -3
  41. package/lib/commonjs/renderer/nodes/Node.js.map +1 -1
  42. package/lib/commonjs/renderer/processors/Paint.js +6 -1
  43. package/lib/commonjs/renderer/processors/Paint.js.map +1 -1
  44. package/lib/commonjs/skia/Color.js +3 -25
  45. package/lib/commonjs/skia/Color.js.map +1 -1
  46. package/lib/commonjs/skia/Image/Image.js.map +1 -1
  47. package/lib/commonjs/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
  48. package/lib/commonjs/skia/Paint/Paint.js +13 -1
  49. package/lib/commonjs/skia/Paint/Paint.js.map +1 -1
  50. package/lib/commonjs/skia/Paint/usePaint.js +2 -4
  51. package/lib/commonjs/skia/Paint/usePaint.js.map +1 -1
  52. package/lib/commonjs/skia/Path/Path.js +13 -1
  53. package/lib/commonjs/skia/Path/Path.js.map +1 -1
  54. package/lib/commonjs/skia/Shader/Shader.js.map +1 -1
  55. package/lib/commonjs/skia/Skia.js +43 -3
  56. package/lib/commonjs/skia/Skia.js.map +1 -1
  57. package/lib/module/renderer/Canvas.js +2 -2
  58. package/lib/module/renderer/Canvas.js.map +1 -1
  59. package/lib/module/renderer/components/Paint.js +2 -2
  60. package/lib/module/renderer/components/Paint.js.map +1 -1
  61. package/lib/module/renderer/components/shapes/Path.js +10 -3
  62. package/lib/module/renderer/components/shapes/Path.js.map +1 -1
  63. package/lib/module/renderer/nodes/Node.js +3 -3
  64. package/lib/module/renderer/nodes/Node.js.map +1 -1
  65. package/lib/module/renderer/processors/Paint.js +6 -1
  66. package/lib/module/renderer/processors/Paint.js.map +1 -1
  67. package/lib/module/skia/Color.js +2 -21
  68. package/lib/module/skia/Color.js.map +1 -1
  69. package/lib/module/skia/Image/Image.js.map +1 -1
  70. package/lib/module/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
  71. package/lib/module/skia/Paint/Paint.js +6 -0
  72. package/lib/module/skia/Paint/Paint.js.map +1 -1
  73. package/lib/module/skia/Paint/usePaint.js +2 -3
  74. package/lib/module/skia/Paint/usePaint.js.map +1 -1
  75. package/lib/module/skia/Path/Path.js +11 -0
  76. package/lib/module/skia/Path/Path.js.map +1 -1
  77. package/lib/module/skia/Shader/Shader.js.map +1 -1
  78. package/lib/module/skia/Skia.js +45 -2
  79. package/lib/module/skia/Skia.js.map +1 -1
  80. package/lib/typescript/src/renderer/components/shapes/Path.d.ts +3 -1
  81. package/lib/typescript/src/renderer/processors/Paint.d.ts +2 -1
  82. package/lib/typescript/src/skia/Color.d.ts +0 -1
  83. package/lib/typescript/src/skia/Image/Image.d.ts +3 -3
  84. package/lib/typescript/src/skia/ImageFilter/ImageFilterFactory.d.ts +2 -2
  85. package/lib/typescript/src/skia/Paint/Paint.d.ts +3 -2
  86. package/lib/typescript/src/skia/Path/Path.d.ts +13 -0
  87. package/lib/typescript/src/skia/Path/PathFactory.d.ts +7 -1
  88. package/lib/typescript/src/skia/Picture/Picture.d.ts +2 -2
  89. package/lib/typescript/src/skia/RuntimeEffect/RuntimeEffect.d.ts +3 -3
  90. package/lib/typescript/src/skia/Shader/Shader.d.ts +2 -2
  91. package/lib/typescript/src/skia/Shader/ShaderFactory.d.ts +9 -9
  92. package/lib/typescript/src/skia/Skia.d.ts +5 -3
  93. package/package.json +1 -1
  94. package/scripts/install-npm.js +1 -1
  95. package/src/renderer/Canvas.tsx +2 -2
  96. package/src/renderer/components/Paint.tsx +2 -2
  97. package/src/renderer/components/shapes/Path.tsx +12 -4
  98. package/src/renderer/nodes/Node.ts +3 -3
  99. package/src/renderer/processors/Paint.ts +5 -0
  100. package/src/skia/Color.ts +3 -20
  101. package/src/skia/Image/Image.ts +3 -3
  102. package/src/skia/ImageFilter/ImageFilterFactory.ts +2 -2
  103. package/src/skia/Paint/Paint.ts +9 -2
  104. package/src/skia/Paint/usePaint.ts +2 -4
  105. package/src/skia/Path/Path.ts +16 -0
  106. package/src/skia/Path/PathFactory.ts +8 -1
  107. package/src/skia/Picture/Picture.ts +2 -2
  108. package/src/skia/RuntimeEffect/RuntimeEffect.ts +4 -4
  109. package/src/skia/Shader/Shader.ts +2 -2
  110. package/src/skia/Shader/ShaderFactory.ts +9 -9
  111. package/src/skia/Skia.ts +47 -3
@@ -0,0 +1,324 @@
1
+ // (c) Dean McNamee <dean@gmail.com>, 2012.
2
+ // C++ port by Mapbox, Konstantin Käfer <mail@kkaefer.com>, 2014-2017.
3
+ //
4
+ // https://github.com/deanm/css-color-parser-js
5
+ // https://github.com/kkaefer/css-color-parser-cpp
6
+ //
7
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ // of this software and associated documentation files (the "Software"), to
9
+ // deal in the Software without restriction, including without limitation the
10
+ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11
+ // sell copies of the Software, and to permit persons to whom the Software is
12
+ // furnished to do so, subject to the following conditions:
13
+ //
14
+ // The above copyright notice and this permission notice shall be included in
15
+ // all copies or substantial portions of the Software.
16
+ //
17
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23
+ // IN THE SOFTWARE.
24
+
25
+ #pragma once
26
+
27
+ #include <cstdint>
28
+ #include <vector>
29
+ #include <sstream>
30
+ #include <algorithm>
31
+ #include <string>
32
+ #include <cmath>
33
+
34
+ namespace CSSColorParser {
35
+
36
+ struct Color {
37
+ inline Color() {
38
+ }
39
+ inline Color(unsigned char r_, unsigned char g_, unsigned char b_, float a_)
40
+ : r(r_), g(g_), b(b_), a(a_ > 1 ? 1 : a_ < 0 ? 0 : a_) {
41
+ }
42
+ unsigned char r = 0, g = 0, b = 0;
43
+ float a = -1.0f;
44
+ };
45
+
46
+ struct NamedColor { const char *const name; const Color color; };
47
+
48
+ const NamedColor namedColors[] = {
49
+ { "transparent", { 0, 0, 0, 0 } }, { "aliceblue", { 240, 248, 255, 1 } },
50
+ { "antiquewhite", { 250, 235, 215, 1 } }, { "aqua", { 0, 255, 255, 1 } },
51
+ { "aquamarine", { 127, 255, 212, 1 } }, { "azure", { 240, 255, 255, 1 } },
52
+ { "beige", { 245, 245, 220, 1 } }, { "bisque", { 255, 228, 196, 1 } },
53
+ { "black", { 0, 0, 0, 1 } }, { "blanchedalmond", { 255, 235, 205, 1 } },
54
+ { "blue", { 0, 0, 255, 1 } }, { "blueviolet", { 138, 43, 226, 1 } },
55
+ { "brown", { 165, 42, 42, 1 } }, { "burlywood", { 222, 184, 135, 1 } },
56
+ { "cadetblue", { 95, 158, 160, 1 } }, { "chartreuse", { 127, 255, 0, 1 } },
57
+ { "chocolate", { 210, 105, 30, 1 } }, { "coral", { 255, 127, 80, 1 } },
58
+ { "cornflowerblue", { 100, 149, 237, 1 } }, { "cornsilk", { 255, 248, 220, 1 } },
59
+ { "crimson", { 220, 20, 60, 1 } }, { "cyan", { 0, 255, 255, 1 } },
60
+ { "darkblue", { 0, 0, 139, 1 } }, { "darkcyan", { 0, 139, 139, 1 } },
61
+ { "darkgoldenrod", { 184, 134, 11, 1 } }, { "darkgray", { 169, 169, 169, 1 } },
62
+ { "darkgreen", { 0, 100, 0, 1 } }, { "darkgrey", { 169, 169, 169, 1 } },
63
+ { "darkkhaki", { 189, 183, 107, 1 } }, { "darkmagenta", { 139, 0, 139, 1 } },
64
+ { "darkolivegreen", { 85, 107, 47, 1 } }, { "darkorange", { 255, 140, 0, 1 } },
65
+ { "darkorchid", { 153, 50, 204, 1 } }, { "darkred", { 139, 0, 0, 1 } },
66
+ { "darksalmon", { 233, 150, 122, 1 } }, { "darkseagreen", { 143, 188, 143, 1 } },
67
+ { "darkslateblue", { 72, 61, 139, 1 } }, { "darkslategray", { 47, 79, 79, 1 } },
68
+ { "darkslategrey", { 47, 79, 79, 1 } }, { "darkturquoise", { 0, 206, 209, 1 } },
69
+ { "darkviolet", { 148, 0, 211, 1 } }, { "deeppink", { 255, 20, 147, 1 } },
70
+ { "deepskyblue", { 0, 191, 255, 1 } }, { "dimgray", { 105, 105, 105, 1 } },
71
+ { "dimgrey", { 105, 105, 105, 1 } }, { "dodgerblue", { 30, 144, 255, 1 } },
72
+ { "firebrick", { 178, 34, 34, 1 } }, { "floralwhite", { 255, 250, 240, 1 } },
73
+ { "forestgreen", { 34, 139, 34, 1 } }, { "fuchsia", { 255, 0, 255, 1 } },
74
+ { "gainsboro", { 220, 220, 220, 1 } }, { "ghostwhite", { 248, 248, 255, 1 } },
75
+ { "gold", { 255, 215, 0, 1 } }, { "goldenrod", { 218, 165, 32, 1 } },
76
+ { "gray", { 128, 128, 128, 1 } }, { "green", { 0, 128, 0, 1 } },
77
+ { "greenyellow", { 173, 255, 47, 1 } }, { "grey", { 128, 128, 128, 1 } },
78
+ { "honeydew", { 240, 255, 240, 1 } }, { "hotpink", { 255, 105, 180, 1 } },
79
+ { "indianred", { 205, 92, 92, 1 } }, { "indigo", { 75, 0, 130, 1 } },
80
+ { "ivory", { 255, 255, 240, 1 } }, { "khaki", { 240, 230, 140, 1 } },
81
+ { "lavender", { 230, 230, 250, 1 } }, { "lavenderblush", { 255, 240, 245, 1 } },
82
+ { "lawngreen", { 124, 252, 0, 1 } }, { "lemonchiffon", { 255, 250, 205, 1 } },
83
+ { "lightblue", { 173, 216, 230, 1 } }, { "lightcoral", { 240, 128, 128, 1 } },
84
+ { "lightcyan", { 224, 255, 255, 1 } }, { "lightgoldenrodyellow", { 250, 250, 210, 1 } },
85
+ { "lightgray", { 211, 211, 211, 1 } }, { "lightgreen", { 144, 238, 144, 1 } },
86
+ { "lightgrey", { 211, 211, 211, 1 } }, { "lightpink", { 255, 182, 193, 1 } },
87
+ { "lightsalmon", { 255, 160, 122, 1 } }, { "lightseagreen", { 32, 178, 170, 1 } },
88
+ { "lightskyblue", { 135, 206, 250, 1 } }, { "lightslategray", { 119, 136, 153, 1 } },
89
+ { "lightslategrey", { 119, 136, 153, 1 } }, { "lightsteelblue", { 176, 196, 222, 1 } },
90
+ { "lightyellow", { 255, 255, 224, 1 } }, { "lime", { 0, 255, 0, 1 } },
91
+ { "limegreen", { 50, 205, 50, 1 } }, { "linen", { 250, 240, 230, 1 } },
92
+ { "magenta", { 255, 0, 255, 1 } }, { "maroon", { 128, 0, 0, 1 } },
93
+ { "mediumaquamarine", { 102, 205, 170, 1 } }, { "mediumblue", { 0, 0, 205, 1 } },
94
+ { "mediumorchid", { 186, 85, 211, 1 } }, { "mediumpurple", { 147, 112, 219, 1 } },
95
+ { "mediumseagreen", { 60, 179, 113, 1 } }, { "mediumslateblue", { 123, 104, 238, 1 } },
96
+ { "mediumspringgreen", { 0, 250, 154, 1 } }, { "mediumturquoise", { 72, 209, 204, 1 } },
97
+ { "mediumvioletred", { 199, 21, 133, 1 } }, { "midnightblue", { 25, 25, 112, 1 } },
98
+ { "mintcream", { 245, 255, 250, 1 } }, { "mistyrose", { 255, 228, 225, 1 } },
99
+ { "moccasin", { 255, 228, 181, 1 } }, { "navajowhite", { 255, 222, 173, 1 } },
100
+ { "navy", { 0, 0, 128, 1 } }, { "oldlace", { 253, 245, 230, 1 } },
101
+ { "olive", { 128, 128, 0, 1 } }, { "olivedrab", { 107, 142, 35, 1 } },
102
+ { "orange", { 255, 165, 0, 1 } }, { "orangered", { 255, 69, 0, 1 } },
103
+ { "orchid", { 218, 112, 214, 1 } }, { "palegoldenrod", { 238, 232, 170, 1 } },
104
+ { "palegreen", { 152, 251, 152, 1 } }, { "paleturquoise", { 175, 238, 238, 1 } },
105
+ { "palevioletred", { 219, 112, 147, 1 } }, { "papayawhip", { 255, 239, 213, 1 } },
106
+ { "peachpuff", { 255, 218, 185, 1 } }, { "peru", { 205, 133, 63, 1 } },
107
+ { "pink", { 255, 192, 203, 1 } }, { "plum", { 221, 160, 221, 1 } },
108
+ { "powderblue", { 176, 224, 230, 1 } }, { "purple", { 128, 0, 128, 1 } },
109
+ { "red", { 255, 0, 0, 1 } }, { "rosybrown", { 188, 143, 143, 1 } },
110
+ { "royalblue", { 65, 105, 225, 1 } }, { "saddlebrown", { 139, 69, 19, 1 } },
111
+ { "salmon", { 250, 128, 114, 1 } }, { "sandybrown", { 244, 164, 96, 1 } },
112
+ { "seagreen", { 46, 139, 87, 1 } }, { "seashell", { 255, 245, 238, 1 } },
113
+ { "sienna", { 160, 82, 45, 1 } }, { "silver", { 192, 192, 192, 1 } },
114
+ { "skyblue", { 135, 206, 235, 1 } }, { "slateblue", { 106, 90, 205, 1 } },
115
+ { "slategray", { 112, 128, 144, 1 } }, { "slategrey", { 112, 128, 144, 1 } },
116
+ { "snow", { 255, 250, 250, 1 } }, { "springgreen", { 0, 255, 127, 1 } },
117
+ { "steelblue", { 70, 130, 180, 1 } }, { "tan", { 210, 180, 140, 1 } },
118
+ { "teal", { 0, 128, 128, 1 } }, { "thistle", { 216, 191, 216, 1 } },
119
+ { "tomato", { 255, 99, 71, 1 } }, { "turquoise", { 64, 224, 208, 1 } },
120
+ { "violet", { 238, 130, 238, 1 } }, { "wheat", { 245, 222, 179, 1 } },
121
+ { "white", { 255, 255, 255, 1 } }, { "whitesmoke", { 245, 245, 245, 1 } },
122
+ { "yellow", { 255, 255, 0, 1 } }, { "yellowgreen", { 154, 205, 50, 1 } }
123
+ };
124
+
125
+ template <typename T>
126
+ uint8_t clamp_css_byte(T i) { // Clamp to integer 0 .. 255.
127
+ i = ::round(i); // Seems to be what Chrome does (vs truncation).
128
+ return i < 0 ? 0 : i > 255 ? 255 : uint8_t(i);
129
+ }
130
+
131
+ template <typename T>
132
+ float clamp_css_float(T f) { // Clamp to float 0.0 .. 1.0.
133
+ return f < 0 ? 0 : f > 1 ? 1 : float(f);
134
+ }
135
+
136
+ float parseFloat(const std::string& str) {
137
+ return strtof(str.c_str(), nullptr);
138
+ }
139
+
140
+ int64_t parseInt(const std::string& str, uint8_t base = 10) {
141
+ return strtoll(str.c_str(), nullptr, base);
142
+ }
143
+
144
+ uint8_t parse_css_int(const std::string& str) { // int or percentage.
145
+ if (str.length() && str.back() == '%') {
146
+ return clamp_css_byte(parseFloat(str) / 100.0f * 255.0f);
147
+ } else {
148
+ return clamp_css_byte(parseInt(str));
149
+ }
150
+ }
151
+
152
+ float parse_css_float(const std::string& str) { // float or percentage.
153
+ if (str.length() && str.back() == '%') {
154
+ return clamp_css_float(parseFloat(str) / 100.0f);
155
+ } else {
156
+ return clamp_css_float(parseFloat(str));
157
+ }
158
+ }
159
+
160
+ float css_hue_to_rgb(float m1, float m2, float h) {
161
+ if (h < 0.0f) {
162
+ h += 1.0f;
163
+ } else if (h > 1.0f) {
164
+ h -= 1.0f;
165
+ }
166
+
167
+ if (h * 6.0f < 1.0f) {
168
+ return m1 + (m2 - m1) * h * 6.0f;
169
+ }
170
+ if (h * 2.0f < 1.0f) {
171
+ return m2;
172
+ }
173
+ if (h * 3.0f < 2.0f) {
174
+ return m1 + (m2 - m1) * (2.0f / 3.0f - h) * 6.0f;
175
+ }
176
+ return m1;
177
+ }
178
+
179
+ std::vector<std::string> split(const std::string& s, char delim) {
180
+ std::vector<std::string> elems;
181
+ std::stringstream ss(s);
182
+ std::string item;
183
+ while (std::getline(ss, item, delim)) {
184
+ elems.push_back(item);
185
+ }
186
+ return elems;
187
+ }
188
+
189
+
190
+ inline bool operator==(const Color& lhs, const Color& rhs) {
191
+ return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && ::fabs(lhs.a - rhs.a) < 0.0001f;
192
+ }
193
+
194
+ inline bool operator!=(const Color& lhs, const Color& rhs) {
195
+ return !(lhs == rhs);
196
+ }
197
+
198
+ Color parse(const std::string& css_str) {
199
+ std::string str = css_str;
200
+
201
+ // Remove all whitespace, not compliant, but should just be more accepting.
202
+ str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
203
+
204
+ // Convert to lowercase.
205
+ std::transform(str.begin(), str.end(), str.begin(), ::tolower);
206
+
207
+ for (const auto& namedColor : namedColors) {
208
+ if (str == namedColor.name) {
209
+ return { namedColor.color };
210
+ }
211
+ }
212
+
213
+ // #abc and #abc123 syntax.
214
+ if (str.length() && str.front() == '#') {
215
+ auto iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
216
+ if (str.length() == 4) {
217
+ if (!(iv >= 0 && iv <= 0xfff)) {
218
+ return {};
219
+ } else {
220
+ return {
221
+ static_cast<uint8_t>(((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8)),
222
+ static_cast<uint8_t>((iv & 0xf0) | ((iv & 0xf0) >> 4)),
223
+ static_cast<uint8_t>((iv & 0xf) | ((iv & 0xf) << 4)),
224
+ 1
225
+ };
226
+ }
227
+ } else if (str.length() == 7) {
228
+ if (!(iv >= 0 && iv <= 0xffffff)) {
229
+ return {}; // Covers NaN.
230
+ } else {
231
+ return {
232
+ static_cast<uint8_t>((iv & 0xff0000) >> 16),
233
+ static_cast<uint8_t>((iv & 0xff00) >> 8),
234
+ static_cast<uint8_t>(iv & 0xff),
235
+ 1
236
+ };
237
+ }
238
+ }else if (str.length() == 5) {
239
+ // #rgba
240
+ if (!(iv >= 0 && iv <= 0xffff)) return {}; // Covers NaN.
241
+ return {
242
+ static_cast<uint8_t>(((iv & 0xf000) >> 8) | ((iv & 0xf000) >> 12)),
243
+ static_cast<uint8_t>(((iv & 0x0f00) >> 4) | ((iv & 0x0f00) >> 8)),
244
+ static_cast<uint8_t>((iv & 0x00f0) | ((iv & 0x00f0) >> 4)),
245
+ static_cast<uint8_t>(((iv & 0x000f) << 4 | (iv & 0x000f))) / 255.0f
246
+ };
247
+ } else if (str.length() == 9) {
248
+ // #rrggbbaa
249
+ if (!(iv >= 0 && iv <= 0xffffffff)) return {}; // Covers NaN.
250
+ return {
251
+ static_cast<uint8_t>(((iv & 0xff000000) >> 24) & 0xff),
252
+ static_cast<uint8_t>((iv & 0x00ff0000) >> 16),
253
+ static_cast<uint8_t>((iv & 0x0000ff00) >> 8),
254
+ static_cast<uint8_t>((iv & 0x000000ff)) / 255.0f
255
+ };
256
+ }
257
+
258
+ return {};
259
+ }
260
+
261
+ size_t op = str.find_first_of('('), ep = str.find_first_of(')');
262
+ if (op != std::string::npos && ep + 1 == str.length()) {
263
+ const std::string fname = str.substr(0, op);
264
+ const std::vector<std::string> params = split(str.substr(op + 1, ep - (op + 1)), ',');
265
+
266
+ float alpha = 1.0f;
267
+
268
+ if (fname == "rgba" || fname == "rgb") {
269
+ if (fname == "rgba") {
270
+ if (params.size() != 4) {
271
+ return { };
272
+ }
273
+ alpha = parse_css_float(params.back());
274
+ } else {
275
+ if (params.size() != 3) {
276
+ return { };
277
+ }
278
+ }
279
+
280
+ return {
281
+ parse_css_int(params[0]),
282
+ parse_css_int(params[1]),
283
+ parse_css_int(params[2]),
284
+ alpha
285
+ };
286
+
287
+ } else if (fname == "hsla" || fname == "hsl") {
288
+ if (fname == "hsla") {
289
+ if (params.size() != 4) {
290
+ return { };
291
+ }
292
+ alpha = parse_css_float(params.back());
293
+ } else {
294
+ if (params.size() != 3) {
295
+ return { };
296
+ }
297
+ }
298
+
299
+ float h = parseFloat(params[0]) / 360.0f;
300
+ float i;
301
+ // Normalize the hue to [0..1[
302
+ h = std::modf(h, &i);
303
+
304
+ // NOTE(deanm): According to the CSS spec s/l should only be
305
+ // percentages, but we don't bother and let float or percentage.
306
+ float s = parse_css_float(params[1]);
307
+ float l = parse_css_float(params[2]);
308
+
309
+ float m2 = l <= 0.5f ? l * (s + 1.0f) : l + s - l * s;
310
+ float m1 = l * 2.0f - m2;
311
+
312
+ return {
313
+ clamp_css_byte(css_hue_to_rgb(m1, m2, h + 1.0f / 3.0f) * 255.0f),
314
+ clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255.0f),
315
+ clamp_css_byte(css_hue_to_rgb(m1, m2, h - 1.0f / 3.0f) * 255.0f),
316
+ alpha
317
+ };
318
+ }
319
+ }
320
+
321
+ return { };
322
+ }
323
+
324
+ } // namespace CSSColorParser
@@ -15,7 +15,7 @@ using namespace facebook;
15
15
  /**
16
16
  Implements an animation that can be used to drive other values
17
17
  */
18
- class RNSkAnimation : public RNSkClockValue, public std::enable_shared_from_this<RNSkAnimation>
18
+ class RNSkAnimation : public RNSkClockValue
19
19
  {
20
20
 
21
21
  public:
@@ -23,8 +23,8 @@ public:
23
23
  size_t identifier,
24
24
  jsi::Runtime& runtime,
25
25
  const jsi::Value *arguments,
26
- size_t count)
27
- : RNSkClockValue(platformContext, identifier, runtime, arguments, count) {
26
+ size_t count) :
27
+ RNSkClockValue(platformContext, identifier, runtime, arguments, count) {
28
28
  // Save the update function
29
29
  _updateFunction = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
30
30
 
@@ -32,10 +32,7 @@ public:
32
32
  _args[1] = jsi::Value::undefined();
33
33
  }
34
34
 
35
- ~RNSkAnimation() {
36
- // We need to stop/unsubscribe
37
- stopClock();
38
- }
35
+ virtual ~RNSkAnimation() {}
39
36
 
40
37
  JSI_HOST_FUNCTION(cancel) {
41
38
  stopClock();
@@ -40,31 +40,13 @@ RNSkDrawView::RNSkDrawView(std::shared_ptr<RNSkPlatformContext> context)
40
40
  _platformContext(std::move(context)),
41
41
  _infoObject(std::make_shared<RNSkInfoObject>()),
42
42
  _jsDrawingLock(std::make_shared<std::timed_mutex>()),
43
- _gpuDrawingLock(std::make_shared<std::timed_mutex>())
43
+ _gpuDrawingLock(std::make_shared<std::timed_mutex>()),
44
+ _jsTimingInfo("SKIA/JS"),
45
+ _gpuTimingInfo("SKIA/GPU")
44
46
  {}
45
47
 
46
48
  RNSkDrawView::~RNSkDrawView() {
47
- #if LOG_ALL_DRAWING
48
- RNSkLogger::logToConsole("RNSkDrawView::~RNSkDrawView - %i", getNativeId());
49
- #endif
50
-
51
- _isInvalidated = true;
52
-
53
49
  endDrawingLoop();
54
-
55
- // Wait for the drawing locks
56
- if(!_jsDrawingLock->try_lock_for(1250ms)) {
57
- RNSkLogger::logToConsole("Warning: JS drawing is still locked for native view with id %i", _nativeId);
58
- }
59
-
60
- if(!_gpuDrawingLock->try_lock_for(1250ms)) {
61
- RNSkLogger::logToConsole("Warning: SKIA drawing is still locked for native view with id %i", _nativeId);
62
- }
63
-
64
- onInvalidated();
65
-
66
- _jsDrawingLock = nullptr;
67
- _gpuDrawingLock = nullptr;
68
50
  }
69
51
 
70
52
  void RNSkDrawView::setNativeId(size_t nativeId) {
@@ -84,7 +66,6 @@ void RNSkDrawView::setDrawCallback(std::shared_ptr<jsi::Function> callback) {
84
66
  // Reset timing info
85
67
  _jsTimingInfo.reset();
86
68
  _gpuTimingInfo.reset();
87
- _vsyncTimingInfo.reset();
88
69
 
89
70
  // Set up debug font/paints
90
71
  auto font = SkFont();
@@ -94,53 +75,57 @@ void RNSkDrawView::setDrawCallback(std::shared_ptr<jsi::Function> callback) {
94
75
 
95
76
  // Create draw drawCallback wrapper
96
77
  _drawCallback = std::make_shared<RNSkDrawCallback>(
97
- [this, paint = std::move(paint), font = std::move(font), callback = std::move(callback)](std::shared_ptr<JsiSkCanvas> canvas, int width,
98
- int height, double timestamp,
99
- std::shared_ptr<RNSkPlatformContext> context) {
100
-
101
- auto runtime = context->getJsRuntime();
102
-
103
- // Update info parameter
104
- _infoObject->beginDrawOperation(width, height, timestamp);
105
-
106
- // Set up arguments array
107
- std::vector<jsi::Value> args(2);
108
- args[0] = jsi::Object::createFromHostObject(*runtime, canvas);
109
- args[1] = jsi::Object::createFromHostObject(*runtime, _infoObject);
110
-
111
- // To be able to call the drawing function we'll wrap it once again
112
- callback->call(*runtime,
113
- static_cast<const jsi::Value *>(args.data()),
114
- (size_t)2);
115
-
116
- // Reset touches
117
- _infoObject->endDrawOperation();
118
-
119
- // Draw debug overlays
120
- if (_showDebugOverlay) {
121
-
122
- // Display average rendering timer
123
- auto jsAvg = _jsTimingInfo.getAverage();
124
- //auto jsFps = _jsTimingInfo.getFps();
125
-
126
- auto gpuAvg = _gpuTimingInfo.getAverage();
127
- //auto gpuFps = _gpuTimingInfo.getFps();
128
-
129
- auto total = jsAvg + gpuAvg;
130
-
131
- //auto vsyncFps = _vsyncTimingInfo.getFps();
132
-
133
- // Build string
134
- std::ostringstream stream;
135
- stream << "js: " << jsAvg << "ms gpu: " << gpuAvg << "ms " << " total: " << total << "ms";
136
- // stream << "js:" << jsAvg << "ms/" << jsFps << "fps " << "gpu:" << gpuAvg << "ms/" <<
137
- // gpuFps << "fps" << " total:" << total << "ms/" << vsyncFps << "fps";
138
-
139
- std::string debugString = stream.str();
140
-
141
- canvas->getCanvas()->drawSimpleText(
142
- debugString.c_str(), debugString.size(), SkTextEncoding::kUTF8, 8,
143
- 18, font, paint);
78
+ [weakSelf = weak_from_this(),
79
+ paint = std::move(paint),
80
+ font = std::move(font),
81
+ callback = std::move(callback)](std::shared_ptr<JsiSkCanvas> canvas,
82
+ int width,
83
+ int height,
84
+ double timestamp,
85
+ std::shared_ptr<RNSkPlatformContext> context) {
86
+
87
+ auto self = weakSelf.lock();
88
+ if(self) {
89
+ auto runtime = context->getJsRuntime();
90
+
91
+ // Update info parameter
92
+ self->_infoObject->beginDrawOperation(width, height, timestamp);
93
+
94
+ // Set up arguments array
95
+ std::vector<jsi::Value> args(2);
96
+ args[0] = jsi::Object::createFromHostObject(*runtime, canvas);
97
+ args[1] = jsi::Object::createFromHostObject(*runtime, self->_infoObject);
98
+
99
+ // To be able to call the drawing function we'll wrap it once again
100
+ callback->call(*runtime,
101
+ static_cast<const jsi::Value *>(args.data()),
102
+ (size_t)2);
103
+
104
+ // Reset touches
105
+ self->_infoObject->endDrawOperation();
106
+
107
+ // Draw debug overlays
108
+ if (self->_showDebugOverlay) {
109
+
110
+ // Display average rendering timer
111
+ auto jsAvg = self->_jsTimingInfo.getAverage();
112
+ //auto jsFps = _jsTimingInfo.getFps();
113
+
114
+ auto gpuAvg = self->_gpuTimingInfo.getAverage();
115
+ //auto gpuFps = _gpuTimingInfo.getFps();
116
+
117
+ auto total = jsAvg + gpuAvg;
118
+
119
+ // Build string
120
+ std::ostringstream stream;
121
+ stream << "js: " << jsAvg << "ms gpu: " << gpuAvg << "ms " << " total: " << total << "ms";
122
+
123
+ std::string debugString = stream.str();
124
+
125
+ canvas->getCanvas()->drawSimpleText(
126
+ debugString.c_str(), debugString.size(), SkTextEncoding::kUTF8, 8,
127
+ 18, font, paint);
128
+ }
144
129
  }
145
130
  });
146
131
 
@@ -196,10 +181,6 @@ void RNSkDrawView::updateTouchState(std::vector<RNSkTouchPoint>&& points) {
196
181
  }
197
182
 
198
183
  void RNSkDrawView::performDraw() {
199
- #if LOG_ALL_DRAWING
200
- RNSkLogger::logToConsole("RNSkDrawView::performDraw - %i", getNativeId());
201
- #endif
202
-
203
184
  // Start timing
204
185
  _jsTimingInfo.beginTiming();
205
186
 
@@ -234,37 +215,22 @@ void RNSkDrawView::performDraw() {
234
215
  // Post drawing message to the render thread where the picture recorded
235
216
  // will be sent to the GPU/backend for rendering to screen.
236
217
  auto gpuLock = _gpuDrawingLock;
237
- getPlatformContext()->runOnRenderThread([this, p = std::move(p), gpuLock]() {
238
-
239
- if(isInvalidated()) {
240
- gpuLock->unlock();
241
- return;
218
+ _platformContext->runOnRenderThread([weakSelf = weak_from_this(), p = std::move(p), gpuLock]() {
219
+ auto self = weakSelf.lock();
220
+ if (self) {
221
+ // Draw the picture recorded on the real GPU canvas
222
+ self->_gpuTimingInfo.beginTiming();
223
+ self->drawPicture(p);
224
+ self->_gpuTimingInfo.stopTiming();
242
225
  }
243
-
244
- _gpuTimingInfo.beginTiming();
245
-
246
- // Draw the picture recorded on the real GPU canvas
247
- if(_nativeDrawFunc != nullptr) {
248
- #if LOG_ALL_DRAWING
249
- RNSkLogger::logToConsole("RNSkDrawView::drawFrame - %i", getNativeId());
250
- #endif
251
- _nativeDrawFunc(p);
252
- } else {
253
- #if LOG_ALL_DRAWING
254
- RNSkLogger::logToConsole("RNSkDrawView::drawFrame - %i SKIPPING, draw func is null", getNativeId());
255
- #endif
256
- }
257
-
258
- _gpuTimingInfo.stopTiming();
259
-
260
226
  // Unlock GPU drawing
261
227
  gpuLock->unlock();
262
228
  });
263
229
  } else {
264
230
  #ifdef DEBUG
265
- static size_t framesSkipped = 0;
266
- printf("SKIA/GPU: Skipped frames: %lu\n", ++framesSkipped);
231
+ _gpuTimingInfo.markSkipped();
267
232
  #endif
233
+ // Request a new redraw since the last frame was skipped.
268
234
  requestRedraw();
269
235
  }
270
236
 
@@ -280,39 +246,34 @@ void RNSkDrawView::beginDrawingLoop() {
280
246
  if (_drawingLoopId != 0 || _nativeId == 0) {
281
247
  return;
282
248
  }
283
-
284
249
  // Set to zero to avoid calling beginDrawLoop before we return
285
- _drawingLoopId = _platformContext->beginDrawLoop(
286
- _nativeId, std::bind(&RNSkDrawView::drawLoopCallback, this, std::placeholders::_1));
250
+ _drawingLoopId = _platformContext->beginDrawLoop(_nativeId,
251
+ [weakSelf = weak_from_this()](bool invalidated) {
252
+ auto self = weakSelf.lock();
253
+ if(self) {
254
+ self->drawLoopCallback(invalidated);
255
+ }
256
+ });
287
257
  }
288
258
 
289
259
  void RNSkDrawView::drawLoopCallback(bool invalidated) {
290
- if(invalidated) {
291
- _isInvalidated = true;
292
- onInvalidated();
293
- #if LOG_ALL_DRAWING
294
- RNSkLogger::logToConsole("RNSkDrawView::onInvalidated - %i", getNativeId());
295
- #endif
296
- return;
297
- }
298
-
299
260
  if(_redrawRequestCounter > 0 || _drawingMode == RNSkDrawingMode::Continuous) {
300
261
  _redrawRequestCounter = 0;
301
262
 
302
- _vsyncTimingInfo.beginTiming();
303
-
304
263
  // We render on the javascript thread.
305
264
  if(_jsDrawingLock->try_lock()) {
306
- _platformContext->runOnJavascriptThread(std::bind(&RNSkDrawView::performDraw, this));
265
+ _platformContext->runOnJavascriptThread([weakSelf = weak_from_this()](){
266
+ auto self = weakSelf.lock();
267
+ if(self) {
268
+ self->performDraw();
269
+ }
270
+ });
307
271
  } else {
308
272
  #ifdef DEBUG
309
- static size_t framesSkipped = 0;
310
- printf("SKIA/JS: Skipped frames: %lu\n", ++framesSkipped);
273
+ _jsTimingInfo.markSkipped();
311
274
  #endif
312
275
  requestRedraw();
313
276
  }
314
-
315
- _vsyncTimingInfo.stopTiming();
316
277
  }
317
278
  }
318
279