@shopify/react-native-skia 0.1.211 → 0.1.213

Sign up to get free protection for your applications and to get access to all the features.
@@ -113,6 +113,11 @@ buildscript {
113
113
  }
114
114
 
115
115
  android {
116
+ def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
117
+ if (agpVersion.tokenize('.')[0].toInteger() >= 7) {
118
+ namespace "com.shopify.reactnative.skia"
119
+ }
120
+
116
121
  compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
117
122
  buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION)
118
123
  defaultConfig {
@@ -27,6 +27,7 @@
27
27
  #include "SkStrokeRec.h"
28
28
  #include "SkTextUtils.h"
29
29
  #include "SkTrimPathEffect.h"
30
+ #include "src/core/SkPathPriv.h"
30
31
 
31
32
  #pragma clang diagnostic pop
32
33
 
@@ -36,6 +37,13 @@ namespace jsi = facebook::jsi;
36
37
 
37
38
  class JsiSkPath : public JsiSkWrappingSharedPtrHostObject<SkPath> {
38
39
  private:
40
+ static const int MOVE = 0;
41
+ static const int LINE = 1;
42
+ static const int QUAD = 2;
43
+ static const int CONIC = 3;
44
+ static const int CUBIC = 4;
45
+ static const int CLOSE = 5;
46
+
39
47
  float pinT(double value) {
40
48
  // Clamp the double value between 0 and 1 and then cast it to float
41
49
  return static_cast<float>(std::clamp(value, 0.0, 1.0));
@@ -498,30 +506,66 @@ public:
498
506
  JSI_HOST_FUNCTION(toCmds) {
499
507
  auto path = *getObject();
500
508
  auto cmds = jsi::Array(runtime, path.countVerbs());
501
- auto it = SkPath::Iter(path, false);
502
- // { "Move", "Line", "Quad", "Conic", "Cubic",
503
- // "Close", "Done" };
504
- const int pointCount[] = {1, 1, 2, 2, 3, 0, 0};
505
- const int cmdCount[] = {3, 3, 5, 6, 7, 1, 0};
506
- SkPoint points[4];
507
- SkPath::Verb verb;
508
- auto k = 0;
509
- while (SkPath::kDone_Verb != (verb = it.next(points))) {
510
- auto verbVal = static_cast<int>(verb);
511
- auto cmd = jsi::Array(runtime, cmdCount[verbVal]);
512
- auto j = 0;
513
- cmd.setValueAtIndex(runtime, j++, jsi::Value(verbVal));
514
- for (int i = 0; i < pointCount[verbVal]; ++i) {
515
- cmd.setValueAtIndex(runtime, j++,
516
- jsi::Value(static_cast<double>(points[1 + i].fX)));
517
- cmd.setValueAtIndex(runtime, j++,
518
- jsi::Value(static_cast<double>(points[1 + i].fY)));
509
+ auto j = 0;
510
+ for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
511
+ switch (verb) {
512
+ case SkPathVerb::kMove: {
513
+ auto cmd = jsi::Array(runtime, 3);
514
+ cmd.setValueAtIndex(runtime, 0, static_cast<double>(MOVE));
515
+ cmd.setValueAtIndex(runtime, 1, static_cast<double>(pts[0].x()));
516
+ cmd.setValueAtIndex(runtime, 2, static_cast<double>(pts[0].y()));
517
+ cmds.setValueAtIndex(runtime, j, cmd);
518
+ break;
519
+ }
520
+ case SkPathVerb::kLine: {
521
+ auto cmd = jsi::Array(runtime, 3);
522
+ cmd.setValueAtIndex(runtime, 0, static_cast<double>(LINE));
523
+ cmd.setValueAtIndex(runtime, 1, static_cast<double>(pts[1].x()));
524
+ cmd.setValueAtIndex(runtime, 2, static_cast<double>(pts[1].y()));
525
+ cmds.setValueAtIndex(runtime, j, cmd);
526
+ break;
527
+ }
528
+ case SkPathVerb::kQuad: {
529
+ auto cmd = jsi::Array(runtime, 5);
530
+ cmd.setValueAtIndex(runtime, 0, static_cast<double>(QUAD));
531
+ cmd.setValueAtIndex(runtime, 1, static_cast<double>(pts[1].x()));
532
+ cmd.setValueAtIndex(runtime, 2, static_cast<double>(pts[1].y()));
533
+ cmd.setValueAtIndex(runtime, 3, static_cast<double>(pts[2].x()));
534
+ cmd.setValueAtIndex(runtime, 4, static_cast<double>(pts[2].y()));
535
+ cmds.setValueAtIndex(runtime, j, cmd);
536
+ break;
537
+ }
538
+ case SkPathVerb::kConic: {
539
+ auto cmd = jsi::Array(runtime, 6);
540
+ cmd.setValueAtIndex(runtime, 0, static_cast<double>(CONIC));
541
+ cmd.setValueAtIndex(runtime, 1, static_cast<double>(pts[1].x()));
542
+ cmd.setValueAtIndex(runtime, 2, static_cast<double>(pts[1].y()));
543
+ cmd.setValueAtIndex(runtime, 3, static_cast<double>(pts[2].x()));
544
+ cmd.setValueAtIndex(runtime, 4, static_cast<double>(pts[2].y()));
545
+ cmd.setValueAtIndex(runtime, 5, static_cast<double>(*w));
546
+ cmds.setValueAtIndex(runtime, j, cmd);
547
+ break;
548
+ }
549
+ case SkPathVerb::kCubic: {
550
+ auto cmd = jsi::Array(runtime, 7);
551
+ cmd.setValueAtIndex(runtime, 0, static_cast<double>(CUBIC));
552
+ cmd.setValueAtIndex(runtime, 1, static_cast<double>(pts[1].x()));
553
+ cmd.setValueAtIndex(runtime, 2, static_cast<double>(pts[1].y()));
554
+ cmd.setValueAtIndex(runtime, 3, static_cast<double>(pts[2].x()));
555
+ cmd.setValueAtIndex(runtime, 4, static_cast<double>(pts[2].y()));
556
+ cmd.setValueAtIndex(runtime, 5, static_cast<double>(pts[3].x()));
557
+ cmd.setValueAtIndex(runtime, 6, static_cast<double>(pts[3].y()));
558
+ cmds.setValueAtIndex(runtime, j, cmd);
559
+ break;
560
+ }
561
+ case SkPathVerb::kClose: {
562
+ auto cmd = jsi::Array(runtime, 1);
563
+ cmd.setValueAtIndex(runtime, 0, static_cast<double>(CLOSE));
564
+ cmds.setValueAtIndex(runtime, j, cmd);
565
+ break;
519
566
  }
520
- if (SkPath::kConic_Verb == verb) {
521
- cmd.setValueAtIndex(runtime, j,
522
- jsi::Value(static_cast<double>(it.conicWeight())));
523
567
  }
524
- cmds.setValueAtIndex(runtime, k++, cmd);
568
+ j++;
525
569
  }
526
570
  return cmds;
527
571
  }
@@ -0,0 +1,540 @@
1
+ /*
2
+ * Copyright 2015 Google Inc.
3
+ *
4
+ * Use of this source code is governed by a BSD-style license that can be
5
+ * found in the LICENSE file.
6
+ */
7
+
8
+ #ifndef SkPathPriv_DEFINED
9
+ #define SkPathPriv_DEFINED
10
+
11
+ #include "include/core/SkPath.h"
12
+ #include "include/core/SkPathBuilder.h"
13
+ #include "include/core/SkPathTypes.h"
14
+ #include "include/core/SkPoint.h"
15
+ #include "include/core/SkRect.h"
16
+ #include "include/core/SkRefCnt.h"
17
+ #include "include/core/SkScalar.h"
18
+ #include "include/core/SkTypes.h"
19
+ #include "include/private/SkIDChangeListener.h"
20
+ #include "include/private/SkPathRef.h"
21
+ #include "include/private/base/SkDebug.h"
22
+ #include "include/private/base/SkPathEnums.h"
23
+
24
+ #include <cstdint>
25
+ #include <iterator>
26
+ #include <utility>
27
+
28
+ class SkMatrix;
29
+ class SkRRect;
30
+
31
+ static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
32
+ static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
33
+ static_assert(2 == static_cast<int>(SkPathFillType::kInverseWinding), "fill_type_mismatch");
34
+ static_assert(3 == static_cast<int>(SkPathFillType::kInverseEvenOdd), "fill_type_mismatch");
35
+
36
+ class SkPathPriv {
37
+ public:
38
+ // skbug.com/9906: Not a perfect solution for W plane clipping, but 1/16384 is a
39
+ // reasonable limit (roughly 5e-5)
40
+ inline static constexpr SkScalar kW0PlaneDistance = 1.f / (1 << 14);
41
+
42
+ static SkPathFirstDirection AsFirstDirection(SkPathDirection dir) {
43
+ // since we agree numerically for the values in Direction, we can just cast.
44
+ return (SkPathFirstDirection)dir;
45
+ }
46
+
47
+ /**
48
+ * Return the opposite of the specified direction. kUnknown is its own
49
+ * opposite.
50
+ */
51
+ static SkPathFirstDirection OppositeFirstDirection(SkPathFirstDirection dir) {
52
+ static const SkPathFirstDirection gOppositeDir[] = {
53
+ SkPathFirstDirection::kCCW, SkPathFirstDirection::kCW, SkPathFirstDirection::kUnknown,
54
+ };
55
+ return gOppositeDir[(unsigned)dir];
56
+ }
57
+
58
+ /**
59
+ * Tries to compute the direction of the outer-most non-degenerate
60
+ * contour. If it can be computed, return that direction. If it cannot be determined,
61
+ * or the contour is known to be convex, return kUnknown. If the direction was determined,
62
+ * it is cached to make subsequent calls return quickly.
63
+ */
64
+ static SkPathFirstDirection ComputeFirstDirection(const SkPath&);
65
+
66
+ static bool IsClosedSingleContour(const SkPath& path) {
67
+ int verbCount = path.countVerbs();
68
+ if (verbCount == 0)
69
+ return false;
70
+ int moveCount = 0;
71
+ auto verbs = path.fPathRef->verbsBegin();
72
+ for (int i = 0; i < verbCount; i++) {
73
+ switch (verbs[i]) {
74
+ case SkPath::Verb::kMove_Verb:
75
+ moveCount += 1;
76
+ if (moveCount > 1) {
77
+ return false;
78
+ }
79
+ break;
80
+ case SkPath::Verb::kClose_Verb:
81
+ if (i == verbCount - 1) {
82
+ return true;
83
+ }
84
+ return false;
85
+ default: break;
86
+ }
87
+ }
88
+ return false;
89
+ }
90
+
91
+ // In some scenarios (e.g. fill or convexity checking all but the last leading move to are
92
+ // irrelevant to behavior). SkPath::injectMoveToIfNeeded should ensure that this is always at
93
+ // least 1.
94
+ static int LeadingMoveToCount(const SkPath& path) {
95
+ int verbCount = path.countVerbs();
96
+ auto verbs = path.fPathRef->verbsBegin();
97
+ for (int i = 0; i < verbCount; i++) {
98
+ if (verbs[i] != SkPath::Verb::kMove_Verb) {
99
+ return i;
100
+ }
101
+ }
102
+ return verbCount; // path is all move verbs
103
+ }
104
+
105
+ static void AddGenIDChangeListener(const SkPath& path, sk_sp<SkIDChangeListener> listener) {
106
+ path.fPathRef->addGenIDChangeListener(std::move(listener));
107
+ }
108
+
109
+ /**
110
+ * This returns true for a rect that has a move followed by 3 or 4 lines and a close. If
111
+ * 'isSimpleFill' is true, an uncloseed rect will also be accepted as long as it starts and
112
+ * ends at the same corner. This does not permit degenerate line or point rectangles.
113
+ */
114
+ static bool IsSimpleRect(const SkPath& path, bool isSimpleFill, SkRect* rect,
115
+ SkPathDirection* direction, unsigned* start);
116
+
117
+ /**
118
+ * Creates a path from arc params using the semantics of SkCanvas::drawArc. This function
119
+ * assumes empty ovals and zero sweeps have already been filtered out.
120
+ */
121
+ static void CreateDrawArcPath(SkPath* path, const SkRect& oval, SkScalar startAngle,
122
+ SkScalar sweepAngle, bool useCenter, bool isFillNoPathEffect);
123
+
124
+ /**
125
+ * Determines whether an arc produced by CreateDrawArcPath will be convex. Assumes a non-empty
126
+ * oval.
127
+ */
128
+ static bool DrawArcIsConvex(SkScalar sweepAngle, bool useCenter, bool isFillNoPathEffect);
129
+
130
+ static void ShrinkToFit(SkPath* path) {
131
+ path->shrinkToFit();
132
+ }
133
+
134
+ /**
135
+ * Returns a C++11-iterable object that traverses a path's verbs in order. e.g:
136
+ *
137
+ * for (SkPath::Verb verb : SkPathPriv::Verbs(path)) {
138
+ * ...
139
+ * }
140
+ */
141
+ struct Verbs {
142
+ public:
143
+ Verbs(const SkPath& path) : fPathRef(path.fPathRef.get()) {}
144
+ struct Iter {
145
+ void operator++() { fVerb++; }
146
+ bool operator!=(const Iter& b) { return fVerb != b.fVerb; }
147
+ SkPath::Verb operator*() { return static_cast<SkPath::Verb>(*fVerb); }
148
+ const uint8_t* fVerb;
149
+ };
150
+ Iter begin() { return Iter{fPathRef->verbsBegin()}; }
151
+ Iter end() { return Iter{fPathRef->verbsEnd()}; }
152
+ private:
153
+ Verbs(const Verbs&) = delete;
154
+ Verbs& operator=(const Verbs&) = delete;
155
+ SkPathRef* fPathRef;
156
+ };
157
+
158
+ /**
159
+ * Iterates through a raw range of path verbs, points, and conics. All values are returned
160
+ * unaltered.
161
+ *
162
+ * NOTE: This class's definition will be moved into SkPathPriv once RangeIter is removed.
163
+ */
164
+ using RangeIter = SkPath::RangeIter;
165
+
166
+ /**
167
+ * Iterable object for traversing verbs, points, and conic weights in a path:
168
+ *
169
+ * for (auto [verb, pts, weights] : SkPathPriv::Iterate(skPath)) {
170
+ * ...
171
+ * }
172
+ */
173
+ struct Iterate {
174
+ public:
175
+ Iterate(const SkPath& path)
176
+ : Iterate(path.fPathRef->verbsBegin(),
177
+ // Don't allow iteration through non-finite points.
178
+ (!path.isFinite()) ? path.fPathRef->verbsBegin()
179
+ : path.fPathRef->verbsEnd(),
180
+ path.fPathRef->points(), path.fPathRef->conicWeights()) {
181
+ }
182
+ Iterate(const uint8_t* verbsBegin, const uint8_t* verbsEnd, const SkPoint* points,
183
+ const SkScalar* weights)
184
+ : fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) {
185
+ }
186
+ SkPath::RangeIter begin() { return {fVerbsBegin, fPoints, fWeights}; }
187
+ SkPath::RangeIter end() { return {fVerbsEnd, nullptr, nullptr}; }
188
+ private:
189
+ const uint8_t* fVerbsBegin;
190
+ const uint8_t* fVerbsEnd;
191
+ const SkPoint* fPoints;
192
+ const SkScalar* fWeights;
193
+ };
194
+
195
+ /**
196
+ * Returns a pointer to the verb data.
197
+ */
198
+ static const uint8_t* VerbData(const SkPath& path) {
199
+ return path.fPathRef->verbsBegin();
200
+ }
201
+
202
+ /** Returns a raw pointer to the path points */
203
+ static const SkPoint* PointData(const SkPath& path) {
204
+ return path.fPathRef->points();
205
+ }
206
+
207
+ /** Returns the number of conic weights in the path */
208
+ static int ConicWeightCnt(const SkPath& path) {
209
+ return path.fPathRef->countWeights();
210
+ }
211
+
212
+ /** Returns a raw pointer to the path conic weights. */
213
+ static const SkScalar* ConicWeightData(const SkPath& path) {
214
+ return path.fPathRef->conicWeights();
215
+ }
216
+
217
+ /** Returns true if the underlying SkPathRef has one single owner. */
218
+ static bool TestingOnly_unique(const SkPath& path) {
219
+ return path.fPathRef->unique();
220
+ }
221
+
222
+ // Won't be needed once we can make path's immutable (with their bounds always computed)
223
+ static bool HasComputedBounds(const SkPath& path) {
224
+ return path.hasComputedBounds();
225
+ }
226
+
227
+ /** Returns true if constructed by addCircle(), addOval(); and in some cases,
228
+ addRoundRect(), addRRect(). SkPath constructed with conicTo() or rConicTo() will not
229
+ return true though SkPath draws oval.
230
+
231
+ rect receives bounds of oval.
232
+ dir receives SkPathDirection of oval: kCW_Direction if clockwise, kCCW_Direction if
233
+ counterclockwise.
234
+ start receives start of oval: 0 for top, 1 for right, 2 for bottom, 3 for left.
235
+
236
+ rect, dir, and start are unmodified if oval is not found.
237
+
238
+ Triggers performance optimizations on some GPU surface implementations.
239
+
240
+ @param rect storage for bounding SkRect of oval; may be nullptr
241
+ @param dir storage for SkPathDirection; may be nullptr
242
+ @param start storage for start of oval; may be nullptr
243
+ @return true if SkPath was constructed by method that reduces to oval
244
+ */
245
+ static bool IsOval(const SkPath& path, SkRect* rect, SkPathDirection* dir, unsigned* start) {
246
+ bool isCCW = false;
247
+ bool result = path.fPathRef->isOval(rect, &isCCW, start);
248
+ if (dir && result) {
249
+ *dir = isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
250
+ }
251
+ return result;
252
+ }
253
+
254
+ /** Returns true if constructed by addRoundRect(), addRRect(); and if construction
255
+ is not empty, not SkRect, and not oval. SkPath constructed with other calls
256
+ will not return true though SkPath draws SkRRect.
257
+
258
+ rrect receives bounds of SkRRect.
259
+ dir receives SkPathDirection of oval: kCW_Direction if clockwise, kCCW_Direction if
260
+ counterclockwise.
261
+ start receives start of SkRRect: 0 for top, 1 for right, 2 for bottom, 3 for left.
262
+
263
+ rrect, dir, and start are unmodified if SkRRect is not found.
264
+
265
+ Triggers performance optimizations on some GPU surface implementations.
266
+
267
+ @param rrect storage for bounding SkRect of SkRRect; may be nullptr
268
+ @param dir storage for SkPathDirection; may be nullptr
269
+ @param start storage for start of SkRRect; may be nullptr
270
+ @return true if SkPath contains only SkRRect
271
+ */
272
+ static bool IsRRect(const SkPath& path, SkRRect* rrect, SkPathDirection* dir,
273
+ unsigned* start) {
274
+ bool isCCW = false;
275
+ bool result = path.fPathRef->isRRect(rrect, &isCCW, start);
276
+ if (dir && result) {
277
+ *dir = isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
278
+ }
279
+ return result;
280
+ }
281
+
282
+ /**
283
+ * Sometimes in the drawing pipeline, we have to perform math on path coordinates, even after
284
+ * the path is in device-coordinates. Tessellation and clipping are two examples. Usually this
285
+ * is pretty modest, but it can involve subtracting/adding coordinates, or multiplying by
286
+ * small constants (e.g. 2,3,4). To try to preflight issues where these optionations could turn
287
+ * finite path values into infinities (or NaNs), we allow the upper drawing code to reject
288
+ * the path if its bounds (in device coordinates) is too close to max float.
289
+ */
290
+ static bool TooBigForMath(const SkRect& bounds) {
291
+ // This value is just a guess. smaller is safer, but we don't want to reject largish paths
292
+ // that we don't have to.
293
+ constexpr SkScalar scale_down_to_allow_for_small_multiplies = 0.25f;
294
+ constexpr SkScalar max = SK_ScalarMax * scale_down_to_allow_for_small_multiplies;
295
+
296
+ // use ! expression so we return true if bounds contains NaN
297
+ return !(bounds.fLeft >= -max && bounds.fTop >= -max &&
298
+ bounds.fRight <= max && bounds.fBottom <= max);
299
+ }
300
+ static bool TooBigForMath(const SkPath& path) {
301
+ return TooBigForMath(path.getBounds());
302
+ }
303
+
304
+ // Returns number of valid points for each SkPath::Iter verb
305
+ static int PtsInIter(unsigned verb) {
306
+ static const uint8_t gPtsInVerb[] = {
307
+ 1, // kMove pts[0]
308
+ 2, // kLine pts[0..1]
309
+ 3, // kQuad pts[0..2]
310
+ 3, // kConic pts[0..2]
311
+ 4, // kCubic pts[0..3]
312
+ 0, // kClose
313
+ 0 // kDone
314
+ };
315
+
316
+ SkASSERT(verb < std::size(gPtsInVerb));
317
+ return gPtsInVerb[verb];
318
+ }
319
+
320
+ // Returns number of valid points for each verb, not including the "starter"
321
+ // point that the Iterator adds for line/quad/conic/cubic
322
+ static int PtsInVerb(unsigned verb) {
323
+ static const uint8_t gPtsInVerb[] = {
324
+ 1, // kMove pts[0]
325
+ 1, // kLine pts[0..1]
326
+ 2, // kQuad pts[0..2]
327
+ 2, // kConic pts[0..2]
328
+ 3, // kCubic pts[0..3]
329
+ 0, // kClose
330
+ 0 // kDone
331
+ };
332
+
333
+ SkASSERT(verb < std::size(gPtsInVerb));
334
+ return gPtsInVerb[verb];
335
+ }
336
+
337
+ static bool IsAxisAligned(const SkPath& path);
338
+
339
+ static bool AllPointsEq(const SkPoint pts[], int count) {
340
+ for (int i = 1; i < count; ++i) {
341
+ if (pts[0] != pts[i]) {
342
+ return false;
343
+ }
344
+ }
345
+ return true;
346
+ }
347
+
348
+ static int LastMoveToIndex(const SkPath& path) { return path.fLastMoveToIndex; }
349
+
350
+ static bool IsRectContour(const SkPath&, bool allowPartial, int* currVerb,
351
+ const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
352
+ SkRect* rect);
353
+
354
+ /** Returns true if SkPath is equivalent to nested SkRect pair when filled.
355
+ If false, rect and dirs are unchanged.
356
+ If true, rect and dirs are written to if not nullptr:
357
+ setting rect[0] to outer SkRect, and rect[1] to inner SkRect;
358
+ setting dirs[0] to SkPathDirection of outer SkRect, and dirs[1] to SkPathDirection of
359
+ inner SkRect.
360
+
361
+ @param rect storage for SkRect pair; may be nullptr
362
+ @param dirs storage for SkPathDirection pair; may be nullptr
363
+ @return true if SkPath contains nested SkRect pair
364
+ */
365
+ static bool IsNestedFillRects(const SkPath&, SkRect rect[2],
366
+ SkPathDirection dirs[2] = nullptr);
367
+
368
+ static bool IsInverseFillType(SkPathFillType fill) {
369
+ return (static_cast<int>(fill) & 2) != 0;
370
+ }
371
+
372
+ /** Returns equivalent SkPath::FillType representing SkPath fill inside its bounds.
373
+ .
374
+
375
+ @param fill one of: kWinding_FillType, kEvenOdd_FillType,
376
+ kInverseWinding_FillType, kInverseEvenOdd_FillType
377
+ @return fill, or kWinding_FillType or kEvenOdd_FillType if fill is inverted
378
+ */
379
+ static SkPathFillType ConvertToNonInverseFillType(SkPathFillType fill) {
380
+ return (SkPathFillType)(static_cast<int>(fill) & 1);
381
+ }
382
+
383
+ /**
384
+ * If needed (to not blow-up under a perspective matrix), clip the path, returning the
385
+ * answer in "result", and return true.
386
+ *
387
+ * Note result might be empty (if the path was completely clipped out).
388
+ *
389
+ * If no clipping is needed, returns false and "result" is left unchanged.
390
+ */
391
+ static bool PerspectiveClip(const SkPath& src, const SkMatrix&, SkPath* result);
392
+
393
+ /**
394
+ * Gets the number of GenIDChangeListeners. If another thread has access to this path then
395
+ * this may be stale before return and only indicates that the count was the return value
396
+ * at some point during the execution of the function.
397
+ */
398
+ static int GenIDChangeListenersCount(const SkPath&);
399
+
400
+ static void UpdatePathPoint(SkPath* path, int index, const SkPoint& pt) {
401
+ SkASSERT(index < path->countPoints());
402
+ SkPathRef::Editor ed(&path->fPathRef);
403
+ ed.writablePoints()[index] = pt;
404
+ path->dirtyAfterEdit();
405
+ }
406
+
407
+ static SkPathConvexity GetConvexity(const SkPath& path) {
408
+ return path.getConvexity();
409
+ }
410
+ static SkPathConvexity GetConvexityOrUnknown(const SkPath& path) {
411
+ return path.getConvexityOrUnknown();
412
+ }
413
+ static void SetConvexity(const SkPath& path, SkPathConvexity c) {
414
+ path.setConvexity(c);
415
+ }
416
+ static void ForceComputeConvexity(const SkPath& path) {
417
+ path.setConvexity(SkPathConvexity::kUnknown);
418
+ (void)path.isConvex();
419
+ }
420
+
421
+ static void ReverseAddPath(SkPathBuilder* builder, const SkPath& reverseMe) {
422
+ builder->privateReverseAddPath(reverseMe);
423
+ }
424
+
425
+ static SkPath MakePath(const SkPathVerbAnalysis& analysis,
426
+ const SkPoint points[],
427
+ const uint8_t verbs[],
428
+ int verbCount,
429
+ const SkScalar conics[],
430
+ SkPathFillType fillType,
431
+ bool isVolatile) {
432
+ return SkPath::MakeInternal(analysis, points, verbs, verbCount, conics, fillType,
433
+ isVolatile);
434
+ }
435
+ };
436
+
437
+ // Lightweight variant of SkPath::Iter that only returns segments (e.g. lines/conics).
438
+ // Does not return kMove or kClose.
439
+ // Always "auto-closes" each contour.
440
+ // Roughly the same as SkPath::Iter(path, true), but does not return moves or closes
441
+ //
442
+ class SkPathEdgeIter {
443
+ const uint8_t* fVerbs;
444
+ const uint8_t* fVerbsStop;
445
+ const SkPoint* fPts;
446
+ const SkPoint* fMoveToPtr;
447
+ const SkScalar* fConicWeights;
448
+ SkPoint fScratch[2]; // for auto-close lines
449
+ bool fNeedsCloseLine;
450
+ bool fNextIsNewContour;
451
+ SkDEBUGCODE(bool fIsConic;)
452
+
453
+ enum {
454
+ kIllegalEdgeValue = 99
455
+ };
456
+
457
+ public:
458
+ SkPathEdgeIter(const SkPath& path);
459
+
460
+ SkScalar conicWeight() const {
461
+ SkASSERT(fIsConic);
462
+ return *fConicWeights;
463
+ }
464
+
465
+ enum class Edge {
466
+ kLine = SkPath::kLine_Verb,
467
+ kQuad = SkPath::kQuad_Verb,
468
+ kConic = SkPath::kConic_Verb,
469
+ kCubic = SkPath::kCubic_Verb,
470
+ };
471
+
472
+ static SkPath::Verb EdgeToVerb(Edge e) {
473
+ return SkPath::Verb(e);
474
+ }
475
+
476
+ struct Result {
477
+ const SkPoint* fPts; // points for the segment, or null if done
478
+ Edge fEdge;
479
+ bool fIsNewContour;
480
+
481
+ // Returns true when it holds an Edge, false when the path is done.
482
+ explicit operator bool() { return fPts != nullptr; }
483
+ };
484
+
485
+ Result next() {
486
+ auto closeline = [&]() {
487
+ fScratch[0] = fPts[-1];
488
+ fScratch[1] = *fMoveToPtr;
489
+ fNeedsCloseLine = false;
490
+ fNextIsNewContour = true;
491
+ return Result{ fScratch, Edge::kLine, false };
492
+ };
493
+
494
+ for (;;) {
495
+ SkASSERT(fVerbs <= fVerbsStop);
496
+ if (fVerbs == fVerbsStop) {
497
+ return fNeedsCloseLine
498
+ ? closeline()
499
+ : Result{ nullptr, Edge(kIllegalEdgeValue), false };
500
+ }
501
+
502
+ SkDEBUGCODE(fIsConic = false;)
503
+
504
+ const auto v = *fVerbs++;
505
+ switch (v) {
506
+ case SkPath::kMove_Verb: {
507
+ if (fNeedsCloseLine) {
508
+ auto res = closeline();
509
+ fMoveToPtr = fPts++;
510
+ return res;
511
+ }
512
+ fMoveToPtr = fPts++;
513
+ fNextIsNewContour = true;
514
+ } break;
515
+ case SkPath::kClose_Verb:
516
+ if (fNeedsCloseLine) return closeline();
517
+ break;
518
+ default: {
519
+ // Actual edge.
520
+ const int pts_count = (v+2) / 2,
521
+ cws_count = (v & (v-1)) / 2;
522
+ SkASSERT(pts_count == SkPathPriv::PtsInIter(v) - 1);
523
+
524
+ fNeedsCloseLine = true;
525
+ fPts += pts_count;
526
+ fConicWeights += cws_count;
527
+
528
+ SkDEBUGCODE(fIsConic = (v == SkPath::kConic_Verb);)
529
+ SkASSERT(fIsConic == (cws_count > 0));
530
+
531
+ bool isNewContour = fNextIsNewContour;
532
+ fNextIsNewContour = false;
533
+ return { &fPts[-(pts_count + 1)], Edge(v), isNewContour };
534
+ }
535
+ }
536
+ }
537
+ }
538
+ };
539
+
540
+ #endif
@@ -1,4 +1,5 @@
1
1
  import "./skia/NativeSetup";
2
+ export { JsiSkImage } from "./skia/web/JsiSkImage";
2
3
  export * from "./renderer";
3
4
  export * from "./renderer/Canvas";
4
5
  export * from "./renderer/Offscreen";
@@ -3,13 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ var _exportNames = {
7
+ JsiSkImage: true
8
+ };
9
+ Object.defineProperty(exports, "JsiSkImage", {
10
+ enumerable: true,
11
+ get: function () {
12
+ return _JsiSkImage.JsiSkImage;
13
+ }
14
+ });
6
15
 
7
16
  require("./skia/NativeSetup");
8
17
 
18
+ var _JsiSkImage = require("./skia/web/JsiSkImage");
19
+
9
20
  var _renderer = require("./renderer");
10
21
 
11
22
  Object.keys(_renderer).forEach(function (key) {
12
23
  if (key === "default" || key === "__esModule") return;
24
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
13
25
  if (key in exports && exports[key] === _renderer[key]) return;
14
26
  Object.defineProperty(exports, key, {
15
27
  enumerable: true,
@@ -23,6 +35,7 @@ var _Canvas = require("./renderer/Canvas");
23
35
 
24
36
  Object.keys(_Canvas).forEach(function (key) {
25
37
  if (key === "default" || key === "__esModule") return;
38
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
26
39
  if (key in exports && exports[key] === _Canvas[key]) return;
27
40
  Object.defineProperty(exports, key, {
28
41
  enumerable: true,
@@ -36,6 +49,7 @@ var _Offscreen = require("./renderer/Offscreen");
36
49
 
37
50
  Object.keys(_Offscreen).forEach(function (key) {
38
51
  if (key === "default" || key === "__esModule") return;
52
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
39
53
  if (key in exports && exports[key] === _Offscreen[key]) return;
40
54
  Object.defineProperty(exports, key, {
41
55
  enumerable: true,
@@ -49,6 +63,7 @@ var _views = require("./views");
49
63
 
50
64
  Object.keys(_views).forEach(function (key) {
51
65
  if (key === "default" || key === "__esModule") return;
66
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
52
67
  if (key in exports && exports[key] === _views[key]) return;
53
68
  Object.defineProperty(exports, key, {
54
69
  enumerable: true,
@@ -62,6 +77,7 @@ var _skia = require("./skia");
62
77
 
63
78
  Object.keys(_skia).forEach(function (key) {
64
79
  if (key === "default" || key === "__esModule") return;
80
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
65
81
  if (key in exports && exports[key] === _skia[key]) return;
66
82
  Object.defineProperty(exports, key, {
67
83
  enumerable: true,
@@ -75,6 +91,7 @@ var _external = require("./external");
75
91
 
76
92
  Object.keys(_external).forEach(function (key) {
77
93
  if (key === "default" || key === "__esModule") return;
94
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
78
95
  if (key in exports && exports[key] === _external[key]) return;
79
96
  Object.defineProperty(exports, key, {
80
97
  enumerable: true,
@@ -88,6 +105,7 @@ var _values = require("./values");
88
105
 
89
106
  Object.keys(_values).forEach(function (key) {
90
107
  if (key === "default" || key === "__esModule") return;
108
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
91
109
  if (key in exports && exports[key] === _values[key]) return;
92
110
  Object.defineProperty(exports, key, {
93
111
  enumerable: true,
@@ -101,6 +119,7 @@ var _animation = require("./animation");
101
119
 
102
120
  Object.keys(_animation).forEach(function (key) {
103
121
  if (key === "default" || key === "__esModule") return;
122
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
104
123
  if (key in exports && exports[key] === _animation[key]) return;
105
124
  Object.defineProperty(exports, key, {
106
125
  enumerable: true,
@@ -114,6 +133,7 @@ var _types = require("./dom/types");
114
133
 
115
134
  Object.keys(_types).forEach(function (key) {
116
135
  if (key === "default" || key === "__esModule") return;
136
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
117
137
  if (key in exports && exports[key] === _types[key]) return;
118
138
  Object.defineProperty(exports, key, {
119
139
  enumerable: true,
@@ -127,6 +147,7 @@ var _nodes = require("./dom/nodes");
127
147
 
128
148
  Object.keys(_nodes).forEach(function (key) {
129
149
  if (key === "default" || key === "__esModule") return;
150
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
130
151
  if (key in exports && exports[key] === _nodes[key]) return;
131
152
  Object.defineProperty(exports, key, {
132
153
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["import \"./skia/NativeSetup\";\nexport * from \"./renderer\";\nexport * from \"./renderer/Canvas\";\nexport * from \"./renderer/Offscreen\";\nexport * from \"./views\";\nexport * from \"./skia\";\nexport * from \"./external\";\nexport * from \"./values\";\nexport * from \"./animation\";\nexport * from \"./dom/types\";\nexport * from \"./dom/nodes\";\n"],"mappings":";;;;;;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA"}
1
+ {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["import \"./skia/NativeSetup\";\nexport { JsiSkImage } from \"./skia/web/JsiSkImage\";\nexport * from \"./renderer\";\nexport * from \"./renderer/Canvas\";\nexport * from \"./renderer/Offscreen\";\nexport * from \"./views\";\nexport * from \"./skia\";\nexport * from \"./external\";\nexport * from \"./values\";\nexport * from \"./animation\";\nexport * from \"./dom/types\";\nexport * from \"./dom/nodes\";\n"],"mappings":";;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA"}
@@ -16,17 +16,18 @@ var _Platform = require("../../Platform");
16
16
  var _Typeface = require("./Typeface");
17
17
 
18
18
  /*global SkiaApi*/
19
-
19
+ const defaultFontSize = 14;
20
20
  /**
21
21
  * Returns a Skia Font object
22
22
  * */
23
- const useFont = (font, size, onError) => {
23
+
24
+ const useFont = function (font) {
25
+ let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultFontSize;
26
+ let onError = arguments.length > 2 ? arguments[2] : undefined;
24
27
  const typeface = (0, _Typeface.useTypeface)(font, onError);
25
28
  return (0, _react.useMemo)(() => {
26
- if (typeface && size) {
29
+ if (typeface) {
27
30
  return _Skia.Skia.Font(typeface, size);
28
- } else if (typeface && !size) {
29
- return _Skia.Skia.Font(typeface);
30
31
  } else {
31
32
  return null;
32
33
  }
@@ -36,7 +37,7 @@ const useFont = (font, size, onError) => {
36
37
  exports.useFont = useFont;
37
38
  const defaultFontStyle = {
38
39
  fontFamily: "System",
39
- fontSize: 14,
40
+ fontSize: defaultFontSize,
40
41
  fontStyle: "normal",
41
42
  fontWeight: "normal"
42
43
  };
@@ -1 +1 @@
1
- {"version":3,"names":["useFont","font","size","onError","typeface","useTypeface","useMemo","Skia","Font","defaultFontStyle","fontFamily","fontSize","fontStyle","fontWeight","slant","s","FontSlant","Italic","Oblique","Upright","weight","parseInt","matchFont","inputStyle","fontMgr","FontMgr","System","style","width","matchFamilyStyle","listFontFamilies","Array","countFamilies","fill","map","_","i","getFamilyName","loadTypefaces","typefacesToLoad","promises","Object","keys","flatMap","familyName","typefaceToLoad","Data","fromURI","Platform","resolveAsset","then","data","tf","Typeface","MakeFreeTypeFaceFromData","Error","Promise","all","useFonts","sources","setFontMgr","useState","useEffect","result","fMgr","TypefaceFontProvider","Make","forEach","registerFont"],"sources":["Font.ts"],"sourcesContent":["/*global SkiaApi*/\nimport { useEffect, useMemo, useState } from \"react\";\n\nimport { Skia } from \"../Skia\";\nimport { FontSlant } from \"../types\";\nimport type { DataModule, DataSourceParam, SkFontMgr } from \"../types\";\nimport { Platform } from \"../../Platform\";\nimport type { SkTypefaceFontProvider } from \"../types/Paragraph/TypefaceFontProvider\";\n\nimport { useTypeface } from \"./Typeface\";\n\n/**\n * Returns a Skia Font object\n * */\nexport const useFont = (\n font: DataSourceParam,\n size?: number,\n onError?: (err: Error) => void\n) => {\n const typeface = useTypeface(font, onError);\n return useMemo(() => {\n if (typeface && size) {\n return Skia.Font(typeface, size);\n } else if (typeface && !size) {\n return Skia.Font(typeface);\n } else {\n return null;\n }\n }, [size, typeface]);\n};\n\ntype Slant = \"normal\" | \"italic\" | \"oblique\";\ntype Weight =\n | \"normal\"\n | \"bold\"\n | \"100\"\n | \"200\"\n | \"300\"\n | \"400\"\n | \"500\"\n | \"600\"\n | \"700\"\n | \"800\"\n | \"900\";\n\ninterface RNFontStyle {\n fontFamily: string;\n fontSize: number;\n fontStyle: Slant;\n fontWeight: Weight;\n}\n\nconst defaultFontStyle: RNFontStyle = {\n fontFamily: \"System\",\n fontSize: 14,\n fontStyle: \"normal\",\n fontWeight: \"normal\",\n};\n\nconst slant = (s: Slant) => {\n if (s === \"italic\") {\n return FontSlant.Italic;\n } else if (s === \"oblique\") {\n return FontSlant.Oblique;\n } else {\n return FontSlant.Upright;\n }\n};\n\nconst weight = (fontWeight: Weight) => {\n switch (fontWeight) {\n case \"normal\":\n return 400;\n case \"bold\":\n return 700;\n default:\n return parseInt(fontWeight, 10);\n }\n};\n\nexport const matchFont = (\n inputStyle: Partial<RNFontStyle> = {},\n fontMgr: SkFontMgr = Skia.FontMgr.System()\n) => {\n const fontStyle = {\n ...defaultFontStyle,\n ...inputStyle,\n };\n const style = {\n weight: weight(fontStyle.fontWeight),\n width: 5,\n slant: slant(fontStyle.fontStyle),\n };\n const typeface = fontMgr.matchFamilyStyle(fontStyle.fontFamily, style);\n return Skia.Font(typeface, fontStyle.fontSize);\n};\n\nexport const listFontFamilies = (fontMgr: SkFontMgr = Skia.FontMgr.System()) =>\n new Array(fontMgr.countFamilies())\n .fill(0)\n .map((_, i) => fontMgr.getFamilyName(i));\n\nconst loadTypefaces = (typefacesToLoad: Record<string, DataModule[]>) => {\n const promises = Object.keys(typefacesToLoad).flatMap((familyName) => {\n return typefacesToLoad[familyName].map((typefaceToLoad) => {\n return Skia.Data.fromURI(Platform.resolveAsset(typefaceToLoad)).then(\n (data) => {\n const tf = Skia.Typeface.MakeFreeTypeFaceFromData(data);\n if (tf === null) {\n throw new Error(`Couldn't create typeface for ${familyName}`);\n }\n return [familyName, tf] as const;\n }\n );\n });\n });\n return Promise.all(promises);\n};\n\nexport const useFonts = (sources: Record<string, DataModule[]>) => {\n const [fontMgr, setFontMgr] = useState<null | SkTypefaceFontProvider>(null);\n\n useEffect(() => {\n loadTypefaces(sources).then((result) => {\n const fMgr = Skia.TypefaceFontProvider.Make();\n result.forEach(([familyName, typeface]) => {\n fMgr.registerFont(typeface, familyName);\n });\n setFontMgr(fMgr);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return fontMgr;\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["defaultFontSize","useFont","font","size","onError","typeface","useTypeface","useMemo","Skia","Font","defaultFontStyle","fontFamily","fontSize","fontStyle","fontWeight","slant","s","FontSlant","Italic","Oblique","Upright","weight","parseInt","matchFont","inputStyle","fontMgr","FontMgr","System","style","width","matchFamilyStyle","listFontFamilies","Array","countFamilies","fill","map","_","i","getFamilyName","loadTypefaces","typefacesToLoad","promises","Object","keys","flatMap","familyName","typefaceToLoad","Data","fromURI","Platform","resolveAsset","then","data","tf","Typeface","MakeFreeTypeFaceFromData","Error","Promise","all","useFonts","sources","setFontMgr","useState","useEffect","result","fMgr","TypefaceFontProvider","Make","forEach","registerFont"],"sources":["Font.ts"],"sourcesContent":["/*global SkiaApi*/\nimport { useEffect, useMemo, useState } from \"react\";\n\nimport { Skia } from \"../Skia\";\nimport { FontSlant } from \"../types\";\nimport type { DataModule, DataSourceParam, SkFontMgr } from \"../types\";\nimport { Platform } from \"../../Platform\";\nimport type { SkTypefaceFontProvider } from \"../types/Paragraph/TypefaceFontProvider\";\n\nimport { useTypeface } from \"./Typeface\";\n\nconst defaultFontSize = 14;\n\n/**\n * Returns a Skia Font object\n * */\nexport const useFont = (\n font: DataSourceParam,\n size = defaultFontSize,\n onError?: (err: Error) => void\n) => {\n const typeface = useTypeface(font, onError);\n return useMemo(() => {\n if (typeface) {\n return Skia.Font(typeface, size);\n } else {\n return null;\n }\n }, [size, typeface]);\n};\n\ntype Slant = \"normal\" | \"italic\" | \"oblique\";\ntype Weight =\n | \"normal\"\n | \"bold\"\n | \"100\"\n | \"200\"\n | \"300\"\n | \"400\"\n | \"500\"\n | \"600\"\n | \"700\"\n | \"800\"\n | \"900\";\n\ninterface RNFontStyle {\n fontFamily: string;\n fontSize: number;\n fontStyle: Slant;\n fontWeight: Weight;\n}\n\nconst defaultFontStyle: RNFontStyle = {\n fontFamily: \"System\",\n fontSize: defaultFontSize,\n fontStyle: \"normal\",\n fontWeight: \"normal\",\n};\n\nconst slant = (s: Slant) => {\n if (s === \"italic\") {\n return FontSlant.Italic;\n } else if (s === \"oblique\") {\n return FontSlant.Oblique;\n } else {\n return FontSlant.Upright;\n }\n};\n\nconst weight = (fontWeight: Weight) => {\n switch (fontWeight) {\n case \"normal\":\n return 400;\n case \"bold\":\n return 700;\n default:\n return parseInt(fontWeight, 10);\n }\n};\n\nexport const matchFont = (\n inputStyle: Partial<RNFontStyle> = {},\n fontMgr: SkFontMgr = Skia.FontMgr.System()\n) => {\n const fontStyle = {\n ...defaultFontStyle,\n ...inputStyle,\n };\n const style = {\n weight: weight(fontStyle.fontWeight),\n width: 5,\n slant: slant(fontStyle.fontStyle),\n };\n const typeface = fontMgr.matchFamilyStyle(fontStyle.fontFamily, style);\n return Skia.Font(typeface, fontStyle.fontSize);\n};\n\nexport const listFontFamilies = (fontMgr: SkFontMgr = Skia.FontMgr.System()) =>\n new Array(fontMgr.countFamilies())\n .fill(0)\n .map((_, i) => fontMgr.getFamilyName(i));\n\nconst loadTypefaces = (typefacesToLoad: Record<string, DataModule[]>) => {\n const promises = Object.keys(typefacesToLoad).flatMap((familyName) => {\n return typefacesToLoad[familyName].map((typefaceToLoad) => {\n return Skia.Data.fromURI(Platform.resolveAsset(typefaceToLoad)).then(\n (data) => {\n const tf = Skia.Typeface.MakeFreeTypeFaceFromData(data);\n if (tf === null) {\n throw new Error(`Couldn't create typeface for ${familyName}`);\n }\n return [familyName, tf] as const;\n }\n );\n });\n });\n return Promise.all(promises);\n};\n\nexport const useFonts = (sources: Record<string, DataModule[]>) => {\n const [fontMgr, setFontMgr] = useState<null | SkTypefaceFontProvider>(null);\n\n useEffect(() => {\n loadTypefaces(sources).then((result) => {\n const fMgr = Skia.TypefaceFontProvider.Make();\n result.forEach(([familyName, typeface]) => {\n fMgr.registerFont(typeface, familyName);\n });\n setFontMgr(fMgr);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return fontMgr;\n};\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import "./skia/NativeSetup";
2
+ export { JsiSkImage } from "./skia/web/JsiSkImage";
2
3
  export * from "./renderer";
3
4
  export * from "./renderer/Canvas";
4
5
  export * from "./renderer/Offscreen";
@@ -1,4 +1,5 @@
1
1
  import "./skia/NativeSetup";
2
+ export { JsiSkImage } from "./skia/web/JsiSkImage";
2
3
  export * from "./renderer";
3
4
  export * from "./renderer/Canvas";
4
5
  export * from "./renderer/Offscreen";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["import \"./skia/NativeSetup\";\nexport * from \"./renderer\";\nexport * from \"./renderer/Canvas\";\nexport * from \"./renderer/Offscreen\";\nexport * from \"./views\";\nexport * from \"./skia\";\nexport * from \"./external\";\nexport * from \"./values\";\nexport * from \"./animation\";\nexport * from \"./dom/types\";\nexport * from \"./dom/nodes\";\n"],"mappings":"AAAA,OAAO,oBAAP;AACA,cAAc,YAAd;AACA,cAAc,mBAAd;AACA,cAAc,sBAAd;AACA,cAAc,SAAd;AACA,cAAc,QAAd;AACA,cAAc,YAAd;AACA,cAAc,UAAd;AACA,cAAc,aAAd;AACA,cAAc,aAAd;AACA,cAAc,aAAd"}
1
+ {"version":3,"names":["JsiSkImage"],"sources":["index.ts"],"sourcesContent":["import \"./skia/NativeSetup\";\nexport { JsiSkImage } from \"./skia/web/JsiSkImage\";\nexport * from \"./renderer\";\nexport * from \"./renderer/Canvas\";\nexport * from \"./renderer/Offscreen\";\nexport * from \"./views\";\nexport * from \"./skia\";\nexport * from \"./external\";\nexport * from \"./values\";\nexport * from \"./animation\";\nexport * from \"./dom/types\";\nexport * from \"./dom/nodes\";\n"],"mappings":"AAAA,OAAO,oBAAP;AACA,SAASA,UAAT,QAA2B,uBAA3B;AACA,cAAc,YAAd;AACA,cAAc,mBAAd;AACA,cAAc,sBAAd;AACA,cAAc,SAAd;AACA,cAAc,QAAd;AACA,cAAc,YAAd;AACA,cAAc,UAAd;AACA,cAAc,aAAd;AACA,cAAc,aAAd;AACA,cAAc,aAAd"}
@@ -4,17 +4,18 @@ import { Skia } from "../Skia";
4
4
  import { FontSlant } from "../types";
5
5
  import { Platform } from "../../Platform";
6
6
  import { useTypeface } from "./Typeface";
7
+ const defaultFontSize = 14;
7
8
  /**
8
9
  * Returns a Skia Font object
9
10
  * */
10
11
 
11
- export const useFont = (font, size, onError) => {
12
+ export const useFont = function (font) {
13
+ let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultFontSize;
14
+ let onError = arguments.length > 2 ? arguments[2] : undefined;
12
15
  const typeface = useTypeface(font, onError);
13
16
  return useMemo(() => {
14
- if (typeface && size) {
17
+ if (typeface) {
15
18
  return Skia.Font(typeface, size);
16
- } else if (typeface && !size) {
17
- return Skia.Font(typeface);
18
19
  } else {
19
20
  return null;
20
21
  }
@@ -22,7 +23,7 @@ export const useFont = (font, size, onError) => {
22
23
  };
23
24
  const defaultFontStyle = {
24
25
  fontFamily: "System",
25
- fontSize: 14,
26
+ fontSize: defaultFontSize,
26
27
  fontStyle: "normal",
27
28
  fontWeight: "normal"
28
29
  };
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useMemo","useState","Skia","FontSlant","Platform","useTypeface","useFont","font","size","onError","typeface","Font","defaultFontStyle","fontFamily","fontSize","fontStyle","fontWeight","slant","s","Italic","Oblique","Upright","weight","parseInt","matchFont","inputStyle","fontMgr","FontMgr","System","style","width","matchFamilyStyle","listFontFamilies","Array","countFamilies","fill","map","_","i","getFamilyName","loadTypefaces","typefacesToLoad","promises","Object","keys","flatMap","familyName","typefaceToLoad","Data","fromURI","resolveAsset","then","data","tf","Typeface","MakeFreeTypeFaceFromData","Error","Promise","all","useFonts","sources","setFontMgr","result","fMgr","TypefaceFontProvider","Make","forEach","registerFont"],"sources":["Font.ts"],"sourcesContent":["/*global SkiaApi*/\nimport { useEffect, useMemo, useState } from \"react\";\n\nimport { Skia } from \"../Skia\";\nimport { FontSlant } from \"../types\";\nimport type { DataModule, DataSourceParam, SkFontMgr } from \"../types\";\nimport { Platform } from \"../../Platform\";\nimport type { SkTypefaceFontProvider } from \"../types/Paragraph/TypefaceFontProvider\";\n\nimport { useTypeface } from \"./Typeface\";\n\n/**\n * Returns a Skia Font object\n * */\nexport const useFont = (\n font: DataSourceParam,\n size?: number,\n onError?: (err: Error) => void\n) => {\n const typeface = useTypeface(font, onError);\n return useMemo(() => {\n if (typeface && size) {\n return Skia.Font(typeface, size);\n } else if (typeface && !size) {\n return Skia.Font(typeface);\n } else {\n return null;\n }\n }, [size, typeface]);\n};\n\ntype Slant = \"normal\" | \"italic\" | \"oblique\";\ntype Weight =\n | \"normal\"\n | \"bold\"\n | \"100\"\n | \"200\"\n | \"300\"\n | \"400\"\n | \"500\"\n | \"600\"\n | \"700\"\n | \"800\"\n | \"900\";\n\ninterface RNFontStyle {\n fontFamily: string;\n fontSize: number;\n fontStyle: Slant;\n fontWeight: Weight;\n}\n\nconst defaultFontStyle: RNFontStyle = {\n fontFamily: \"System\",\n fontSize: 14,\n fontStyle: \"normal\",\n fontWeight: \"normal\",\n};\n\nconst slant = (s: Slant) => {\n if (s === \"italic\") {\n return FontSlant.Italic;\n } else if (s === \"oblique\") {\n return FontSlant.Oblique;\n } else {\n return FontSlant.Upright;\n }\n};\n\nconst weight = (fontWeight: Weight) => {\n switch (fontWeight) {\n case \"normal\":\n return 400;\n case \"bold\":\n return 700;\n default:\n return parseInt(fontWeight, 10);\n }\n};\n\nexport const matchFont = (\n inputStyle: Partial<RNFontStyle> = {},\n fontMgr: SkFontMgr = Skia.FontMgr.System()\n) => {\n const fontStyle = {\n ...defaultFontStyle,\n ...inputStyle,\n };\n const style = {\n weight: weight(fontStyle.fontWeight),\n width: 5,\n slant: slant(fontStyle.fontStyle),\n };\n const typeface = fontMgr.matchFamilyStyle(fontStyle.fontFamily, style);\n return Skia.Font(typeface, fontStyle.fontSize);\n};\n\nexport const listFontFamilies = (fontMgr: SkFontMgr = Skia.FontMgr.System()) =>\n new Array(fontMgr.countFamilies())\n .fill(0)\n .map((_, i) => fontMgr.getFamilyName(i));\n\nconst loadTypefaces = (typefacesToLoad: Record<string, DataModule[]>) => {\n const promises = Object.keys(typefacesToLoad).flatMap((familyName) => {\n return typefacesToLoad[familyName].map((typefaceToLoad) => {\n return Skia.Data.fromURI(Platform.resolveAsset(typefaceToLoad)).then(\n (data) => {\n const tf = Skia.Typeface.MakeFreeTypeFaceFromData(data);\n if (tf === null) {\n throw new Error(`Couldn't create typeface for ${familyName}`);\n }\n return [familyName, tf] as const;\n }\n );\n });\n });\n return Promise.all(promises);\n};\n\nexport const useFonts = (sources: Record<string, DataModule[]>) => {\n const [fontMgr, setFontMgr] = useState<null | SkTypefaceFontProvider>(null);\n\n useEffect(() => {\n loadTypefaces(sources).then((result) => {\n const fMgr = Skia.TypefaceFontProvider.Make();\n result.forEach(([familyName, typeface]) => {\n fMgr.registerFont(typeface, familyName);\n });\n setFontMgr(fMgr);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return fontMgr;\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["useEffect","useMemo","useState","Skia","FontSlant","Platform","useTypeface","defaultFontSize","useFont","font","size","onError","typeface","Font","defaultFontStyle","fontFamily","fontSize","fontStyle","fontWeight","slant","s","Italic","Oblique","Upright","weight","parseInt","matchFont","inputStyle","fontMgr","FontMgr","System","style","width","matchFamilyStyle","listFontFamilies","Array","countFamilies","fill","map","_","i","getFamilyName","loadTypefaces","typefacesToLoad","promises","Object","keys","flatMap","familyName","typefaceToLoad","Data","fromURI","resolveAsset","then","data","tf","Typeface","MakeFreeTypeFaceFromData","Error","Promise","all","useFonts","sources","setFontMgr","result","fMgr","TypefaceFontProvider","Make","forEach","registerFont"],"sources":["Font.ts"],"sourcesContent":["/*global SkiaApi*/\nimport { useEffect, useMemo, useState } from \"react\";\n\nimport { Skia } from \"../Skia\";\nimport { FontSlant } from \"../types\";\nimport type { DataModule, DataSourceParam, SkFontMgr } from \"../types\";\nimport { Platform } from \"../../Platform\";\nimport type { SkTypefaceFontProvider } from \"../types/Paragraph/TypefaceFontProvider\";\n\nimport { useTypeface } from \"./Typeface\";\n\nconst defaultFontSize = 14;\n\n/**\n * Returns a Skia Font object\n * */\nexport const useFont = (\n font: DataSourceParam,\n size = defaultFontSize,\n onError?: (err: Error) => void\n) => {\n const typeface = useTypeface(font, onError);\n return useMemo(() => {\n if (typeface) {\n return Skia.Font(typeface, size);\n } else {\n return null;\n }\n }, [size, typeface]);\n};\n\ntype Slant = \"normal\" | \"italic\" | \"oblique\";\ntype Weight =\n | \"normal\"\n | \"bold\"\n | \"100\"\n | \"200\"\n | \"300\"\n | \"400\"\n | \"500\"\n | \"600\"\n | \"700\"\n | \"800\"\n | \"900\";\n\ninterface RNFontStyle {\n fontFamily: string;\n fontSize: number;\n fontStyle: Slant;\n fontWeight: Weight;\n}\n\nconst defaultFontStyle: RNFontStyle = {\n fontFamily: \"System\",\n fontSize: defaultFontSize,\n fontStyle: \"normal\",\n fontWeight: \"normal\",\n};\n\nconst slant = (s: Slant) => {\n if (s === \"italic\") {\n return FontSlant.Italic;\n } else if (s === \"oblique\") {\n return FontSlant.Oblique;\n } else {\n return FontSlant.Upright;\n }\n};\n\nconst weight = (fontWeight: Weight) => {\n switch (fontWeight) {\n case \"normal\":\n return 400;\n case \"bold\":\n return 700;\n default:\n return parseInt(fontWeight, 10);\n }\n};\n\nexport const matchFont = (\n inputStyle: Partial<RNFontStyle> = {},\n fontMgr: SkFontMgr = Skia.FontMgr.System()\n) => {\n const fontStyle = {\n ...defaultFontStyle,\n ...inputStyle,\n };\n const style = {\n weight: weight(fontStyle.fontWeight),\n width: 5,\n slant: slant(fontStyle.fontStyle),\n };\n const typeface = fontMgr.matchFamilyStyle(fontStyle.fontFamily, style);\n return Skia.Font(typeface, fontStyle.fontSize);\n};\n\nexport const listFontFamilies = (fontMgr: SkFontMgr = Skia.FontMgr.System()) =>\n new Array(fontMgr.countFamilies())\n .fill(0)\n .map((_, i) => fontMgr.getFamilyName(i));\n\nconst loadTypefaces = (typefacesToLoad: Record<string, DataModule[]>) => {\n const promises = Object.keys(typefacesToLoad).flatMap((familyName) => {\n return typefacesToLoad[familyName].map((typefaceToLoad) => {\n return Skia.Data.fromURI(Platform.resolveAsset(typefaceToLoad)).then(\n (data) => {\n const tf = Skia.Typeface.MakeFreeTypeFaceFromData(data);\n if (tf === null) {\n throw new Error(`Couldn't create typeface for ${familyName}`);\n }\n return [familyName, tf] as const;\n }\n );\n });\n });\n return Promise.all(promises);\n};\n\nexport const useFonts = (sources: Record<string, DataModule[]>) => {\n const [fontMgr, setFontMgr] = useState<null | SkTypefaceFontProvider>(null);\n\n useEffect(() => {\n loadTypefaces(sources).then((result) => {\n const fMgr = Skia.TypefaceFontProvider.Make();\n result.forEach(([familyName, typeface]) => {\n fMgr.registerFont(typeface, familyName);\n });\n setFontMgr(fMgr);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return fontMgr;\n};\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import "./skia/NativeSetup";
2
+ export { JsiSkImage } from "./skia/web/JsiSkImage";
2
3
  export * from "./renderer";
3
4
  export * from "./renderer/Canvas";
4
5
  export * from "./renderer/Offscreen";
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "setup-skia-web": "./scripts/setup-canvaskit.js"
8
8
  },
9
9
  "title": "React Native Skia",
10
- "version": "0.1.211",
10
+ "version": "0.1.213",
11
11
  "description": "High-performance React Native Graphics using Skia",
12
12
  "main": "lib/module/index.js",
13
13
  "files": [
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import "./skia/NativeSetup";
2
+ export { JsiSkImage } from "./skia/web/JsiSkImage";
2
3
  export * from "./renderer";
3
4
  export * from "./renderer/Canvas";
4
5
  export * from "./renderer/Offscreen";
@@ -9,20 +9,20 @@ import type { SkTypefaceFontProvider } from "../types/Paragraph/TypefaceFontProv
9
9
 
10
10
  import { useTypeface } from "./Typeface";
11
11
 
12
+ const defaultFontSize = 14;
13
+
12
14
  /**
13
15
  * Returns a Skia Font object
14
16
  * */
15
17
  export const useFont = (
16
18
  font: DataSourceParam,
17
- size?: number,
19
+ size = defaultFontSize,
18
20
  onError?: (err: Error) => void
19
21
  ) => {
20
22
  const typeface = useTypeface(font, onError);
21
23
  return useMemo(() => {
22
- if (typeface && size) {
24
+ if (typeface) {
23
25
  return Skia.Font(typeface, size);
24
- } else if (typeface && !size) {
25
- return Skia.Font(typeface);
26
26
  } else {
27
27
  return null;
28
28
  }
@@ -52,7 +52,7 @@ interface RNFontStyle {
52
52
 
53
53
  const defaultFontStyle: RNFontStyle = {
54
54
  fontFamily: "System",
55
- fontSize: 14,
55
+ fontSize: defaultFontSize,
56
56
  fontStyle: "normal",
57
57
  fontWeight: "normal",
58
58
  };