@shopify/react-native-skia 2.12.0-next.1 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/LICENSE.md +2 -1
  2. package/Package.swift +117 -0
  3. package/android/CMakeLists.txt +23 -179
  4. package/android/build.gradle +40 -209
  5. package/android/cpp/jni/JniSkiaManager.cpp +3 -45
  6. package/android/cpp/jni/include/JniPlatformContext.h +1 -1
  7. package/android/cpp/jni/include/JniSkiaBaseView.h +18 -11
  8. package/android/cpp/jni/include/JniSkiaManager.h +3 -4
  9. package/android/cpp/jni/include/JniSkiaPictureView.h +5 -5
  10. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +0 -10
  11. package/android/cpp/rnskia-android/RNSkAndroidView.h +6 -6
  12. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +4 -4
  13. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +2 -2
  14. package/android/src/main/AndroidManifest.xml +1 -1
  15. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/PlatformContext.java +1 -1
  16. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkVideo.java +1 -1
  17. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkiaModule.java +1 -8
  18. package/android/src/main/java/com/reactnative/skia/RNSkiaPackage.java +57 -0
  19. package/android/src/main/java/com/reactnative/skia/SkiaBaseView.java +185 -0
  20. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaBaseViewManager.java +20 -1
  21. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaManager.java +11 -6
  22. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureView.java +3 -3
  23. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureViewManager.java +1 -1
  24. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaSurfaceView.java +13 -3
  25. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaTextureView.java +5 -3
  26. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaViewAPI.java +1 -1
  27. package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/ViewScreenshotService.java +10 -13
  28. package/apple/MetalContext.mm +1 -1
  29. package/apple/RNSkApplePlatformContext.h +0 -3
  30. package/apple/RNSkApplePlatformContext.mm +0 -11
  31. package/apple/RNSkiaModule.h +1 -10
  32. package/apple/RNSkiaModule.mm +2 -10
  33. package/apple/SkiaManager.h +0 -2
  34. package/apple/SkiaManager.mm +4 -6
  35. package/apple/SkiaPictureView.h +2 -2
  36. package/apple/SkiaPictureView.mm +0 -4
  37. package/apple/SkiaUIView.h +3 -18
  38. package/apple/SkiaUIView.mm +0 -30
  39. package/cpp/api/CustomBlendModes.h +17 -0
  40. package/cpp/api/JsiSkApi.h +0 -6
  41. package/cpp/api/JsiSkCanvas.h +19 -10
  42. package/cpp/api/JsiSkFont.h +5 -10
  43. package/cpp/api/JsiSkMatrix.h +4 -2
  44. package/cpp/api/JsiSkSVGFactory.h +4 -0
  45. package/cpp/api/recorder/Convertor.h +5 -2
  46. package/cpp/api/recorder/Drawings.h +13 -3
  47. package/cpp/api/recorder/ImageFilters.h +15 -1
  48. package/cpp/api/recorder/Paint.h +8 -1
  49. package/cpp/jsi/JSICache.cpp +99 -0
  50. package/cpp/jsi/JSICache.h +90 -0
  51. package/cpp/jsi/NativeObject.h +38 -87
  52. package/cpp/jsi/ViewProperty.h +0 -28
  53. package/cpp/rnskia/RNDawnContext.h +2 -1
  54. package/cpp/rnskia/RNDawnWindowContext.h +22 -0
  55. package/cpp/rnskia/RNSkManager.cpp +0 -6
  56. package/cpp/rnskia/RNSkPlatformContext.h +0 -3
  57. package/cpp/skia/include/core/RasterContext.h +25 -0
  58. package/cpp/skia/include/core/SkCanvas.h +0 -1
  59. package/cpp/skia/include/core/SkContext.h +62 -0
  60. package/cpp/skia/include/core/SkContextOptions.h +15 -0
  61. package/cpp/skia/include/core/SkMilestone.h +1 -1
  62. package/cpp/skia/include/core/SkPicture.h +36 -18
  63. package/cpp/skia/include/core/SkRecorder.h +8 -0
  64. package/cpp/skia/include/core/SkSerialProcs.h +2 -6
  65. package/cpp/skia/include/effects/SkImageFilters.h +15 -2
  66. package/cpp/skia/include/gpu/ganesh/GrDirectContext.h +73 -47
  67. package/cpp/skia/include/gpu/ganesh/SkSurfaceGanesh.h +7 -4
  68. package/cpp/skia/include/gpu/ganesh/d3d/GrD3DDirectContext.h +12 -0
  69. package/cpp/skia/include/gpu/ganesh/gl/GrGLDirectContext.h +11 -0
  70. package/cpp/skia/include/gpu/ganesh/mtl/GrMtlDirectContext.h +11 -0
  71. package/cpp/skia/include/gpu/ganesh/vk/GrVkDirectContext.h +13 -0
  72. package/cpp/skia/include/gpu/graphite/ContextOptions.h +6 -0
  73. package/cpp/skia/include/gpu/graphite/GraphiteTypes.h +5 -4
  74. package/cpp/skia/include/gpu/graphite/PrecompileContext.h +9 -1
  75. package/cpp/skia/include/gpu/graphite/Recorder.h +0 -2
  76. package/cpp/skia/include/gpu/graphite/Recording.h +3 -0
  77. package/cpp/skia/include/gpu/graphite/dawn/DawnBackendContext.h +8 -0
  78. package/cpp/skia/include/gpu/graphite/mtl/MtlBackendContext.h +11 -0
  79. package/cpp/skia/include/gpu/graphite/vk/VulkanGraphiteContext.h +11 -0
  80. package/cpp/skia/include/private/SkLog.h +1 -19
  81. package/cpp/skia/include/private/chromium/GrVkSecondaryCBDrawContext.h +2 -1
  82. package/cpp/skia/include/utils/SkLogHandler.h +53 -0
  83. package/cpp/skia/include/utils/SkNWayCanvas.h +1 -0
  84. package/cpp/skia/modules/skcms/src/Transform_inl.h +9 -10
  85. package/cpp/skia/modules/skcms/src/skcms_internals.h +8 -3
  86. package/cpp/skia/modules/skottie/include/SkottieProperty.h +2 -0
  87. package/cpp/skia/modules/skottie/include/TextShaper.h +1 -0
  88. package/cpp/skia/modules/skshaper/include/SkShaper.h +23 -1
  89. package/include/ReactNativeSkia.h +6 -0
  90. package/lib/commonjs/dom/nodes/datatypes/Rect.js +5 -1
  91. package/lib/commonjs/dom/nodes/datatypes/Rect.js.map +1 -1
  92. package/lib/commonjs/external/reanimated/useVideo.js +8 -2
  93. package/lib/commonjs/external/reanimated/useVideo.js.map +1 -1
  94. package/lib/commonjs/mock/index.js +0 -1
  95. package/lib/commonjs/mock/index.js.map +1 -1
  96. package/lib/commonjs/renderer/Canvas.d.ts +11 -3
  97. package/lib/commonjs/renderer/Canvas.js +8 -6
  98. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  99. package/lib/commonjs/renderer/components/Mask.js +3 -9
  100. package/lib/commonjs/renderer/components/Mask.js.map +1 -1
  101. package/lib/commonjs/skia/types/JsiInstance.d.ts +1 -0
  102. package/lib/commonjs/skia/types/JsiInstance.js.map +1 -1
  103. package/lib/commonjs/skia/types/Matrix4.js +7 -2
  104. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  105. package/lib/commonjs/skia/types/Skia.d.ts +1 -6
  106. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  107. package/lib/commonjs/skia/web/JsiSkCanvas.js +12 -7
  108. package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
  109. package/lib/commonjs/skia/web/JsiSkImage.js +6 -3
  110. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  111. package/lib/commonjs/skia/web/JsiSkPathBuilder.d.ts +1 -1
  112. package/lib/commonjs/skia/web/JsiSkPathBuilder.js +2 -2
  113. package/lib/commonjs/skia/web/JsiSkPathBuilder.js.map +1 -1
  114. package/lib/commonjs/skia/web/JsiSkTextStyle.js +5 -5
  115. package/lib/commonjs/skia/web/JsiSkTextStyle.js.map +1 -1
  116. package/lib/commonjs/skia/web/JsiSkia.js +0 -3
  117. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  118. package/lib/commonjs/skia/web/JsiSkottieAnimation.js +8 -8
  119. package/lib/commonjs/skia/web/JsiSkottieAnimation.js.map +1 -1
  120. package/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +1 -0
  121. package/lib/commonjs/sksg/Recorder/DrawingContext.js +15 -0
  122. package/lib/commonjs/sksg/Recorder/DrawingContext.js.map +1 -1
  123. package/lib/commonjs/sksg/Recorder/Player.js +1 -1
  124. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  125. package/lib/commonjs/sksg/Recorder/Visitor.js +6 -1
  126. package/lib/commonjs/sksg/Recorder/Visitor.js.map +1 -1
  127. package/lib/commonjs/sksg/Recorder/commands/Drawing.js +12 -9
  128. package/lib/commonjs/sksg/Recorder/commands/Drawing.js.map +1 -1
  129. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js +15 -1
  130. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  131. package/lib/commonjs/sksg/Recorder/commands/Shaders.js +1 -1
  132. package/lib/commonjs/sksg/Recorder/commands/Shaders.js.map +1 -1
  133. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
  134. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  135. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
  136. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js +3 -0
  137. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js.map +1 -1
  138. package/lib/commonjs/views/SkiaPictureView.js +2 -12
  139. package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
  140. package/lib/commonjs/views/SkiaPictureView.web.js +247 -57
  141. package/lib/commonjs/views/SkiaPictureView.web.js.map +1 -1
  142. package/lib/commonjs/views/types.d.ts +19 -8
  143. package/lib/commonjs/views/types.js.map +1 -1
  144. package/lib/module/dom/nodes/datatypes/Rect.js +5 -1
  145. package/lib/module/dom/nodes/datatypes/Rect.js.map +1 -1
  146. package/lib/module/external/reanimated/useVideo.js +8 -2
  147. package/lib/module/external/reanimated/useVideo.js.map +1 -1
  148. package/lib/module/mock/index.js +0 -1
  149. package/lib/module/mock/index.js.map +1 -1
  150. package/lib/module/renderer/Canvas.d.ts +11 -3
  151. package/lib/module/renderer/Canvas.js +7 -5
  152. package/lib/module/renderer/Canvas.js.map +1 -1
  153. package/lib/module/renderer/components/Mask.js +3 -9
  154. package/lib/module/renderer/components/Mask.js.map +1 -1
  155. package/lib/module/skia/types/JsiInstance.d.ts +1 -0
  156. package/lib/module/skia/types/JsiInstance.js.map +1 -1
  157. package/lib/module/skia/types/Matrix4.js +7 -2
  158. package/lib/module/skia/types/Matrix4.js.map +1 -1
  159. package/lib/module/skia/types/Skia.d.ts +1 -6
  160. package/lib/module/skia/types/Skia.js.map +1 -1
  161. package/lib/module/skia/web/JsiSkCanvas.js +12 -7
  162. package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
  163. package/lib/module/skia/web/JsiSkImage.js +6 -3
  164. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  165. package/lib/module/skia/web/JsiSkPathBuilder.d.ts +1 -1
  166. package/lib/module/skia/web/JsiSkPathBuilder.js +2 -2
  167. package/lib/module/skia/web/JsiSkPathBuilder.js.map +1 -1
  168. package/lib/module/skia/web/JsiSkTextStyle.js +5 -5
  169. package/lib/module/skia/web/JsiSkTextStyle.js.map +1 -1
  170. package/lib/module/skia/web/JsiSkia.js +0 -3
  171. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  172. package/lib/module/skia/web/JsiSkottieAnimation.js +8 -8
  173. package/lib/module/skia/web/JsiSkottieAnimation.js.map +1 -1
  174. package/lib/module/sksg/Recorder/DrawingContext.d.ts +1 -0
  175. package/lib/module/sksg/Recorder/DrawingContext.js +15 -0
  176. package/lib/module/sksg/Recorder/DrawingContext.js.map +1 -1
  177. package/lib/module/sksg/Recorder/Player.js +1 -1
  178. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  179. package/lib/module/sksg/Recorder/Visitor.js +6 -1
  180. package/lib/module/sksg/Recorder/Visitor.js.map +1 -1
  181. package/lib/module/sksg/Recorder/commands/Drawing.js +12 -9
  182. package/lib/module/sksg/Recorder/commands/Drawing.js.map +1 -1
  183. package/lib/module/sksg/Recorder/commands/ImageFilters.js +15 -1
  184. package/lib/module/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  185. package/lib/module/sksg/Recorder/commands/Shaders.js +1 -1
  186. package/lib/module/sksg/Recorder/commands/Shaders.js.map +1 -1
  187. package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
  188. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  189. package/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
  190. package/lib/module/specs/SkiaPictureViewNativeComponent.web.js +3 -0
  191. package/lib/module/specs/SkiaPictureViewNativeComponent.web.js.map +1 -1
  192. package/lib/module/views/SkiaPictureView.js +2 -12
  193. package/lib/module/views/SkiaPictureView.js.map +1 -1
  194. package/lib/module/views/SkiaPictureView.web.js +247 -57
  195. package/lib/module/views/SkiaPictureView.web.js.map +1 -1
  196. package/lib/module/views/types.d.ts +19 -8
  197. package/lib/module/views/types.js.map +1 -1
  198. package/lib/typescript/lib/commonjs/mock/index.d.ts +0 -1
  199. package/lib/typescript/lib/commonjs/renderer/Canvas.d.ts +2 -2
  200. package/lib/typescript/lib/commonjs/skia/web/JsiSkPathBuilder.d.ts +1 -1
  201. package/lib/typescript/lib/commonjs/skia/web/JsiSkia.d.ts +0 -1
  202. package/lib/typescript/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +1 -0
  203. package/lib/typescript/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
  204. package/lib/typescript/lib/module/mock/index.d.ts +0 -1
  205. package/lib/typescript/lib/module/renderer/Canvas.d.ts +2 -2
  206. package/lib/typescript/lib/module/skia/Skia.web.d.ts +0 -1
  207. package/lib/typescript/lib/module/skia/web/JsiSkPathBuilder.d.ts +1 -1
  208. package/lib/typescript/lib/module/skia/web/JsiSkia.d.ts +0 -1
  209. package/lib/typescript/lib/module/sksg/Recorder/DrawingContext.d.ts +1 -0
  210. package/lib/typescript/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
  211. package/lib/typescript/react-native.config.d.ts +3 -0
  212. package/lib/typescript/src/renderer/Canvas.d.ts +11 -3
  213. package/lib/typescript/src/skia/types/JsiInstance.d.ts +1 -0
  214. package/lib/typescript/src/skia/types/Skia.d.ts +1 -6
  215. package/lib/typescript/src/skia/web/JsiSkPathBuilder.d.ts +1 -1
  216. package/lib/typescript/src/sksg/Recorder/DrawingContext.d.ts +1 -0
  217. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
  218. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
  219. package/lib/typescript/src/views/types.d.ts +19 -8
  220. package/package.json +15 -12
  221. package/react-native-skia.podspec +4 -10
  222. package/react-native.config.js +5 -0
  223. package/src/dom/nodes/datatypes/Rect.ts +6 -1
  224. package/src/external/reanimated/useVideo.ts +7 -2
  225. package/src/mock/index.ts +0 -1
  226. package/src/renderer/Canvas.tsx +23 -5
  227. package/src/renderer/components/Mask.tsx +10 -3
  228. package/src/skia/types/JsiInstance.ts +2 -0
  229. package/src/skia/types/Matrix4.ts +6 -2
  230. package/src/skia/types/Skia.ts +1 -7
  231. package/src/skia/web/JsiSkCanvas.ts +22 -12
  232. package/src/skia/web/JsiSkImage.ts +6 -3
  233. package/src/skia/web/JsiSkPathBuilder.ts +2 -2
  234. package/src/skia/web/JsiSkTextStyle.ts +20 -15
  235. package/src/skia/web/JsiSkia.ts +0 -4
  236. package/src/skia/web/JsiSkottieAnimation.ts +8 -8
  237. package/src/sksg/Recorder/DrawingContext.ts +15 -0
  238. package/src/sksg/Recorder/Player.ts +1 -1
  239. package/src/sksg/Recorder/Visitor.ts +9 -6
  240. package/src/sksg/Recorder/commands/Drawing.ts +12 -9
  241. package/src/sksg/Recorder/commands/ImageFilters.ts +20 -1
  242. package/src/sksg/Recorder/commands/Shaders.ts +1 -1
  243. package/src/specs/SkiaPictureViewNativeComponent.ts +5 -0
  244. package/src/specs/SkiaPictureViewNativeComponent.web.ts +5 -0
  245. package/src/views/SkiaPictureView.tsx +2 -10
  246. package/src/views/SkiaPictureView.web.tsx +245 -57
  247. package/src/views/types.ts +23 -10
  248. package/android/src/latest/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +0 -11
  249. package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaPackage.java +0 -79
  250. package/android/src/main/java/com/shopify/reactnative/skia/SkiaAHBView.java +0 -113
  251. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -136
  252. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerDelegate.java +0 -41
  253. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java +0 -20
  254. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerDelegate.java +0 -35
  255. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerInterface.java +0 -17
  256. package/android/src/paper/java/com/shopify/reactnative/skia/NativeSkiaModuleSpec.java +0 -38
  257. package/android/src/reactnative74/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +0 -14
  258. package/apple/SkiaPictureViewManager.h +0 -8
  259. package/apple/SkiaPictureViewManager.mm +0 -60
  260. package/apple/SkiaWebGPUView.h +0 -20
  261. package/apple/WebGPUMetalView.h +0 -12
  262. package/cpp/api/JsiSkiaContext.h +0 -94
  263. package/cpp/dawn/include/dawn/dawn_proc.h +0 -53
  264. package/cpp/dawn/include/dawn/dawn_proc_table.h +0 -330
  265. package/cpp/dawn/include/dawn/dawn_thread_dispatch_proc.h +0 -47
  266. package/cpp/dawn/include/dawn/dawn_version.h +0 -41
  267. package/cpp/dawn/include/dawn/native/D3D11Backend.h +0 -65
  268. package/cpp/dawn/include/dawn/native/D3D12Backend.h +0 -103
  269. package/cpp/dawn/include/dawn/native/D3DBackend.h +0 -56
  270. package/cpp/dawn/include/dawn/native/DawnNative.h +0 -368
  271. package/cpp/dawn/include/dawn/native/MetalBackend.h +0 -56
  272. package/cpp/dawn/include/dawn/native/NullBackend.h +0 -39
  273. package/cpp/dawn/include/dawn/native/OpenGLBackend.h +0 -89
  274. package/cpp/dawn/include/dawn/native/VulkanBackend.h +0 -183
  275. package/cpp/dawn/include/dawn/native/WebGPUBackend.h +0 -49
  276. package/cpp/dawn/include/dawn/native/dawn_native_export.h +0 -49
  277. package/cpp/dawn/include/dawn/platform/DawnPlatform.h +0 -207
  278. package/cpp/dawn/include/dawn/platform/dawn_platform_export.h +0 -49
  279. package/cpp/dawn/include/dawn/replay/Replay.h +0 -99
  280. package/cpp/dawn/include/dawn/replay/dawn_replay_export.h +0 -49
  281. package/cpp/dawn/include/dawn/webgpu_cpp_print.h +0 -2856
  282. package/cpp/dawn/include/tint/tint.h +0 -91
  283. package/cpp/dawn/include/webgpu/webgpu.h +0 -5029
  284. package/cpp/dawn/include/webgpu/webgpu_cpp.h +0 -10353
  285. package/cpp/dawn/include/webgpu/webgpu_cpp_chained_struct.h +0 -57
  286. package/cpp/dawn/include/webgpu/webgpu_enum_class_bitmasks.h +0 -162
  287. package/cpp/dawn/include/webgpu/webgpu_glfw.h +0 -88
  288. package/cpp/jsi/RuntimeAwareCache.cpp +0 -7
  289. package/cpp/jsi/RuntimeAwareCache.h +0 -117
  290. package/cpp/jsi/RuntimeLifecycleMonitor.cpp +0 -72
  291. package/cpp/jsi/RuntimeLifecycleMonitor.h +0 -32
  292. package/cpp/skia/src/gpu/graphite/ContextOptionsPriv.h +0 -45
  293. package/cpp/skia/src/gpu/graphite/ResourceTypes.h +0 -360
  294. package/cpp/skia/src/gpu/graphite/TextureProxyView.h +0 -105
  295. package/libs/.graphite +0 -1
