@shopify/react-native-skia 0.1.211 → 0.1.213

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.
@@ -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
  };