@shopify/react-native-skia 1.5.3 → 1.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. package/android/CMakeLists.txt +53 -13
  2. package/android/build.gradle +3 -0
  3. package/android/cpp/rnskia-android/OpenGLContext.h +122 -11
  4. package/android/cpp/rnskia-android/OpenGLWindowContext.cpp +73 -0
  5. package/android/cpp/rnskia-android/OpenGLWindowContext.h +74 -0
  6. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +18 -1
  7. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +12 -1
  8. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +13 -1
  9. package/android/cpp/rnskia-android/opengl/Context.h +77 -0
  10. package/android/cpp/rnskia-android/opengl/Display.h +117 -0
  11. package/android/cpp/rnskia-android/opengl/Error.cpp +9 -0
  12. package/android/cpp/rnskia-android/opengl/Error.h +44 -0
  13. package/android/cpp/rnskia-android/opengl/Surface.h +43 -0
  14. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -1
  15. package/cpp/api/JsiSkImage.h +15 -2
  16. package/cpp/api/JsiSkSurface.h +18 -3
  17. package/cpp/rnskia/DawnContext.h +241 -0
  18. package/cpp/rnskia/DawnUtils.h +127 -0
  19. package/cpp/rnskia/DawnWindowContext.cpp +19 -0
  20. package/cpp/rnskia/DawnWindowContext.h +77 -0
  21. package/cpp/rnskia/ImageProvider.h +100 -0
  22. package/cpp/rnskia/RNSkView.h +6 -0
  23. package/cpp/skia/include/android/SkAnimatedImage.h +14 -0
  24. package/cpp/skia/include/codec/SkAvifDecoder.h +39 -3
  25. package/cpp/skia/include/codec/SkCodec.h +16 -0
  26. package/cpp/skia/include/config/SkUserConfig.h +3 -2
  27. package/cpp/skia/include/core/SkCanvas.h +55 -10
  28. package/cpp/skia/include/core/SkContourMeasure.h +76 -0
  29. package/cpp/skia/include/core/SkFontScanner.h +48 -0
  30. package/cpp/skia/include/core/SkMilestone.h +1 -1
  31. package/cpp/skia/include/core/SkPath.h +11 -0
  32. package/cpp/skia/include/core/SkPathEffect.h +0 -23
  33. package/cpp/skia/include/core/SkRect.h +2 -0
  34. package/cpp/skia/include/core/SkString.h +4 -0
  35. package/cpp/skia/include/core/SkTypeface.h +5 -0
  36. package/cpp/skia/include/core/SkTypes.h +8 -3
  37. package/cpp/skia/include/docs/SkPDFDocument.h +3 -3
  38. package/cpp/skia/include/effects/SkOverdrawColorFilter.h +1 -0
  39. package/cpp/skia/include/effects/SkRuntimeEffect.h +2 -1
  40. package/cpp/skia/include/encode/SkJpegEncoder.h +4 -0
  41. package/cpp/skia/include/gpu/ganesh/GrContextOptions.h +8 -1
  42. package/cpp/skia/include/gpu/ganesh/GrDirectContext.h +18 -3
  43. package/cpp/skia/include/gpu/ganesh/GrTypes.h +11 -0
  44. package/cpp/skia/include/gpu/ganesh/gl/GrGLFunctions.h +5 -1
  45. package/cpp/skia/include/gpu/ganesh/gl/GrGLInterface.h +0 -1
  46. package/cpp/skia/include/gpu/graphite/GraphiteTypes.h +8 -0
  47. package/cpp/skia/include/gpu/graphite/Recorder.h +0 -2
  48. package/cpp/skia/include/gpu/graphite/precompile/PaintOptions.h +7 -4
  49. package/cpp/skia/include/gpu/graphite/precompile/PrecompileImageFilter.h +2 -0
  50. package/cpp/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h +2 -0
  51. package/cpp/skia/include/ports/SkFontMgr_android_ndk.h +25 -0
  52. package/cpp/skia/include/ports/SkFontMgr_fontconfig.h +4 -2
  53. package/cpp/skia/include/ports/SkFontScanner_Fontations.h +15 -0
  54. package/cpp/skia/include/ports/SkFontScanner_FreeType.h +15 -0
  55. package/cpp/skia/include/private/SkExif.h +14 -0
  56. package/cpp/skia/include/private/SkPathRef.h +36 -0
  57. package/cpp/skia/include/private/base/SkFeatures.h +4 -0
  58. package/cpp/skia/include/private/base/SkSpan_impl.h +1 -3
  59. package/cpp/skia/modules/skcms/src/skcms_internals.h +3 -0
  60. package/cpp/skia/src/base/SkMathPriv.h +1 -8
  61. package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.h +1 -2
  62. package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +25 -19
  63. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +23 -0
  64. package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +4 -8
  65. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +26 -8
  66. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -20
  67. package/libs/android/arm64-v8a/libskia.a +0 -0
  68. package/libs/android/arm64-v8a/libskottie.a +0 -0
  69. package/libs/android/armeabi-v7a/libskia.a +0 -0
  70. package/libs/android/armeabi-v7a/libskottie.a +0 -0
  71. package/libs/android/x86/libskia.a +0 -0
  72. package/libs/android/x86/libskottie.a +0 -0
  73. package/libs/android/x86_64/libskia.a +0 -0
  74. package/libs/android/x86_64/libskottie.a +0 -0
  75. package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  76. package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  77. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
  78. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
  79. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
  80. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
  81. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
  82. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
  83. package/libs/ios/libskshaper.xcframework/Info.plist +5 -5
  84. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
  85. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
  86. package/libs/ios/libskunicode_core.xcframework/Info.plist +5 -5
  87. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
  88. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
  89. package/libs/ios/libskunicode_libgrapheme.xcframework/Info.plist +5 -5
  90. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
  91. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
  92. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
  93. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
  94. package/package.json +1 -1
  95. package/react-native-skia.podspec +35 -9
  96. package/src/renderer/__tests__/e2e/SVG.spec.tsx +2 -1
  97. package/android/cpp/rnskia-android/SkiaOpenGLHelper.h +0 -310
  98. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +0 -188
  99. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +0 -100