@@ -20,17 +20,24 @@ export const Mask = ({
20
20
  }: MaskProps) => {
21
21
  return (
22
22
  <Group layer>
23
+ {children}
24
+ {/* The children composite against each other in the layer above; the
25
+ mask is then applied once, when its own layer is restored. A blend
26
+ mode attached to a <Group> without a layer would instead be applied
27
+ per draw call, compositing every child after the first against the
28
+ previous child rather than against the mask (issue #3254).
29
+ dstIn keeps the children where the mask is opaque and erases them
30
+ where it is transparent. Without clip, dstATop additionally keeps
31
+ the mask artwork itself wherever the children leave it uncovered. */}
23
32
  <Group
24
33
  layer={
25
- <Paint blendMode="src">
34
+ <Paint blendMode={clip ? "dstIn" : "dstATop"}>
26
35
  {mode === "luminance" && <LumaColorFilter />}
27
36
  </Paint>
28
37
  }
29
38
  >
30
39
  {mask}
31
- {clip && <Group layer={<Paint blendMode="dstIn" />}>{children}</Group>}
32
40
  </Group>
33
- <Group blendMode="srcIn">{children}</Group>
34
41
  </Group>
35
42
  );
36
43
  };
@@ -1,3 +1,5 @@
1
+ /// <reference lib="esnext.disposable" preserve="true" />
2
+
1
3
  export interface SkJSIInstance<T extends string> extends Disposable {
2
4
  __typename__: T;
3
5
  dispose(): void;
@@ -190,12 +190,16 @@ export const multiply4 = (a: Matrix4, b: Matrix4): Matrix4 => {
190
190
  return result as unknown as Matrix4;
191
191
  };
192
192
 
193
- const skewY = (angle: number): Matrix4 => {
193
+ // These matrices are row-major, so the shear factor of skewX - which offsets x
194
+ // in proportion to y - belongs in row 0, column 1, and skewY's in row 1,
195
+ // column 0. React Native's MatrixMath stores the same transforms column-major,
196
+ // and porting its indices verbatim is what swapped the two axes here.
197
+ const skewX = (angle: number): Matrix4 => {
194
198
  "worklet";
195
199
  return [1, Math.tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
196
200
  };
197
201
 
198
- const skewX = (angle: number): Matrix4 => {
202
+ const skewY = (angle: number): Matrix4 => {
199
203
  "worklet";
200
204
  return [1, 0, 0, 0, Math.tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
201
205
  };
@@ -21,7 +21,7 @@ import type { SkVertices, VertexMode } from "./Vertices/Vertices";
21
21
  import type { DataFactory } from "./Data";
22
22
  import type { SVGFactory } from "./SVG";
23
23
  import type { TextBlobFactory } from "./TextBlob";
24
- import type { SkSurface, SurfaceFactory } from "./Surface";
24
+ import type { SurfaceFactory } from "./Surface";
25
25
  import type { SkRSXform } from "./RSXform";
26
26
  import type { SkPath } from "./Path/Path";
27
27
  import type { SkContourMeasureIter } from "./ContourMeasure";
@@ -35,11 +35,6 @@ import type { NativeBufferFactory } from "./NativeBuffer";
35
35
  import type { JsiRecorder } from "./Recorder";
36
36
  import type { SkottieFactory } from "./Skottie";
37
37
 
38
- export interface SkiaContext {
39
- getSurface(): SkSurface;
40
- present(): void;
41
- }
42
-
43
38
  /**
44
39
  * Declares the interface for the native Skia API
45
40
  */
@@ -106,7 +101,6 @@ export interface Skia {
106
101
  ParagraphBuilder: ParagraphBuilderFactory;
107
102
  Skottie: SkottieFactory;
108
103
  Video: (url: string) => Promise<Video> | Video;
109
- Context(surface: bigint, width: number, height: number): SkiaContext;
110
104
  NativeBuffer: NativeBufferFactory;
111
105
  Recorder(): JsiRecorder;
112
106
  /**
@@ -205,13 +205,20 @@ export class JsiSkCanvas
205
205
  mode?: BlendMode | null,
206
206
  paint?: SkPaint
207
207
  ) {
208
- this.ref.drawPatch(
209
- cubics.map(({ x, y }) => [x, y]).flat(),
210
- colors,
211
- texs ? texs.flatMap((p) => Array.from(JsiSkPoint.fromValue(p))) : texs,
212
- mode ? getEnum(this.CanvasKit, "BlendMode", mode) : null,
213
- paint ? JsiSkPaint.fromValue(paint) : undefined
214
- );
208
+ const defaultPaint = paint ? null : new this.CanvasKit.Paint();
209
+ try {
210
+ this.ref.drawPatch(
211
+ cubics.map(({ x, y }) => [x, y]).flat(),
212
+ colors,
213
+ texs ? texs.flatMap((p) => Array.from(JsiSkPoint.fromValue(p))) : texs,
214
+ mode !== undefined && mode !== null
215
+ ? getEnum(this.CanvasKit, "BlendMode", mode)
216
+ : null,
217
+ paint ? JsiSkPaint.fromValue(paint) : defaultPaint!
218
+ );
219
+ } finally {
220
+ defaultPaint?.delete();
221
+ }
215
222
  }
216
223
 
217
224
  restoreToCount(saveCount: number) {
@@ -362,7 +369,9 @@ export class JsiSkCanvas
362
369
  drawColor(color: SkColor, blendMode?: BlendMode) {
363
370
  this.ref.drawColor(
364
371
  color,
365
- blendMode ? getEnum(this.CanvasKit, "BlendMode", blendMode) : undefined
372
+ blendMode !== undefined
373
+ ? getEnum(this.CanvasKit, "BlendMode", blendMode)
374
+ : undefined
366
375
  );
367
376
  }
368
377
 
@@ -430,9 +439,10 @@ export class JsiSkCanvas
430
439
  } else if (sampling) {
431
440
  ckSampling = {
432
441
  filter: getEnum(this.CanvasKit, "FilterMode", sampling.filter),
433
- mipmap: sampling.mipmap
434
- ? getEnum(this.CanvasKit, "MipmapMode", sampling.mipmap)
435
- : this.CanvasKit.MipmapMode.None,
442
+ mipmap:
443
+ sampling.mipmap !== undefined
444
+ ? getEnum(this.CanvasKit, "MipmapMode", sampling.mipmap)
445
+ : this.CanvasKit.MipmapMode.None,
436
446
  };
437
447
  }
438
448
  this.ref.drawAtlas(
@@ -440,7 +450,7 @@ export class JsiSkCanvas
440
450
  src,
441
451
  dst,
442
452
  JsiSkPaint.fromValue(paint),
443
- blendMode
453
+ blendMode !== undefined
444
454
  ? getEnum(this.CanvasKit, "BlendMode", blendMode)
445
455
  : this.CanvasKit.BlendMode.DstOver,
446
456
  cls,
@@ -107,12 +107,15 @@ export class JsiSkImage extends HostObject<Image, "Image"> implements SkImage {
107
107
 
108
108
  encodeToBytes(fmt?: ImageFormat, quality?: number) {
109
109
  let result: Uint8Array | null;
110
- if (fmt && quality) {
110
+ if (fmt !== undefined && quality !== undefined) {
111
+ // CanvasKit's encodeToBytes() applies `quality || 100`, which would
112
+ // turn a valid quality of 0 into 100. The encoders clamp any quality
113
+ // below 1 up to 1 anyway, so pass 1 to get the same output as 0.
111
114
  result = this.ref.encodeToBytes(
112
115
  getEnum(this.CanvasKit, "ImageFormat", fmt),
113
- quality
116
+ Math.max(quality, 1)
114
117
  );
115
- } else if (fmt) {
118
+ } else if (fmt !== undefined) {
116
119
  result = this.ref.encodeToBytes(
117
120
  getEnum(this.CanvasKit, "ImageFormat", fmt)
118
121
  );
@@ -188,8 +188,8 @@ export class JsiSkPathBuilder
188
188
  return this;
189
189
  }
190
190
 
191
- addCircle(x: number, y: number, r: number, _isCCW?: boolean) {
192
- this.ref.addCircle(x, y, r);
191
+ addCircle(x: number, y: number, r: number, isCCW?: boolean) {
192
+ this.ref.addCircle(x, y, r, isCCW);
193
193
  return this;
194
194
  }
195
195
 
@@ -9,23 +9,27 @@ export class JsiSkTextStyle {
9
9
  color: value.color,
10
10
  decoration: value.decoration,
11
11
  decorationColor: value.decorationColor,
12
- decorationStyle: value.decorationStyle
13
- ? { value: value.decorationStyle }
14
- : undefined,
12
+ decorationStyle:
13
+ value.decorationStyle !== undefined
14
+ ? { value: value.decorationStyle }
15
+ : undefined,
15
16
  decorationThickness: value.decorationThickness,
16
17
  fontFamilies: value.fontFamilies,
17
18
  fontSize: value.fontSize,
18
19
  fontStyle: value.fontStyle
19
20
  ? {
20
- slant: value.fontStyle.slant
21
- ? { value: value.fontStyle.slant }
22
- : undefined,
23
- weight: value.fontStyle.weight
24
- ? { value: value.fontStyle.weight }
25
- : undefined,
26
- width: value.fontStyle.width
27
- ? { value: value.fontStyle.width }
28
- : undefined,
21
+ slant:
22
+ value.fontStyle.slant !== undefined
23
+ ? { value: value.fontStyle.slant }
24
+ : undefined,
25
+ weight:
26
+ value.fontStyle.weight !== undefined
27
+ ? { value: value.fontStyle.weight }
28
+ : undefined,
29
+ width:
30
+ value.fontStyle.width !== undefined
31
+ ? { value: value.fontStyle.width }
32
+ : undefined,
29
33
  }
30
34
  : undefined,
31
35
  fontFeatures: value.fontFeatures,
@@ -44,9 +48,10 @@ export class JsiSkTextStyle {
44
48
  : undefined,
45
49
  }))
46
50
  : undefined,
47
- textBaseline: value.textBaseline
48
- ? { value: value.textBaseline }
49
- : undefined,
51
+ textBaseline:
52
+ value.textBaseline !== undefined
53
+ ? { value: value.textBaseline }
54
+ : undefined,
50
55
  wordSpacing: value.wordSpacing,
51
56
  };
52
57
  }
@@ -4,7 +4,6 @@ import type {
4
4
  JsiRecorder,
5
5
  SkContourMeasureIter,
6
6
  Skia,
7
- SkiaContext,
8
7
  SkPath,
9
8
  SkRect,
10
9
  SkRuntimeEffect,
@@ -137,9 +136,6 @@ export const JsiSkApi = (CanvasKit: CanvasKit): Skia => ({
137
136
  NativeBuffer: new JsiSkNativeBufferFactory(CanvasKit),
138
137
  Skottie: new JsiSkottieFactory(CanvasKit),
139
138
  Video: createVideo.bind(null, CanvasKit),
140
- Context: (_surface: bigint, _width: number, _height: number) => {
141
- return throwNotImplementedOnRNWeb<SkiaContext>();
142
- },
143
139
  Recorder: () => {
144
140
  return throwNotImplementedOnRNWeb<JsiRecorder>();
145
141
  },
@@ -164,28 +164,28 @@ export class JsiSkottieAnimation
164
164
  if (result.text) {
165
165
  textSlot.text = result.text;
166
166
  }
167
- if (result.textSize) {
167
+ if (result.textSize !== undefined) {
168
168
  textSlot.textSize = result.textSize;
169
169
  }
170
- if (result.minTextSize) {
170
+ if (result.minTextSize !== undefined) {
171
171
  textSlot.minTextSize = result.minTextSize;
172
172
  }
173
- if (result.maxTextSize) {
173
+ if (result.maxTextSize !== undefined) {
174
174
  textSlot.maxTextSize = result.maxTextSize;
175
175
  }
176
- if (result.strokeWidth) {
176
+ if (result.strokeWidth !== undefined) {
177
177
  textSlot.strokeWidth = result.strokeWidth;
178
178
  }
179
- if (result.lineHeight) {
179
+ if (result.lineHeight !== undefined) {
180
180
  textSlot.lineHeight = result.lineHeight;
181
181
  }
182
- if (result.lineShift) {
182
+ if (result.lineShift !== undefined) {
183
183
  textSlot.lineShift = result.lineShift;
184
184
  }
185
- if (result.ascent) {
185
+ if (result.ascent !== undefined) {
186
186
  textSlot.ascent = result.ascent;
187
187
  }
188
- if (result.maxLines) {
188
+ if (result.maxLines !== undefined) {
189
189
  textSlot.maxLines = result.maxLines;
190
190
  }
191
191
  // if (result.horizAlign) {
@@ -37,7 +37,10 @@ export const createDrawingContext = (
37
37
  if (paintPool.length === 0) {
38
38
  paintPool.push(Skia.Paint());
39
39
  } else {
40
+ // reset() produces an anti-alias false paint, unlike the Skia.Paint()
41
+ // factory: restore the default so reused pools render like the first frame.
40
42
  paintPool[0].reset();
43
+ paintPool[0].setAntiAlias(true);
41
44
  }
42
45
  paints.push(paintPool[0]);
43
46
  opacities.push(1);
@@ -56,6 +59,17 @@ export const createDrawingContext = (
56
59
  nextPaintIndex++;
57
60
  };
58
61
 
62
+ // Pushes an externally owned paint (the `paint` prop) onto the stack. It
63
+ // pushes a frame-scoped copy, like the C++ DrawingCtx: materializePaint()
64
+ // mutates the top of the stack, and those mutations must not leak into the
65
+ // user-owned paint. It must also push an opacity alongside it: restorePaint()
66
+ // pops both, so pushing only the paint would underflow the opacity stack and
67
+ // leak the enclosing group's opacity onto everything drawn afterwards.
68
+ const pushPaint = (paint: SkPaint) => {
69
+ paints.push(track(paint.copy()));
70
+ opacities.push(opacities[opacities.length - 1]);
71
+ };
72
+
59
73
  const getOpacity = () => {
60
74
  return opacities[opacities.length - 1];
61
75
  };
@@ -144,6 +158,7 @@ export const createDrawingContext = (
144
158
 
145
159
  // Public methods
146
160
  savePaint,
161
+ pushPaint,
147
162
  saveBackdropFilter,
148
163
  get paint() {
149
164
  return paints[paints.length - 1];
@@ -123,7 +123,7 @@ const play = (ctx: DrawingContext, _command: Command) => {
123
123
  ctx.canvas.saveLayer(paint);
124
124
  } else if (isDrawCommand(command, CommandType.SavePaint)) {
125
125
  if (command.props.paint) {
126
- ctx.paints.push(command.props.paint);
126
+ ctx.pushPaint(command.props.paint);
127
127
  } else {
128
128
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
129
  const { standalone } = command as any;
@@ -104,13 +104,16 @@ const processCTM = ({
104
104
  if (layer) {
105
105
  ctm.layer = layer;
106
106
  }
107
+ // Only record a CTM command when saveCTM() will actually save the canvas.
108
+ // saveCTM() saves on transform/matrix, clip or layer; restoreCTM() always
109
+ // restores, so recording a CTM that saves nothing - `origin` with no
110
+ // transform, `clip={false}` from a conditional, a bare `invertClip` - pops
111
+ // an enclosing save that belongs to an ancestor.
107
112
  if (
108
- clip !== undefined ||
109
- invertClip !== undefined ||
110
- transform !== undefined ||
111
- origin !== undefined ||
112
- matrix !== undefined ||
113
- layer !== undefined
113
+ ctm.clip !== undefined ||
114
+ ctm.transform !== undefined ||
115
+ ctm.matrix !== undefined ||
116
+ ctm.layer !== undefined
114
117
  ) {
115
118
  return ctm;
116
119
  }
@@ -217,6 +217,16 @@ export const drawPath = (ctx: DrawingContext, props: PathProps) => {
217
217
 
218
218
  let path = processPath(ctx.Skia, pathProps.path);
219
219
 
220
+ // Trim runs first, so start/end address the path the caller drew. Stroking
221
+ // first would replace it with its outline and leave the offsets walking that
222
+ // outline's perimeter instead. The native recorder orders these the same way.
223
+ if (hasStartOffset || hasEndOffset) {
224
+ const trimmed = ctx.Skia.Path.Trim(path, start, end, false);
225
+ if (trimmed) {
226
+ path = trimmed;
227
+ }
228
+ }
229
+
220
230
  // Apply fill type using PathBuilder
221
231
  if (hasFillType) {
222
232
  const builder = ctx.Skia.PathBuilder.MakeFromPath(path);
@@ -232,14 +242,6 @@ export const drawPath = (ctx: DrawingContext, props: PathProps) => {
232
242
  }
233
243
  }
234
244
 
235
- // Apply trim using static Path.Trim
236
- if (hasStartOffset || hasEndOffset) {
237
- const trimmed = ctx.Skia.Path.Trim(path, start, end, false);
238
- if (trimmed) {
239
- path = trimmed;
240
- }
241
- }
242
-
243
245
  ctx.canvas.drawPath(path, ctx.paint);
244
246
  };
245
247
 
@@ -295,7 +297,8 @@ export const drawImageSVG = (ctx: DrawingContext, props: ImageSVGProps) => {
295
297
  return;
296
298
  }
297
299
  canvas.save();
298
- if (x && y) {
300
+ // An offset of 0 is a valid position, so it must not be read as "unset".
301
+ if (x !== undefined && y !== undefined) {
299
302
  canvas.translate(x, y);
300
303
  }
301
304
  canvas.drawSvg(svg, width, height);
@@ -31,6 +31,14 @@ export enum MorphologyOperator {
31
31
 
32
32
  const Black = Float32Array.of(0, 0, 0, 1);
33
33
 
34
+ // Turns the source graphic into a hard silhouette: alpha is multiplied by 255
35
+ // and clamped, so any pixel the shape covers at all becomes fully opaque, and
36
+ // the colour channels are dropped. 255 is the saturation point of an 8-bit
37
+ // alpha channel, so one unit of coverage is enough to reach 1.
38
+ const AlphaSaturate = [
39
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
40
+ ];
41
+
34
42
  const MakeInnerShadow = (
35
43
  Skia: Skia,
36
44
  shadowOnly: boolean | undefined,
@@ -50,9 +58,20 @@ const MakeInnerShadow = (
50
58
  Skia.ColorFilter.MakeBlend(Black, BlendMode.SrcIn),
51
59
  null
52
60
  );
61
+ // The shadow is generated outside the shape and then clipped back into it, so
62
+ // "outside" has to be the complement of the shape's silhouette. Taking SrcOut
63
+ // against the source graphic itself makes it the complement of the source's
64
+ // *alpha*: inside a translucent shape 1 - alpha is non-zero, so the shadow is
65
+ // generated across the whole interior and tints it, no matter how small the
66
+ // blur and the offset are (issue #2990). Saturating alpha first keeps the
67
+ // shadow tied to the shape's outline instead of to its opacity.
68
+ const coverage = Skia.ImageFilter.MakeColorFilter(
69
+ Skia.ColorFilter.MakeMatrix(AlphaSaturate),
70
+ null
71
+ );
53
72
  const f1 = Skia.ImageFilter.MakeColorFilter(
54
73
  Skia.ColorFilter.MakeBlend(color, BlendMode.SrcOut),
55
- null
74
+ coverage
56
75
  );
57
76
  const f2 = Skia.ImageFilter.MakeOffset(dx, dy, f1);
58
77
  const f3 = Skia.ImageFilter.MakeBlur(sigmaX, sigmaY, TileMode.Decal, f2);
@@ -221,7 +221,7 @@ const declareImageShader = (ctx: DrawingContext, props: ImageShaderProps) => {
221
221
  );
222
222
  } else {
223
223
  shader = ctx.track(
224
- image.makeShaderCubic(
224
+ image.makeShaderOptions(
225
225
  TileMode[enumKey(tx)],
226
226
  TileMode[enumKey(ty)],
227
227
  sampling?.filter ?? FilterMode.Linear,
@@ -9,6 +9,11 @@ export interface NativeProps extends ViewProps {
9
9
  colorSpace?: string;
10
10
  highBitDepth?: boolean;
11
11
  androidWarmup?: boolean;
12
+ androidSurfaceType?: WithDefault<
13
+ "auto" | "SurfaceView" | "TextureView",
14
+ "auto"
15
+ >;
16
+ androidZOrderOnTop?: WithDefault<boolean, false>;
12
17
  pointerEvents?: WithDefault<
13
18
  "auto" | "none" | "box-none" | "box-only",
14
19
  "auto"
@@ -7,6 +7,8 @@ export interface NativeProps extends ViewProps {
7
7
  debug?: boolean;
8
8
  opaque?: boolean;
9
9
  nativeID: string;
10
+ androidSurfaceType?: "auto" | "SurfaceView" | "TextureView";
11
+ androidZOrderOnTop?: boolean;
10
12
  }
11
13
 
12
14
  const SkiaPictureViewNativeComponent = ({
@@ -14,6 +16,9 @@ const SkiaPictureViewNativeComponent = ({
14
16
  debug,
15
17
  opaque,
16
18
  onLayout,
19
+ // Android-only, never reaches the DOM
20
+ androidSurfaceType: _androidSurfaceType,
21
+ androidZOrderOnTop: _androidZOrderOnTop,
17
22
  ...viewProps
18
23
  }: NativeProps) => {
19
24
  return createElement(SkiaPictureView, {
@@ -20,15 +20,11 @@ export class SkiaPictureView extends React.Component<SkiaPictureViewProps> {
20
20
  constructor(props: SkiaPictureViewProps) {
21
21
  super(props);
22
22
  this._nativeId = SkiaViewNativeId.current++;
23
- const { picture, onSize } = props;
23
+ const { picture } = props;
24
24
  if (picture) {
25
25
  assertSkiaViewApi();
26
26
  SkiaViewApi.setJsiProperty(this._nativeId, "picture", picture);
27
27
  }
28
- if (onSize) {
29
- assertSkiaViewApi();
30
- SkiaViewApi.setJsiProperty(this._nativeId, "onSize", onSize);
31
- }
32
28
  this.tick();
33
29
  }
34
30
 
@@ -39,15 +35,11 @@ export class SkiaPictureView extends React.Component<SkiaPictureViewProps> {
39
35
  }
40
36
 
41
37
  componentDidUpdate(prevProps: SkiaPictureViewProps) {
42
- const { picture, onSize } = this.props;
38
+ const { picture } = this.props;
43
39
  if (picture !== prevProps.picture) {
44
40
  assertSkiaViewApi();
45
41
  SkiaViewApi.setJsiProperty(this._nativeId, "picture", picture);
46
42
  }
47
- if (onSize !== prevProps.onSize) {
48
- assertSkiaViewApi();
49
- SkiaViewApi.setJsiProperty(this._nativeId, "onSize", onSize);
50
- }
51
43
  this.tick();
52
44
  }
53
45