@@ -0,0 +1,77 @@
1
+ #pragma once
2
+
3
+ #include "DawnUtils.h"
4
+ #include "WindowContext.h"
5
+
6
+ #include "dawn/native/MetalBackend.h"
7
+ #include "webgpu/webgpu_cpp.h"
8
+
9
+ #include "include/core/SkColorSpace.h"
10
+
11
+ #include "include/gpu/graphite/BackendTexture.h"
12
+ #include "include/gpu/graphite/Context.h"
13
+ #include "include/gpu/graphite/ContextOptions.h"
14
+ #include "include/gpu/graphite/GraphiteTypes.h"
15
+ #include "include/gpu/graphite/Recorder.h"
16
+ #include "include/gpu/graphite/Recording.h"
17
+ #include "include/gpu/graphite/Surface.h"
18
+ #include "include/gpu/graphite/dawn/DawnBackendContext.h"
19
+ #include "include/gpu/graphite/dawn/DawnTypes.h"
20
+ #include "include/gpu/graphite/dawn/DawnUtils.h"
21
+
22
+ namespace RNSkia {
23
+
24
+ class DawnWindowContext : public WindowContext {
25
+ public:
26
+ DawnWindowContext(skgpu::graphite::Recorder *recorder, wgpu::Device device,
27
+ wgpu::Surface surface, int width, int height)
28
+ : _recorder(recorder), _device(device), _surface(surface), _width(width),
29
+ _height(height) {
30
+ wgpu::SurfaceConfiguration config;
31
+ config.device = _device;
32
+ config.format = DawnUtils::PreferredTextureFormat;
33
+ config.width = _width;
34
+ config.height = _height;
35
+ #ifdef __APPLE__
36
+ config.alphaMode = wgpu::CompositeAlphaMode::Premultiplied;
37
+ #endif
38
+ _surface.Configure(&config);
39
+ }
40
+
41
+ sk_sp<SkSurface> getSurface() override {
42
+ wgpu::SurfaceTexture surfaceTexture;
43
+ _surface.GetCurrentTexture(&surfaceTexture);
44
+ auto texture = surfaceTexture.texture;
45
+ skgpu::graphite::DawnTextureInfo info(
46
+ /*sampleCount=*/1, skgpu::Mipmapped::kNo,
47
+ DawnUtils::PreferredTextureFormat, texture.GetUsage(),
48
+ wgpu::TextureAspect::All);
49
+ auto backendTex = skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
50
+ sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
51
+ SkSurfaceProps surfaceProps;
52
+ auto surface = SkSurfaces::WrapBackendTexture(_recorder, backendTex,
53
+ DawnUtils::PreferedColorType,
54
+ colorSpace, &surfaceProps);
55
+ return surface;
56
+ }
57
+
58
+ void present() override;
59
+
60
+ void resize(int width, int height) override {
61
+ throw std::runtime_error("resize not implemented yet");
62
+ }
63
+
64
+ int getWidth() override { return _width; }
65
+
66
+ int getHeight() override { return _height; }
67
+
68
+ private:
69
+ skgpu::graphite::Recorder *_recorder;
70
+ // TODO: keep device in DawnContext? Do we need it for resizing?
71
+ wgpu::Device _device;
72
+ wgpu::Surface _surface;
73
+ int _width;
74
+ int _height;
75
+ };
76
+
77
+ } // namespace RNSkia
@@ -0,0 +1,100 @@
1
+ #pragma once
2
+
3
+ #include "include/core/SkCanvas.h"
4
+ #include "include/core/SkImage.h"
5
+
6
+ #include "include/core/SkTiledImageUtils.h"
7
+ #include "include/gpu/graphite/Image.h"
8
+ #include "include/gpu/graphite/ImageProvider.h"
9
+ #include "include/gpu/graphite/Recorder.h"
10
+ #include "src/core/SkLRUCache.h"
11
+
12
+ namespace RNSkia {
13
+
14
+ // Currently, we give each new Recorder its own ImageProvider. This means we
15
+ // don't have to deal w/ any threading issues.
16
+ // TODO: We should probably have this class generate and report some cache stats
17
+ // TODO: Hook up to listener system?
18
+ // TODO: add testing of a single ImageProvider passed to multiple recorders
19
+ class ImageProvider : public skgpu::graphite::ImageProvider {
20
+ public:
21
+ ImageProvider() : fCache(kDefaultNumCachedImages) {}
22
+ ~ImageProvider() override {}
23
+
24
+ static sk_sp<ImageProvider> Make() { return sk_ref_sp(new ImageProvider); }
25
+
26
+ sk_sp<SkImage>
27
+ findOrCreate(skgpu::graphite::Recorder *recorder, const SkImage *image,
28
+ SkImage::RequiredProperties requiredProps) override {
29
+ if (!requiredProps.fMipmapped) {
30
+ // If no mipmaps are required, check to see if we have a mipmapped version
31
+ // anyway - since it can be used in that case.
32
+ // TODO: we could get fancy and, if ever a mipmapped key eclipsed a
33
+ // non-mipmapped key, we could remove the hidden non-mipmapped key/image
34
+ // from the cache.
35
+ ImageKey mipMappedKey(image, /* mipmapped= */ true);
36
+ auto result = fCache.find(mipMappedKey);
37
+ if (result) {
38
+ return *result;
39
+ }
40
+ }
41
+
42
+ ImageKey key(image, requiredProps.fMipmapped);
43
+
44
+ auto result = fCache.find(key);
45
+ if (result) {
46
+ return *result;
47
+ }
48
+
49
+ sk_sp<SkImage> newImage =
50
+ SkImages::TextureFromImage(recorder, image, requiredProps);
51
+ if (!newImage) {
52
+ return nullptr;
53
+ }
54
+
55
+ result = fCache.insert(key, std::move(newImage));
56
+ SkASSERT(result);
57
+
58
+ return *result;
59
+ }
60
+
61
+ private:
62
+ static constexpr int kDefaultNumCachedImages = 256;
63
+
64
+ class ImageKey {
65
+ public:
66
+ ImageKey(const SkImage *image, bool mipmapped) {
67
+ uint32_t flags = mipmapped ? 0x1 : 0x0;
68
+ SkTiledImageUtils::GetImageKeyValues(image, &fValues[1]);
69
+ fValues[kNumValues - 1] = flags;
70
+ fValues[0] =
71
+ SkChecksum::Hash32(&fValues[1], (kNumValues - 1) * sizeof(uint32_t));
72
+ }
73
+
74
+ uint32_t hash() const { return fValues[0]; }
75
+
76
+ bool operator==(const ImageKey &other) const {
77
+ for (int i = 0; i < kNumValues; ++i) {
78
+ if (fValues[i] != other.fValues[i]) {
79
+ return false;
80
+ }
81
+ }
82
+
83
+ return true;
84
+ }
85
+ bool operator!=(const ImageKey &other) const { return !(*this == other); }
86
+
87
+ private:
88
+ static const int kNumValues = SkTiledImageUtils::kNumImageKeyValues + 2;
89
+
90
+ uint32_t fValues[kNumValues];
91
+ };
92
+
93
+ struct ImageHash {
94
+ size_t operator()(const ImageKey &key) const { return key.hash(); }
95
+ };
96
+
97
+ SkLRUCache<ImageKey, sk_sp<SkImage>, ImageHash> fCache;
98
+ };
99
+
100
+ } // namespace RNSkia
@@ -108,7 +108,13 @@ public:
108
108
  } else {
109
109
  image = _surface->makeImageSnapshot();
110
110
  }
111
+ #if defined(SK_GRAPHITE)
112
+ DawnContext::getInstance().submitRecording(
113
+ _surface->recorder()->snap().get());
114
+ return DawnContext::getInstance().MakeRasterImage(image);
115
+ #else
111
116
  return image->makeNonTextureImage();
117
+ #endif
112
118
  }
113
119
 
114
120
  /**
@@ -110,6 +110,19 @@ public:
110
110
  */
111
111
  int getFrameCount() const { return fFrameCount; }
112
112
 
113
+ /**
114
+ * Change the filter mode.
115
+ *
116
+ * By default, the image will apply bilinear filtering when drawing in the
117
+ * OnDraw method.
118
+ */
119
+ void setFilterMode(SkFilterMode filterMode);
120
+
121
+ /**
122
+ * Return the filter mode used for sampling when drawing.
123
+ */
124
+ SkFilterMode getFilterMode() const { return fFilterMode; }
125
+
113
126
  protected:
114
127
  SkRect onGetBounds() override;
115
128
  void onDraw(SkCanvas*) override;
@@ -152,6 +165,7 @@ private:
152
165
  Frame fRestoreFrame;
153
166
  int fRepetitionCount;
154
167
  int fRepetitionsCompleted;
168
+ SkFilterMode fFilterMode = SkFilterMode::kLinear;
155
169
 
156
170
  SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, const SkImageInfo& requestedInfo,
157
171
  SkIRect cropRect, sk_sp<SkPicture> postProcess);
@@ -18,13 +18,15 @@ class SkStream;
18
18
 
19
19
  namespace SkAvifDecoder {
20
20
 
21
- /** Returns true if this data claims to be a AVIF image. */
21
+ namespace LibAvif {
22
+
23
+ /** Returns true if this data claims to be an AVIF image. */
22
24
  SK_API bool IsAvif(const void*, size_t);
23
25
 
24
26
  /**
25
- * Attempts to decode the given bytes as a AVIF.
27
+ * Attempts to decode the given bytes as an AVIF.
26
28
  *
27
- * If the bytes are not a AVIF, returns nullptr.
29
+ * If the bytes are not an AVIF, returns nullptr.
28
30
  *
29
31
  * DecodeContext is ignored
30
32
  */
@@ -39,6 +41,40 @@ inline constexpr SkCodecs::Decoder Decoder() {
39
41
  return { "avif", IsAvif, Decode };
40
42
  }
41
43
 
44
+ } // namespace LibAvif
45
+
46
+ // This function is in the root SkAvifDecoder namespace. It simply routes
47
+ // everything through the LibAvif namespace and exists for backwards
48
+ // compatibility.
49
+ inline constexpr SkCodecs::Decoder Decoder() {
50
+ return { "avif", LibAvif::IsAvif, LibAvif::Decode };
51
+ }
52
+
53
+ namespace CrabbyAvif {
54
+
55
+ /** Returns true if this data claims to be an AVIF image. */
56
+ SK_API bool IsAvif(const void*, size_t);
57
+
58
+ /**
59
+ * Attempts to decode the given bytes as an AVIF.
60
+ *
61
+ * If the bytes are not an AVIF, returns nullptr.
62
+ *
63
+ * DecodeContext is ignored
64
+ */
65
+ SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
66
+ SkCodec::Result*,
67
+ SkCodecs::DecodeContext = nullptr);
68
+ SK_API std::unique_ptr<SkCodec> Decode(sk_sp<SkData>,
69
+ SkCodec::Result*,
70
+ SkCodecs::DecodeContext = nullptr);
71
+
72
+ inline constexpr SkCodecs::Decoder Decoder() {
73
+ return { "avif", IsAvif, Decode };
74
+ }
75
+
76
+ } // namespace CrabbyAvif
77
+
42
78
  } // namespace SkAvifDecoder
43
79
 
44
80
  #endif // SkAvifDecoder_DEFINED
@@ -239,6 +239,16 @@ public:
239
239
  return this->getEncodedInfo().profile();
240
240
  }
241
241
 
242
+ /**
243
+ * Whether the encoded input uses 16 or more bits per component.
244
+ */
245
+ bool hasHighBitDepthEncodedData() const {
246
+ // API design note: We don't return `bitsPerComponent` because it may be
247
+ // misleading in some cases - see https://crbug.com/359350061#comment4
248
+ // for more details.
249
+ return this->getEncodedInfo().bitsPerComponent() >= 16;
250
+ }
251
+
242
252
  /**
243
253
  * Returns the image orientation stored in the EXIF data.
244
254
  * If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft.
@@ -637,6 +647,12 @@ public:
637
647
  * Return the number of frames in the image.
638
648
  *
639
649
  * May require reading through the stream.
650
+ *
651
+ * Note that some codecs may be unable to gather `FrameInfo` for all frames
652
+ * in case of `kIncompleteInput`. For such codecs `getFrameCount` may
653
+ * initially report a low frame count. After the underlying `SkStream`
654
+ * provides additional data, then calling `getFrameCount` again may return
655
+ * an updated, increased frame count.
640
656
  */
641
657
  int getFrameCount() {
642
658
  return this->onGetFrameCount();
@@ -90,9 +90,10 @@
90
90
  integrate with their histogram collection backend.
91
91
  */
92
92
  //#define SK_HISTOGRAM_BOOLEAN(name, sample)
93
- //#define SK_HISTOGRAM_ENUMERATION(name, sample, enum_size)
94
- //#define SK_HISTOGRAM_EXACT_LINEAR(name, sample, value_max)
93
+ //#define SK_HISTOGRAM_ENUMERATION(name, sampleEnum, enumSize)
94
+ //#define SK_HISTOGRAM_EXACT_LINEAR(name, sample, valueMax)
95
95
  //#define SK_HISTOGRAM_MEMORY_KB(name, sample)
96
+ //#define SK_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(name, sampleUSec, minUSec, maxUSec, bucketCount)
96
97
 
97
98
  // To use smaller but slower mipmap builder
98
99
  //#define SK_USE_DRAWING_MIPMAP_DOWNSAMPLER
@@ -28,6 +28,7 @@
28
28
  #include "include/core/SkSpan.h"
29
29
  #include "include/core/SkString.h"
30
30
  #include "include/core/SkSurfaceProps.h"
31
+ #include "include/core/SkTileMode.h"
31
32
  #include "include/core/SkTypes.h"
32
33
  #include "include/private/base/SkCPUTypes.h"
33
34
  #include "include/private/base/SkDeque.h"
@@ -700,7 +701,8 @@ public:
700
701
  @return SaveLayerRec with empty fBackdrop
701
702
  */
702
703
  SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
703
- : SaveLayerRec(bounds, paint, nullptr, nullptr, 1.f, saveLayerFlags, /*filters=*/{}) {}
704
+ : SaveLayerRec(bounds, paint, nullptr, nullptr, 1.f, SkTileMode::kClamp,
705
+ saveLayerFlags, /*filters=*/{}) {}
704
706
 
705
707
  /** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
706
708
 
@@ -716,9 +718,10 @@ public:
716
718
  */
717
719
  SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
718
720
  SaveLayerFlags saveLayerFlags)
719
- : SaveLayerRec(bounds, paint, backdrop, nullptr, 1.f, saveLayerFlags, /*filters=*/{}) {}
721
+ : SaveLayerRec(bounds, paint, backdrop, nullptr, 1.f, SkTileMode::kClamp,
722
+ saveLayerFlags, /*filters=*/{}) {}
720
723
 
721
- /** Sets fBounds, fColorSpace, and fSaveLayerFlags.
724
+ /** Sets fBounds, fBackdrop, fColorSpace, and fSaveLayerFlags.
722
725
 
723
726
  @param bounds layer dimensions; may be nullptr
724
727
  @param paint applied to layer when overlaying prior layer;
@@ -738,15 +741,44 @@ public:
738
741
  */
739
742
  SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
740
743
  const SkColorSpace* colorSpace, SaveLayerFlags saveLayerFlags)
741
- : SaveLayerRec(bounds, paint, backdrop, colorSpace, 1.f, saveLayerFlags, /*filters=*/{}) {}
744
+ : SaveLayerRec(bounds, paint, backdrop, colorSpace, 1.f, SkTileMode::kClamp,
745
+ saveLayerFlags, /*filters=*/{}) {}
746
+
747
+
748
+ /** Sets fBounds, fBackdrop, fBackdropTileMode, fColorSpace, and fSaveLayerFlags.
749
+
750
+ @param bounds layer dimensions; may be nullptr
751
+ @param paint applied to layer when overlaying prior layer;
752
+ may be nullptr
753
+ @param backdrop If not null, this causes the current layer to be filtered by
754
+ backdrop, and then drawn into the new layer
755
+ (respecting the current clip).
756
+ If null, the new layer is initialized with transparent-black.
757
+ @param backdropTileMode If the 'backdrop' is not null, or 'saveLayerFlags' has
758
+ kInitWithPrevious set, this tile mode is used when the new layer
759
+ would read outside the backdrop image's available content.
760
+ @param colorSpace If not null, when the layer is restored, a color space
761
+ conversion will be applied from this color space to the parent's
762
+ color space. The restore paint and backdrop filters will be
763
+ applied in this color space.
764
+ If null, the new layer will inherit the color space from its
765
+ parent.
766
+ @param saveLayerFlags SaveLayerRec options to modify layer
767
+ @return SaveLayerRec fully specified
768
+ */
769
+ SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
770
+ SkTileMode backdropTileMode, const SkColorSpace* colorSpace,
771
+ SaveLayerFlags saveLayerFlags)
772
+ : SaveLayerRec(bounds, paint, backdrop, colorSpace, 1.f, backdropTileMode,
773
+ saveLayerFlags, /*filters=*/{}) {}
742
774
 
743
775
  /** hints at layer size limit */
744
- const SkRect* fBounds = nullptr;
776
+ const SkRect* fBounds = nullptr;
745
777
 
746
778
  /** modifies overlay */
747
- const SkPaint* fPaint = nullptr;
779
+ const SkPaint* fPaint = nullptr;
748
780
 
749
- FilterSpan fFilters = {};
781
+ FilterSpan fFilters = {};
750
782
 
751
783
  /**
752
784
  * If not null, this triggers the same initialization behavior as setting
@@ -754,17 +786,24 @@ public:
754
786
  * the new layer, rather than initializing the new layer with transparent-black.
755
787
  * This is then filtered by fBackdrop (respecting the current clip).
756
788
  */
757
- const SkImageFilter* fBackdrop = nullptr;
789
+ const SkImageFilter* fBackdrop = nullptr;
790
+
791
+ /**
792
+ * If the layer is initialized with prior content (and/or with a backdrop filter) and this
793
+ * would require sampling outside of the available backdrop, this is the tilemode applied
794
+ * to the boundary of the prior layer's image.
795
+ */
796
+ SkTileMode fBackdropTileMode = SkTileMode::kClamp;
758
797
 
759
798
  /**
760
799
  * If not null, this triggers a color space conversion when the layer is restored. It
761
800
  * will be as if the layer's contents are drawn in this color space. Filters from
762
801
  * fBackdrop and fPaint will be applied in this color space.
763
802
  */
764
- const SkColorSpace* fColorSpace = nullptr;
803
+ const SkColorSpace* fColorSpace = nullptr;
765
804
 
766
805
  /** preserves LCD text, creates with prior layer contents */
767
- SaveLayerFlags fSaveLayerFlags = 0;
806
+ SaveLayerFlags fSaveLayerFlags = 0;
768
807
 
769
808
  private:
770
809
  friend class SkCanvas;
@@ -775,12 +814,14 @@ public:
775
814
  const SkImageFilter* backdrop,
776
815
  const SkColorSpace* colorSpace,
777
816
  SkScalar backdropScale,
817
+ SkTileMode backdropTileMode,
778
818
  SaveLayerFlags saveLayerFlags,
779
819
  FilterSpan filters)
780
820
  : fBounds(bounds)
781
821
  , fPaint(paint)
782
822
  , fFilters(filters)
783
823
  , fBackdrop(backdrop)
824
+ , fBackdropTileMode(backdropTileMode)
784
825
  , fColorSpace(colorSpace)
785
826
  , fSaveLayerFlags(saveLayerFlags)
786
827
  , fExperimentalBackdropScale(backdropScale) {
@@ -2591,12 +2632,16 @@ private:
2591
2632
  * before any filtering, or as part of the copy, and is then drawn with 1/scaleFactor to 'dst'.
2592
2633
  * Must be 1.0 if 'compat' is kYes (i.e. any scale factor has already been baked into the
2593
2634
  * relative transforms between the devices).
2635
+ *
2636
+ * 'srcTileMode' is the tile mode to apply to the boundary of the 'src' image when insufficient
2637
+ * content is available. It defaults to kDecal for the regular saveLayer() case.
2594
2638
  */
2595
2639
  void internalDrawDeviceWithFilter(SkDevice* src, SkDevice* dst,
2596
2640
  FilterSpan filters, const SkPaint& paint,
2597
2641
  DeviceCompatibleWithFilter compat,
2598
2642
  const SkColorInfo& filterColorInfo,
2599
2643
  SkScalar scaleFactor = 1.f,
2644
+ SkTileMode srcTileMode = SkTileMode::kDecal,
2600
2645
  bool srcIsCoverageLayer = false);
2601
2646
 
2602
2647
  /*
@@ -11,13 +11,17 @@
11
11
  #include "include/core/SkPoint.h"
12
12
  #include "include/core/SkRefCnt.h"
13
13
  #include "include/core/SkScalar.h"
14
+ #include "include/core/SkSpan.h"
14
15
  #include "include/private/base/SkAPI.h"
16
+ #include "include/private/base/SkAssert.h"
15
17
  #include "include/private/base/SkTDArray.h"
16
18
 
19
+ #include <cstddef>
17
20
  #include <memory>
18
21
 
19
22
  class SkMatrix;
20
23
  class SkPath;
24
+ enum class SkPathVerb;
21
25
 
22
26
  class SK_API SkContourMeasure : public SkRefCnt {
23
27
  public:
@@ -57,6 +61,78 @@ public:
57
61
  */
58
62
  bool isClosed() const { return fIsClosed; }
59
63
 
64
+ /** Measurement data for individual verbs.
65
+ */
66
+ struct VerbMeasure {
67
+ SkScalar fDistance; // Cumulative distance along the current contour.
68
+ SkPathVerb fVerb; // Verb type.
69
+ SkSpan<const SkPoint> fPts; // Verb points.
70
+ };
71
+
72
+ private:
73
+ struct Segment;
74
+
75
+ public:
76
+ /** Utility for iterating over the current contour verbs:
77
+ *
78
+ * for (const auto verb_measure : contour_measure) {
79
+ * ...
80
+ * }
81
+ */
82
+ class ForwardVerbIterator final {
83
+ public:
84
+ VerbMeasure operator*() const;
85
+
86
+ ForwardVerbIterator& operator++() {
87
+ SkASSERT(!fSegments.empty());
88
+
89
+ fSegments = LastSegForCurrentVerb(fSegments.subspan(1));
90
+
91
+ return *this;
92
+ }
93
+
94
+ bool operator==(const ForwardVerbIterator& other) {
95
+ SkASSERT(fSegments.data() != other.fSegments.data() ||
96
+ fSegments.size() == other.fSegments.size());
97
+ return fSegments.data() == other.fSegments.data();
98
+ }
99
+
100
+ bool operator!=(const ForwardVerbIterator& other) {
101
+ return !((*this) == other);
102
+ }
103
+
104
+ private:
105
+ friend class SkContourMeasure;
106
+
107
+ ForwardVerbIterator(SkSpan<const Segment> segs, SkSpan<const SkPoint> pts)
108
+ : fSegments(LastSegForCurrentVerb(segs))
109
+ , fPts(pts) {}
110
+
111
+ static SkSpan<const Segment> LastSegForCurrentVerb(const SkSpan<const Segment>& segs) {
112
+ size_t i = 1;
113
+ while (i < segs.size() && segs[0].fPtIndex == segs[i].fPtIndex) {
114
+ ++i;
115
+ }
116
+
117
+ return segs.subspan(i - 1);
118
+ }
119
+
120
+ // Remaining segments for forward iteration. The first segment in the span is
121
+ // adjusted to always point to the last segment of the current verb, such that its distance
122
+ // corresponds to the verb distance.
123
+ SkSpan<const Segment> fSegments;
124
+
125
+ // All path points (indexed in segments).
126
+ SkSpan<const SkPoint> fPts;
127
+ };
128
+
129
+ ForwardVerbIterator begin() const {
130
+ return ForwardVerbIterator(fSegments, fPts);
131
+ }
132
+ ForwardVerbIterator end() const {
133
+ return ForwardVerbIterator(SkSpan(fSegments.end(), 0), fPts);
134
+ }
135
+
60
136
  private:
61
137
  struct Segment {
62
138
  SkScalar fDistance; // total distance up to this point
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright 2024 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 SKFONTSCANNER_H_
9
+ #define SKFONTSCANNER_H_
10
+
11
+ #include "include/core/SkFontArguments.h"
12
+ #include "include/core/SkRefCnt.h"
13
+ #include "include/core/SkTypes.h"
14
+ #include "include/private/base/SkFixed.h"
15
+ #include "include/private/base/SkNoncopyable.h"
16
+ #include "include/private/base/SkTArray.h"
17
+ class SkFontStyle;
18
+ class SkStreamAsset;
19
+ class SkString;
20
+ class SkTypeface;
21
+
22
+ class SkFontScanner : public SkNoncopyable {
23
+ public:
24
+ virtual ~SkFontScanner() = default;
25
+ struct AxisDefinition {
26
+ SkFourByteTag fTag;
27
+ SkScalar fMinimum;
28
+ SkScalar fDefault;
29
+ SkScalar fMaximum;
30
+ };
31
+ typedef skia_private::STArray<4, AxisDefinition, true> AxisDefinitions;
32
+
33
+ virtual bool scanFile(SkStreamAsset* stream, int* numFaces) const = 0;
34
+ virtual bool scanFace(SkStreamAsset* stream, int faceIndex, int* numInstances) const = 0;
35
+ /* instanceIndex 0 is the default instance, 1 to numInstances are the named instances. */
36
+ virtual bool scanInstance(SkStreamAsset* stream,
37
+ int faceIndex,
38
+ int instanceIndex,
39
+ SkString* name,
40
+ SkFontStyle* style,
41
+ bool* isFixedPitch,
42
+ AxisDefinitions* axes) const = 0;
43
+ virtual sk_sp<SkTypeface> MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
44
+ const SkFontArguments& args) const = 0;
45
+ virtual SkFourByteTag getFactoryId() const = 0;
46
+ };
47
+
48
+ #endif // SKFONTSCANNER_H_
@@ -5,5 +5,5 @@
5
5
  * found in the LICENSE file.
6
6
  */
7
7
  #ifndef SK_MILESTONE
8
- #define SK_MILESTONE 130
8
+ #define SK_MILESTONE 132
9
9
  #endif
@@ -26,6 +26,7 @@
26
26
  #include <tuple>
27
27
  #include <type_traits>
28
28
 
29
+ struct SkArc;
29
30
  class SkData;
30
31
  class SkPathRef;
31
32
  class SkRRect;
@@ -280,6 +281,16 @@ public:
280
281
  */
281
282
  bool isRRect(SkRRect* rrect) const;
282
283
 
284
+ /** Returns true if path is representable as an oval arc. In other words, could this
285
+ path be drawn using SkCanvas::drawArc.
286
+
287
+ arc receives parameters of arc
288
+
289
+ @param arc storage for arc; may be nullptr
290
+ @return true if SkPath contains only a single arc from an oval
291
+ */
292
+ bool isArc(SkArc* arc) const;
293
+
283
294
  /** Sets SkPath to its initial state.
284
295
  Removes verb array, SkPoint array, and weights, and sets FillType to kWinding.
285
296
  Internal storage associated with SkPath is released.