@shopify/react-native-skia 0.1.221 → 0.1.223

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. package/android/cpp/rnskia-android/RNSkAndroidView.h +3 -0
  2. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +1 -0
  3. package/android/cpp/rnskia-android/SkiaOpenGLHelper.h +0 -1
  4. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +46 -6
  5. package/android/src/main/java/com/shopify/reactnative/skia/PlatformContext.java +3 -3
  6. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +8 -14
  7. package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +93 -105
  8. package/cpp/api/JsiSkApi.h +5 -0
  9. package/cpp/api/JsiSkFontMgrFactory.h +9 -4
  10. package/cpp/api/JsiSkParagraph.h +135 -0
  11. package/cpp/api/JsiSkParagraphBuilder.h +159 -0
  12. package/cpp/api/JsiSkParagraphStyle.h +124 -0
  13. package/cpp/api/JsiSkStrutStyle.h +96 -0
  14. package/cpp/api/JsiSkTextStyle.h +185 -0
  15. package/cpp/jsi/JsiHostObject.h +21 -0
  16. package/cpp/rnskia/dom/JsiDomApi.h +4 -0
  17. package/cpp/rnskia/dom/nodes/JsiParagraphNode.h +62 -0
  18. package/cpp/rnskia/dom/props/ParagraphProp.h +45 -0
  19. package/cpp/skia/modules/skunicode/include/SkUnicode.h +312 -0
  20. package/cpp/skia/src/base/SkTInternalLList.h +304 -0
  21. package/cpp/skia/src/base/SkUTF.h +95 -0
  22. package/cpp/skia/src/core/SkLRUCache.h +130 -0
  23. package/cpp/utils/RNSkLog.h +3 -3
  24. package/lib/commonjs/dom/nodes/JsiSkDOM.d.ts +2 -0
  25. package/lib/commonjs/dom/nodes/JsiSkDOM.js +7 -0
  26. package/lib/commonjs/dom/nodes/JsiSkDOM.js.map +1 -1
  27. package/lib/commonjs/dom/nodes/drawings/ParagraphNode.d.ts +8 -0
  28. package/lib/commonjs/dom/nodes/drawings/ParagraphNode.js +41 -0
  29. package/lib/commonjs/dom/nodes/drawings/ParagraphNode.js.map +1 -0
  30. package/lib/commonjs/dom/types/NodeType.d.ts +2 -1
  31. package/lib/commonjs/dom/types/NodeType.js +1 -0
  32. package/lib/commonjs/dom/types/NodeType.js.map +1 -1
  33. package/lib/commonjs/dom/types/Paragraph.d.ts +8 -0
  34. package/lib/commonjs/dom/types/Paragraph.js +6 -0
  35. package/lib/commonjs/dom/types/Paragraph.js.map +1 -0
  36. package/lib/commonjs/dom/types/SkDOM.d.ts +2 -0
  37. package/lib/commonjs/dom/types/SkDOM.js.map +1 -1
  38. package/lib/commonjs/dom/types/index.d.ts +1 -0
  39. package/lib/commonjs/dom/types/index.js +13 -0
  40. package/lib/commonjs/dom/types/index.js.map +1 -1
  41. package/lib/commonjs/renderer/HostComponents.d.ts +3 -1
  42. package/lib/commonjs/renderer/HostComponents.js +4 -0
  43. package/lib/commonjs/renderer/HostComponents.js.map +1 -1
  44. package/lib/commonjs/renderer/components/index.d.ts +1 -0
  45. package/lib/commonjs/renderer/components/index.js +13 -0
  46. package/lib/commonjs/renderer/components/index.js.map +1 -1
  47. package/lib/commonjs/renderer/components/paragraph/Paragraph.d.ts +4 -0
  48. package/lib/commonjs/renderer/components/paragraph/Paragraph.js +17 -0
  49. package/lib/commonjs/renderer/components/paragraph/Paragraph.js.map +1 -0
  50. package/lib/commonjs/renderer/components/paragraph/index.d.ts +1 -0
  51. package/lib/commonjs/renderer/components/paragraph/index.js +19 -0
  52. package/lib/commonjs/renderer/components/paragraph/index.js.map +1 -0
  53. package/lib/commonjs/skia/types/Paragraph/Paragraph.d.ts +56 -0
  54. package/lib/commonjs/skia/types/Paragraph/Paragraph.js +6 -0
  55. package/lib/commonjs/skia/types/Paragraph/Paragraph.js.map +1 -0
  56. package/lib/commonjs/skia/types/Paragraph/ParagraphBuilder.d.ts +60 -0
  57. package/lib/commonjs/skia/types/Paragraph/ParagraphBuilder.js +18 -0
  58. package/lib/commonjs/skia/types/Paragraph/ParagraphBuilder.js.map +1 -0
  59. package/lib/commonjs/skia/types/Paragraph/ParagraphStyle.d.ts +41 -0
  60. package/lib/commonjs/skia/types/Paragraph/ParagraphStyle.js +36 -0
  61. package/lib/commonjs/skia/types/Paragraph/ParagraphStyle.js.map +1 -0
  62. package/lib/commonjs/skia/types/Paragraph/TextStyle.d.ts +62 -0
  63. package/lib/commonjs/skia/types/Paragraph/TextStyle.js +35 -0
  64. package/lib/commonjs/skia/types/Paragraph/TextStyle.js.map +1 -0
  65. package/lib/commonjs/skia/types/Paragraph/index.d.ts +6 -0
  66. package/lib/commonjs/skia/types/Paragraph/index.js +84 -0
  67. package/lib/commonjs/skia/types/Paragraph/index.js.map +1 -0
  68. package/lib/commonjs/skia/types/Skia.d.ts +2 -0
  69. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  70. package/lib/commonjs/skia/types/index.d.ts +1 -0
  71. package/lib/commonjs/skia/types/index.js +13 -0
  72. package/lib/commonjs/skia/types/index.js.map +1 -1
  73. package/lib/commonjs/skia/web/JsiSkImage.js +0 -6
  74. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  75. package/lib/commonjs/skia/web/JsiSkParagraph.d.ts +16 -0
  76. package/lib/commonjs/skia/web/JsiSkParagraph.js +91 -0
  77. package/lib/commonjs/skia/web/JsiSkParagraph.js.map +1 -0
  78. package/lib/commonjs/skia/web/JsiSkParagraphBuilder.d.ts +15 -0
  79. package/lib/commonjs/skia/web/JsiSkParagraphBuilder.js +85 -0
  80. package/lib/commonjs/skia/web/JsiSkParagraphBuilder.js.map +1 -0
  81. package/lib/commonjs/skia/web/JsiSkParagraphBuilderFactory.d.ts +8 -0
  82. package/lib/commonjs/skia/web/JsiSkParagraphBuilderFactory.js +34 -0
  83. package/lib/commonjs/skia/web/JsiSkParagraphBuilderFactory.js.map +1 -0
  84. package/lib/commonjs/skia/web/JsiSkParagraphStyle.d.ts +5 -0
  85. package/lib/commonjs/skia/web/JsiSkParagraphStyle.js +59 -0
  86. package/lib/commonjs/skia/web/JsiSkParagraphStyle.js.map +1 -0
  87. package/lib/commonjs/skia/web/JsiSkTextStyle.d.ts +5 -0
  88. package/lib/commonjs/skia/web/JsiSkTextStyle.js +54 -0
  89. package/lib/commonjs/skia/web/JsiSkTextStyle.js.map +1 -0
  90. package/lib/commonjs/skia/web/JsiSkia.js +4 -1
  91. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  92. package/lib/module/dom/nodes/JsiSkDOM.d.ts +2 -0
  93. package/lib/module/dom/nodes/JsiSkDOM.js +6 -0
  94. package/lib/module/dom/nodes/JsiSkDOM.js.map +1 -1
  95. package/lib/module/dom/nodes/drawings/ParagraphNode.d.ts +8 -0
  96. package/lib/module/dom/nodes/drawings/ParagraphNode.js +30 -0
  97. package/lib/module/dom/nodes/drawings/ParagraphNode.js.map +1 -0
  98. package/lib/module/dom/types/NodeType.d.ts +2 -1
  99. package/lib/module/dom/types/NodeType.js +1 -0
  100. package/lib/module/dom/types/NodeType.js.map +1 -1
  101. package/lib/module/dom/types/Paragraph.d.ts +8 -0
  102. package/lib/module/dom/types/Paragraph.js +2 -0
  103. package/lib/module/dom/types/Paragraph.js.map +1 -0
  104. package/lib/module/dom/types/SkDOM.d.ts +2 -0
  105. package/lib/module/dom/types/SkDOM.js.map +1 -1
  106. package/lib/module/dom/types/index.d.ts +1 -0
  107. package/lib/module/dom/types/index.js +1 -0
  108. package/lib/module/dom/types/index.js.map +1 -1
  109. package/lib/module/renderer/HostComponents.d.ts +3 -1
  110. package/lib/module/renderer/HostComponents.js +4 -0
  111. package/lib/module/renderer/HostComponents.js.map +1 -1
  112. package/lib/module/renderer/components/index.d.ts +1 -0
  113. package/lib/module/renderer/components/index.js +1 -0
  114. package/lib/module/renderer/components/index.js.map +1 -1
  115. package/lib/module/renderer/components/paragraph/Paragraph.d.ts +4 -0
  116. package/lib/module/renderer/components/paragraph/Paragraph.js +5 -0
  117. package/lib/module/renderer/components/paragraph/Paragraph.js.map +1 -0
  118. package/lib/module/renderer/components/paragraph/index.d.ts +1 -0
  119. package/lib/module/renderer/components/paragraph/index.js +2 -0
  120. package/lib/module/renderer/components/paragraph/index.js.map +1 -0
  121. package/lib/module/skia/types/Paragraph/Paragraph.d.ts +56 -0
  122. package/lib/module/skia/types/Paragraph/Paragraph.js +2 -0
  123. package/lib/module/skia/types/Paragraph/Paragraph.js.map +1 -0
  124. package/lib/module/skia/types/Paragraph/ParagraphBuilder.d.ts +60 -0
  125. package/lib/module/skia/types/Paragraph/ParagraphBuilder.js +11 -0
  126. package/lib/module/skia/types/Paragraph/ParagraphBuilder.js.map +1 -0
  127. package/lib/module/skia/types/Paragraph/ParagraphStyle.d.ts +41 -0
  128. package/lib/module/skia/types/Paragraph/ParagraphStyle.js +27 -0
  129. package/lib/module/skia/types/Paragraph/ParagraphStyle.js.map +1 -0
  130. package/lib/module/skia/types/Paragraph/TextStyle.d.ts +62 -0
  131. package/lib/module/skia/types/Paragraph/TextStyle.js +26 -0
  132. package/lib/module/skia/types/Paragraph/TextStyle.js.map +1 -0
  133. package/lib/module/skia/types/Paragraph/index.d.ts +6 -0
  134. package/lib/module/skia/types/Paragraph/index.js +7 -0
  135. package/lib/module/skia/types/Paragraph/index.js.map +1 -0
  136. package/lib/module/skia/types/Skia.d.ts +2 -0
  137. package/lib/module/skia/types/Skia.js.map +1 -1
  138. package/lib/module/skia/types/index.d.ts +1 -0
  139. package/lib/module/skia/types/index.js +1 -0
  140. package/lib/module/skia/types/index.js.map +1 -1
  141. package/lib/module/skia/web/JsiSkImage.js +0 -6
  142. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  143. package/lib/module/skia/web/JsiSkParagraph.d.ts +16 -0
  144. package/lib/module/skia/web/JsiSkParagraph.js +81 -0
  145. package/lib/module/skia/web/JsiSkParagraph.js.map +1 -0
  146. package/lib/module/skia/web/JsiSkParagraphBuilder.d.ts +15 -0
  147. package/lib/module/skia/web/JsiSkParagraphBuilder.js +73 -0
  148. package/lib/module/skia/web/JsiSkParagraphBuilder.js.map +1 -0
  149. package/lib/module/skia/web/JsiSkParagraphBuilderFactory.d.ts +8 -0
  150. package/lib/module/skia/web/JsiSkParagraphBuilderFactory.js +21 -0
  151. package/lib/module/skia/web/JsiSkParagraphBuilderFactory.js.map +1 -0
  152. package/lib/module/skia/web/JsiSkParagraphStyle.d.ts +5 -0
  153. package/lib/module/skia/web/JsiSkParagraphStyle.js +49 -0
  154. package/lib/module/skia/web/JsiSkParagraphStyle.js.map +1 -0
  155. package/lib/module/skia/web/JsiSkTextStyle.d.ts +5 -0
  156. package/lib/module/skia/web/JsiSkTextStyle.js +45 -0
  157. package/lib/module/skia/web/JsiSkTextStyle.js.map +1 -0
  158. package/lib/module/skia/web/JsiSkia.js +3 -1
  159. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  160. package/lib/typescript/src/dom/nodes/JsiSkDOM.d.ts +2 -0
  161. package/lib/typescript/src/dom/nodes/drawings/ParagraphNode.d.ts +8 -0
  162. package/lib/typescript/src/dom/types/NodeType.d.ts +2 -1
  163. package/lib/typescript/src/dom/types/Paragraph.d.ts +8 -0
  164. package/lib/typescript/src/dom/types/SkDOM.d.ts +2 -0
  165. package/lib/typescript/src/dom/types/index.d.ts +1 -0
  166. package/lib/typescript/src/renderer/HostComponents.d.ts +3 -1
  167. package/lib/typescript/src/renderer/components/index.d.ts +1 -0
  168. package/lib/typescript/src/renderer/components/paragraph/Paragraph.d.ts +4 -0
  169. package/lib/typescript/src/renderer/components/paragraph/index.d.ts +1 -0
  170. package/lib/typescript/src/skia/types/Paragraph/Paragraph.d.ts +56 -0
  171. package/lib/typescript/src/skia/types/Paragraph/ParagraphBuilder.d.ts +60 -0
  172. package/lib/typescript/src/skia/types/Paragraph/ParagraphStyle.d.ts +41 -0
  173. package/lib/typescript/src/skia/types/Paragraph/TextStyle.d.ts +62 -0
  174. package/lib/typescript/src/skia/types/Paragraph/index.d.ts +6 -0
  175. package/lib/typescript/src/skia/types/Skia.d.ts +2 -0
  176. package/lib/typescript/src/skia/types/index.d.ts +1 -0
  177. package/lib/typescript/src/skia/web/JsiSkParagraph.d.ts +16 -0
  178. package/lib/typescript/src/skia/web/JsiSkParagraphBuilder.d.ts +15 -0
  179. package/lib/typescript/src/skia/web/JsiSkParagraphBuilderFactory.d.ts +8 -0
  180. package/lib/typescript/src/skia/web/JsiSkParagraphStyle.d.ts +5 -0
  181. package/lib/typescript/src/skia/web/JsiSkTextStyle.d.ts +5 -0
  182. package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  183. package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  184. package/libs/ios/libskottie.xcframework/Info.plist +5 -5
  185. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
  186. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
  187. package/libs/ios/libskparagraph.xcframework/Info.plist +5 -5
  188. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
  189. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
  190. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
  191. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
  192. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
  193. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
  194. package/libs/ios/libskunicode.xcframework/ios-arm64_arm64e/libskunicode.a +0 -0
  195. package/libs/ios/libskunicode.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode.a +0 -0
  196. package/libs/ios/libsvg.xcframework/Info.plist +5 -5
  197. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
  198. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
  199. package/package.json +1 -1
  200. package/src/dom/nodes/JsiSkDOM.ts +9 -0
  201. package/src/dom/nodes/drawings/ParagraphNode.ts +22 -0
  202. package/src/dom/types/NodeType.ts +3 -0
  203. package/src/dom/types/Paragraph.ts +10 -0
  204. package/src/dom/types/SkDOM.ts +4 -0
  205. package/src/dom/types/index.ts +1 -0
  206. package/src/renderer/HostComponents.ts +10 -0
  207. package/src/renderer/components/index.ts +2 -0
  208. package/src/renderer/components/paragraph/Paragraph.tsx +8 -0
  209. package/src/renderer/components/paragraph/index.ts +1 -0
  210. package/src/skia/types/Paragraph/Paragraph.ts +59 -0
  211. package/src/skia/types/Paragraph/ParagraphBuilder.ts +96 -0
  212. package/src/skia/types/Paragraph/ParagraphStyle.ts +45 -0
  213. package/src/skia/types/Paragraph/TextStyle.ts +70 -0
  214. package/src/skia/types/Paragraph/index.ts +6 -0
  215. package/src/skia/types/Skia.ts +3 -0
  216. package/src/skia/types/index.ts +1 -0
  217. package/src/skia/web/JsiSkImage.ts +0 -6
  218. package/src/skia/web/JsiSkParagraph.ts +69 -0
  219. package/src/skia/web/JsiSkParagraphBuilder.ts +99 -0
  220. package/src/skia/web/JsiSkParagraphBuilderFactory.ts +42 -0
  221. package/src/skia/web/JsiSkParagraphStyle.ts +65 -0
  222. package/src/skia/web/JsiSkTextStyle.ts +53 -0
  223. package/src/skia/web/JsiSkia.ts +2 -0
@@ -56,6 +56,9 @@ public:
56
56
  void surfaceSizeChanged(int width, int height) override {
57
57
  std::static_pointer_cast<RNSkOpenGLCanvasProvider>(T::getCanvasProvider())
58
58
  ->surfaceSizeChanged(width, height);
59
+ // This is only need for the first time to frame, this renderImmediate call
60
+ // will invoke updateTexImage for the previous frame
61
+ RNSkView::renderImmediate();
59
62
  }
60
63
 
61
64
  float getPixelDensity() override {
@@ -39,6 +39,7 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas(
39
39
  if (!_surfaceHolder->makeCurrent()) {
40
40
  return false;
41
41
  }
42
+ _surfaceHolder->updateTexImage();
42
43
 
43
44
  // Draw into canvas using callback
44
45
  cb(surface->getCanvas());
@@ -187,7 +187,6 @@ public:
187
187
  RNSkLogger::logToConsole("eglMakeCurrent failed: %d\n", eglGetError());
188
188
  return false;
189
189
  }
190
- return true;
191
190
  }
192
191
  return true;
193
192
  }
@@ -6,6 +6,8 @@
6
6
  #include <jni.h>
7
7
 
8
8
  #include <android/native_window_jni.h>
9
+ #include <android/surface_texture.h>
10
+ #include <android/surface_texture_jni.h>
9
11
  #include <condition_variable>
10
12
  #include <memory>
11
13
  #include <thread>
@@ -42,12 +44,34 @@ public:
42
44
  */
43
45
  class WindowSurfaceHolder {
44
46
  public:
45
- WindowSurfaceHolder(jobject surface, int width, int height)
46
- : _width(width), _height(height),
47
- _window(ANativeWindow_fromSurface(facebook::jni::Environment::current(),
48
- surface)) {}
47
+ WindowSurfaceHolder(jobject jSurfaceTexture, int width, int height)
48
+ : _width(width), _height(height) {
49
+ JNIEnv *env = facebook::jni::Environment::current();
50
+ _jSurfaceTexture = env->NewGlobalRef(jSurfaceTexture);
51
+ jclass surfaceClass = env->FindClass("android/view/Surface");
52
+ jmethodID surfaceConstructor = env->GetMethodID(
53
+ surfaceClass, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
54
+ // Create a new Surface instance
55
+ jobject jSurface =
56
+ env->NewObject(surfaceClass, surfaceConstructor, jSurfaceTexture);
57
+
58
+ jclass surfaceTextureClass = env->GetObjectClass(_jSurfaceTexture);
59
+ _updateTexImageMethod =
60
+ env->GetMethodID(surfaceTextureClass, "updateTexImage", "()V");
61
+
62
+ // Acquire the native window from the Surface
63
+ _window = ANativeWindow_fromSurface(env, jSurface);
64
+ // Clean up local references
65
+ env->DeleteLocalRef(jSurface);
66
+ env->DeleteLocalRef(surfaceClass);
67
+ env->DeleteLocalRef(surfaceTextureClass);
68
+ }
49
69
 
50
- ~WindowSurfaceHolder() { ANativeWindow_release(_window); }
70
+ ~WindowSurfaceHolder() {
71
+ JNIEnv *env = facebook::jni::Environment::current();
72
+ env->DeleteGlobalRef(_jSurfaceTexture);
73
+ ANativeWindow_release(_window);
74
+ }
51
75
 
52
76
  int getWidth() { return _width; }
53
77
  int getHeight() { return _height; }
@@ -57,6 +81,20 @@ public:
57
81
  */
58
82
  sk_sp<SkSurface> getSurface();
59
83
 
84
+ void updateTexImage() {
85
+ JNIEnv *env = facebook::jni::Environment::current();
86
+
87
+ // Call updateTexImage on the SurfaceTexture object
88
+ env->CallVoidMethod(_jSurfaceTexture, _updateTexImageMethod);
89
+
90
+ // Check for exceptions
91
+ if (env->ExceptionCheck()) {
92
+ RNSkLogger::logToConsole(
93
+ "updateTexImage() failed. The exception above can safely be ignored");
94
+ env->ExceptionClear();
95
+ }
96
+ }
97
+
60
98
  /**
61
99
  * Resizes the surface
62
100
  * @param width
@@ -92,9 +130,11 @@ public:
92
130
  }
93
131
 
94
132
  private:
95
- ANativeWindow *_window = nullptr;
133
+ ANativeWindow *_window;
96
134
  sk_sp<SkSurface> _skSurface = nullptr;
135
+ jobject _jSurfaceTexture = nullptr;
97
136
  EGLSurface _glSurface = EGL_NO_SURFACE;
137
+ jmethodID _updateTexImageMethod = nullptr;
98
138
  int _width = 0;
99
139
  int _height = 0;
100
140
  };
@@ -52,13 +52,13 @@ public class PlatformContext {
52
52
  Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() {
53
53
  @Override
54
54
  public void doFrame(long frameTimeNanos) {
55
+ if (_drawLoopActive) {
56
+ Choreographer.getInstance().postFrameCallback(this);
57
+ }
55
58
  if (_isPaused) {
56
59
  return;
57
60
  }
58
61
  notifyDrawLoop();
59
- if (_drawLoopActive) {
60
- postFrameLoop();
61
- }
62
62
  }
63
63
  };
64
64
  Choreographer.getInstance().postFrameCallback(frameCallback);
@@ -4,16 +4,11 @@ import android.content.Context;
4
4
  import android.graphics.SurfaceTexture;
5
5
  import android.util.Log;
6
6
  import android.view.MotionEvent;
7
- import android.view.Surface;
8
7
  import android.view.TextureView;
9
8
 
10
- import com.facebook.jni.annotations.DoNotStrip;
11
9
  import com.facebook.react.views.view.ReactViewGroup;
12
10
 
13
11
  public abstract class SkiaBaseView extends ReactViewGroup implements TextureView.SurfaceTextureListener {
14
-
15
- @DoNotStrip
16
- private Surface mSurface;
17
12
  private TextureView mTexture;
18
13
 
19
14
  private String tag = "SkiaView";
@@ -30,12 +25,8 @@ public abstract class SkiaBaseView extends ReactViewGroup implements TextureView
30
25
  }
31
26
 
32
27
  public void destroySurface() {
33
- if (mSurface != null) {
34
- Log.i(tag, "destroySurface");
35
- surfaceDestroyed();
36
- mSurface.release();
37
- mSurface = null;
38
- }
28
+ Log.i(tag, "destroySurface");
29
+ surfaceDestroyed();
39
30
  }
40
31
 
41
32
  private void createSurfaceTexture() {
@@ -138,8 +129,7 @@ public abstract class SkiaBaseView extends ReactViewGroup implements TextureView
138
129
  @Override
139
130
  public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
140
131
  Log.i(tag, "onSurfaceTextureAvailable " + width + "/" + height);
141
- mSurface = new Surface(surface);
142
- surfaceAvailable(mSurface, width, height);
132
+ surfaceAvailable(surface, width, height);
143
133
  }
144
134
 
145
135
  @Override
@@ -153,6 +143,10 @@ public abstract class SkiaBaseView extends ReactViewGroup implements TextureView
153
143
  Log.i(tag, "onSurfaceTextureDestroyed");
154
144
  // https://developer.android.com/reference/android/view/TextureView.SurfaceTextureListener#onSurfaceTextureDestroyed(android.graphics.SurfaceTexture)
155
145
  destroySurface();
146
+ // Because of React Native Screens (which dettach the view), we always keep the surface alive.
147
+ // If not, Texture view will recreate the texture surface by itself and
148
+ // we will lose the fast first time to frame.
149
+ // We only delete the surface when the view is dropped (destroySurface invoked by SkiaBaseViewManager);
156
150
  createSurfaceTexture();
157
151
  return false;
158
152
  }
@@ -181,4 +175,4 @@ public abstract class SkiaBaseView extends ReactViewGroup implements TextureView
181
175
  protected abstract void registerView(int nativeId);
182
176
 
183
177
  protected abstract void unregisterView();
184
- }
178
+ }
@@ -1,11 +1,10 @@
1
1
  package com.shopify.reactnative.skia;
2
2
 
3
- import static android.view.View.VISIBLE;
4
-
5
3
  import android.graphics.Bitmap;
6
4
  import android.graphics.Canvas;
7
5
  import android.graphics.Matrix;
8
6
  import android.graphics.Paint;
7
+ import android.graphics.drawable.Drawable;
9
8
  import android.os.Build;
10
9
  import android.os.Handler;
11
10
  import android.os.Looper;
@@ -15,14 +14,12 @@ import android.view.SurfaceView;
15
14
  import android.view.TextureView;
16
15
  import android.view.View;
17
16
  import android.view.ViewGroup;
18
-
19
17
  import androidx.annotation.NonNull;
20
-
21
18
  import com.facebook.react.bridge.ReactContext;
22
19
  import com.facebook.react.uimanager.UIManagerModule;
20
+ import com.facebook.react.views.view.ReactViewGroup;
23
21
 
24
- import java.util.ArrayList;
25
- import java.util.List;
22
+ import java.lang.reflect.Method;
26
23
  import java.util.concurrent.CountDownLatch;
27
24
  import java.util.concurrent.TimeUnit;
28
25
 
@@ -42,143 +39,134 @@ public class ViewScreenshotService {
42
39
  return null;
43
40
  }
44
41
 
45
- // Measure and get size of view
46
42
  int width = view.getWidth();
47
43
  int height = view.getHeight();
48
-
49
44
  if (width <= 0 || height <= 0) {
50
45
  return null;
51
46
  }
52
47
 
53
- // The following code is taken from react-native-view-shot to be able to handle and
54
- // correctly render all kinds of views, also including TextureViews and SurfaceViews
55
48
  Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
49
+ final Canvas canvas = new Canvas(bitmap);
50
+ final Paint paint = createPaint();
51
+
52
+ canvas.save();
53
+ canvas.translate(-view.getLeft(), -view.getTop());
54
+ renderViewToCanvas(canvas, view, paint, 1.0f); // Initial opacity
55
+ canvas.restore();
56
+
57
+ return bitmap;
58
+ }
56
59
 
60
+ private static Paint createPaint() {
57
61
  final Paint paint = new Paint();
58
62
  paint.setAntiAlias(true);
59
63
  paint.setFilterBitmap(true);
60
64
  paint.setDither(true);
61
-
62
- // Render the main view and its children
63
- final Canvas canvas = new Canvas(bitmap);
64
-
65
- // Renders view with child views to canvas
66
- renderViewToCanvas(canvas, view, paint);
67
-
68
- return bitmap;
65
+ return paint;
69
66
  }
70
67
 
71
- private static void renderViewToCanvas(Canvas canvas, View view, Paint paint) {
72
- // Apply transformations for the current view
68
+ private static void renderViewToCanvas(Canvas canvas, View view, Paint paint, float parentOpacity) {
69
+ float combinedOpacity = parentOpacity * view.getAlpha();
73
70
  canvas.save();
74
71
  applyTransformations(canvas, view);
75
72
 
76
- // Draw children if the view has children
77
- if ((view instanceof ViewGroup)) {
78
- // Draw children
73
+ if (view instanceof ViewGroup) {
79
74
  ViewGroup group = (ViewGroup) view;
75
+ drawBackgroundIfPresent(canvas, view, combinedOpacity);
76
+ drawChildren(canvas, group, paint, combinedOpacity);
77
+ } else {
78
+ drawView(canvas, view, paint, combinedOpacity);
79
+ }
80
80
 
81
- // Hide visible children - this needs to be done because view.draw(canvas)
82
- // will render all visible non-texture/surface views directly - causing
83
- // views to be rendered twice - once by view.draw() and once when we
84
- // enumerate children. We therefore need to turn off rendering of visible
85
- // children before we call view.draw:
86
- List<View> visibleChildren = new ArrayList<>();
87
- for (int i = 0; i < group.getChildCount(); i++) {
88
- View child = group.getChildAt(i);
89
- if (child.getVisibility() == VISIBLE) {
90
- visibleChildren.add(child);
91
- child.setVisibility(View.INVISIBLE);
92
- }
93
- }
81
+ canvas.restore();
82
+ }
94
83
 
95
- // Draw ourselves
96
- canvas.saveLayerAlpha(null, Math.round(view.getAlpha() * 255));
97
- view.draw(canvas);
84
+ private static void drawBackgroundIfPresent(Canvas canvas, View view, float opacity) {
85
+ Drawable bg = view.getBackground();
86
+ if (bg != null) {
87
+ canvas.saveLayerAlpha(null, Math.round(opacity * 255));
88
+ bg.draw(canvas);
98
89
  canvas.restore();
90
+ }
91
+ }
99
92
 
100
- // Enable children again
101
- for (int i = 0; i < visibleChildren.size(); i++) {
102
- View child = visibleChildren.get(i);
103
- child.setVisibility(VISIBLE);
93
+ private static void drawChildren(Canvas canvas, ViewGroup group, Paint paint, float parentOpacity) {
94
+ // Handle clipping for ReactViewGroup
95
+ if (group instanceof ReactViewGroup) {
96
+ try {
97
+ Class[] cArg = new Class[1];
98
+ cArg[0] = Canvas.class;
99
+ Method method = ReactViewGroup.class.getDeclaredMethod("dispatchOverflowDraw", cArg);
100
+ method.setAccessible(true);
101
+ method.invoke(group, canvas);
102
+ } catch (Exception e) {
103
+ Log.e(TAG, "couldn't invoke dispatchOverflowDraw() on ReactViewGroup", e);
104
104
  }
105
+ }
106
+ for (int i = 0; i < group.getChildCount(); i++) {
107
+ View child = group.getChildAt(i);
108
+ if (child.getVisibility() != View.VISIBLE) continue;
109
+
110
+ if (child instanceof TextureView) {
111
+ drawTextureView(canvas, (TextureView) child, paint, parentOpacity);
112
+ } else if (child instanceof SurfaceView) {
113
+ drawSurfaceView(canvas, (SurfaceView) child, paint, parentOpacity);
114
+ } else {
115
+ renderViewToCanvas(canvas, child, paint, parentOpacity);
116
+ }
117
+ }
118
+ }
105
119
 
106
- // Draw children
107
- for (int i = 0; i < group.getChildCount(); i++) {
108
- View child = group.getChildAt(i);
109
-
110
- // skip all invisible to user child views
111
- if (child.getVisibility() != VISIBLE) continue;
120
+ private static void drawView(Canvas canvas, View view, Paint paint, float opacity) {
121
+ canvas.saveLayerAlpha(null, Math.round(opacity * 255));
122
+ view.draw(canvas);
123
+ canvas.restore();
124
+ }
112
125
 
113
- // skip any child that we don't know how to process
114
- if (child instanceof TextureView) {
115
- final TextureView tvChild = (TextureView) child;
116
- tvChild.setOpaque(false); // <-- switch off background fill
126
+ private static void drawTextureView(Canvas canvas, TextureView tv, Paint paint, float opacity) {
127
+ tv.setOpaque(false);
128
+ Bitmap childBitmapBuffer = tv.getBitmap(Bitmap.createBitmap(tv.getWidth(), tv.getHeight(), Bitmap.Config.ARGB_8888));
129
+ canvas.save();
130
+ applyTransformations(canvas, tv);
131
+ paint.setAlpha(Math.round(opacity * 255)); // Set paint alpha based on opacity
132
+ canvas.drawBitmap(childBitmapBuffer, 0, 0, paint);
133
+ canvas.restore();
134
+ }
117
135
 
136
+ private static void drawSurfaceView(Canvas canvas, SurfaceView sv, Paint paint, float opacity) {
137
+ final CountDownLatch latch = new CountDownLatch(1);
138
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
139
+ Bitmap childBitmapBuffer = Bitmap.createBitmap(sv.getWidth(), sv.getHeight(), Bitmap.Config.ARGB_8888);
140
+ try {
141
+ PixelCopy.request(sv, childBitmapBuffer, copyResult -> {
118
142
  canvas.save();
119
- applyTransformations(canvas, child);
120
-
121
- // TextureView should use bitmaps with matching size,
122
- // otherwise content of the TextureView will be scaled to provided bitmap dimensions
123
- final Bitmap childBitmapBuffer = tvChild.getBitmap(Bitmap.createBitmap(child.getWidth(), child.getHeight(), Bitmap.Config.ARGB_8888));
143
+ applyTransformations(canvas, sv);
144
+ paint.setAlpha(Math.round(opacity * 255)); // Set paint alpha based on opacity
124
145
  canvas.drawBitmap(childBitmapBuffer, 0, 0, paint);
125
-
126
146
  canvas.restore();
127
-
128
- } else if (child instanceof SurfaceView) {
129
- final SurfaceView svChild = (SurfaceView) child;
130
- final CountDownLatch latch = new CountDownLatch(1);
131
-
132
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
133
- final Bitmap childBitmapBuffer = Bitmap.createBitmap(child.getWidth(), child.getHeight(), Bitmap.Config.ARGB_8888);
134
- try {
135
- PixelCopy.request(svChild, childBitmapBuffer, copyResult -> {
136
- canvas.save();
137
- applyTransformations(canvas, child);
138
- canvas.drawBitmap(childBitmapBuffer, 0, 0, paint);
139
- canvas.restore();
140
- latch.countDown();
141
- }, new Handler(Looper.getMainLooper()));
142
- latch.await(SURFACE_VIEW_READ_PIXELS_TIMEOUT, TimeUnit.SECONDS);
143
- } catch (Exception e) {
144
- Log.e(TAG, "Cannot PixelCopy for " + svChild, e);
145
- }
146
- } else {
147
- Bitmap cache = svChild.getDrawingCache();
148
- if (cache != null) {
149
- canvas.save();
150
- applyTransformations(canvas, child);
151
- canvas.drawBitmap(svChild.getDrawingCache(), 0, 0, paint);
152
- canvas.restore();
153
- }
154
- }
155
- } else {
156
- // Regular views needs to be rendered again to ensure correct z-index
157
- // order with texture views and surface views.
158
- renderViewToCanvas(canvas, child, paint);
159
- }
147
+ latch.countDown();
148
+ }, new Handler(Looper.getMainLooper()));
149
+ latch.await(SURFACE_VIEW_READ_PIXELS_TIMEOUT, TimeUnit.SECONDS);
150
+ } catch (Exception e) {
151
+ Log.e(TAG, "Cannot PixelCopy for " + sv, e);
160
152
  }
161
153
  } else {
162
- // Draw ourselves
163
- view.draw(canvas);
154
+ Bitmap cache = sv.getDrawingCache();
155
+ if (cache != null) {
156
+ canvas.save();
157
+ applyTransformations(canvas, sv);
158
+ paint.setAlpha(Math.round(opacity * 255)); // Set paint alpha based on opacity
159
+ canvas.drawBitmap(cache, 0, 0, paint);
160
+ canvas.restore();
161
+ }
164
162
  }
165
-
166
- // Restore canvas
167
- canvas.restore();
168
163
  }
169
164
 
170
165
  @NonNull
171
166
  private static void applyTransformations(final Canvas c, @NonNull final View view) {
172
- // Get the transformation matrix of the view
173
167
  final Matrix matrix = view.getMatrix();
174
-
175
- // Create a new matrix for translation
176
168
  final Matrix translateMatrix = new Matrix();
177
- final float dx = view.getLeft() + view.getPaddingLeft();
178
- final float dy = view.getTop() + view.getPaddingTop();
179
- translateMatrix.setTranslate(dx, dy);
180
-
181
- // Pre-concatenate the current matrix of the canvas with the translation and transformation matrices of the view
169
+ translateMatrix.setTranslate(view.getLeft() + view.getPaddingLeft(), view.getTop() + view.getPaddingTop());
182
170
  c.concat(translateMatrix);
183
171
  c.concat(matrix);
184
172
  }
@@ -24,6 +24,7 @@
24
24
  #include "JsiSkMaskFilterFactory.h"
25
25
  #include "JsiSkMatrix.h"
26
26
  #include "JsiSkPaint.h"
27
+ #include "JsiSkParagraphBuilder.h"
27
28
  #include "JsiSkPath.h"
28
29
  #include "JsiSkPathEffect.h"
29
30
  #include "JsiSkPathEffectFactory.h"
@@ -112,6 +113,10 @@ public:
112
113
  installReadonlyProperty(
113
114
  "TypefaceFontProvider",
114
115
  std::make_shared<JsiSkTypefaceFontProviderFactory>(context));
116
+
117
+ installReadonlyProperty(
118
+ "ParagraphBuilder",
119
+ std::make_shared<JsiSkParagraphBuilderFactory>(context));
115
120
  }
116
121
  };
117
122
  } // namespace RNSkia
@@ -22,13 +22,18 @@ namespace jsi = facebook::jsi;
22
22
 
23
23
  class JsiSkFontMgrFactory : public JsiSkHostObject {
24
24
  public:
25
- JSI_HOST_FUNCTION(System) {
26
- auto context = getContext();
25
+ static sk_sp<SkFontMgr>
26
+ getFontMgr(std::shared_ptr<RNSkPlatformContext> context) {
27
27
  static SkOnce once;
28
28
  static sk_sp<SkFontMgr> fontMgr;
29
- once([&context, &runtime] { fontMgr = context->createFontMgr(); });
29
+ once([&context] { fontMgr = context->createFontMgr(); });
30
+ return fontMgr;
31
+ }
32
+
33
+ JSI_HOST_FUNCTION(System) {
34
+ auto fontMgr = JsiSkFontMgrFactory::getFontMgr(getContext());
30
35
  return jsi::Object::createFromHostObject(
31
- runtime, std::make_shared<JsiSkFontMgr>(std::move(context), fontMgr));
36
+ runtime, std::make_shared<JsiSkFontMgr>(getContext(), fontMgr));
32
37
  }
33
38
 
34
39
  JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkFontMgrFactory, System))
@@ -0,0 +1,135 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <string>
5
+ #include <utility>
6
+ #include <vector>
7
+
8
+ #include <jsi/jsi.h>
9
+
10
+ #include <JsiSkCanvas.h>
11
+ #include <JsiSkHostObjects.h>
12
+ #include <JsiSkPath.h>
13
+ #include <JsiSkRect.h>
14
+
15
+ #pragma clang diagnostic push
16
+ #pragma clang diagnostic ignored "-Wdocumentation"
17
+
18
+ #include "Paragraph.h"
19
+ #include "ParagraphBuilder.h"
20
+ #include "ParagraphStyle.h"
21
+
22
+ #pragma clang diagnostic pop
23
+
24
+ namespace RNSkia {
25
+
26
+ namespace jsi = facebook::jsi;
27
+
28
+ namespace para = skia::textlayout;
29
+
30
+ /**
31
+ Implementation of the Paragraph object in JSI
32
+ */
33
+ class JsiSkParagraph : public JsiSkHostObject {
34
+ public:
35
+ JSI_HOST_FUNCTION(layout) {
36
+ auto width = getArgumentAsNumber(runtime, arguments, count, 0);
37
+ _paragraph->layout(width);
38
+ return jsi::Value::undefined();
39
+ }
40
+
41
+ JSI_HOST_FUNCTION(paint) {
42
+ auto jsiCanvas =
43
+ getArgumentAsHostObject<JsiSkCanvas>(runtime, arguments, count, 0);
44
+ auto x = getArgumentAsNumber(runtime, arguments, count, 1);
45
+ auto y = getArgumentAsNumber(runtime, arguments, count, 2);
46
+ _paragraph->paint(jsiCanvas->getCanvas(), x, y);
47
+ return jsi::Value::undefined();
48
+ }
49
+
50
+ JSI_HOST_FUNCTION(getHeight) {
51
+ return static_cast<double>(_paragraph->getHeight());
52
+ }
53
+
54
+ JSI_HOST_FUNCTION(getMaxWidth) {
55
+ return static_cast<double>(_paragraph->getMaxWidth());
56
+ }
57
+
58
+ JSI_HOST_FUNCTION(getGlyphPositionAtCoordinate) {
59
+ auto dx = getArgumentAsNumber(runtime, arguments, count, 0);
60
+ auto dy = getArgumentAsNumber(runtime, arguments, count, 1);
61
+ auto result = _paragraph->getGlyphPositionAtCoordinate(dx, dy);
62
+ return result.position;
63
+ }
64
+
65
+ JSI_HOST_FUNCTION(getRectsForRange) {
66
+ auto start = getArgumentAsNumber(runtime, arguments, count, 0);
67
+ auto end = getArgumentAsNumber(runtime, arguments, count, 1);
68
+ auto result =
69
+ _paragraph->getRectsForRange(start, end, para::RectHeightStyle::kTight,
70
+ para::RectWidthStyle::kTight);
71
+ auto returnValue = jsi::Array(runtime, result.size());
72
+ for (size_t i = 0; i < result.size(); ++i) {
73
+ returnValue.setValueAtIndex(
74
+ runtime, i,
75
+ JsiSkRect::toValue(runtime, getContext(), result[i].rect));
76
+ }
77
+ return returnValue;
78
+ }
79
+
80
+ JSI_HOST_FUNCTION(getLineMetrics) {
81
+ std::vector<para::LineMetrics> metrics;
82
+ _paragraph->getLineMetrics(metrics);
83
+ auto returnValue = jsi::Array(runtime, metrics.size());
84
+ auto height = 0;
85
+ for (size_t i = 0; i < metrics.size(); ++i) {
86
+ returnValue.setValueAtIndex(
87
+ runtime, i,
88
+ JsiSkRect::toValue(runtime, getContext(),
89
+ SkRect::MakeXYWH(metrics[i].fLeft, height,
90
+ metrics[i].fWidth,
91
+ metrics[i].fHeight)));
92
+ height += metrics[i].fHeight;
93
+ }
94
+ return returnValue;
95
+ }
96
+
97
+ JSI_HOST_FUNCTION(getRectsForPlaceholders) {
98
+ std::vector<para::TextBox> placeholderInfos =
99
+ _paragraph->getRectsForPlaceholders();
100
+ auto returnValue = jsi::Array(runtime, placeholderInfos.size());
101
+ for (size_t i = 0; i < placeholderInfos.size(); ++i) {
102
+ auto obj = jsi::Object(runtime);
103
+ obj.setProperty(
104
+ runtime, "rect",
105
+ JsiSkRect::toValue(runtime, getContext(), placeholderInfos[i].rect));
106
+ obj.setProperty(runtime, "direction",
107
+ static_cast<double>(placeholderInfos[i].direction));
108
+ returnValue.setValueAtIndex(runtime, i, obj);
109
+ }
110
+ return returnValue;
111
+ }
112
+
113
+ JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkParagraph, layout),
114
+ JSI_EXPORT_FUNC(JsiSkParagraph, paint),
115
+ JSI_EXPORT_FUNC(JsiSkParagraph, getMaxWidth),
116
+ JSI_EXPORT_FUNC(JsiSkParagraph, getHeight),
117
+ JSI_EXPORT_FUNC(JsiSkParagraph, getRectsForPlaceholders),
118
+ JSI_EXPORT_FUNC(JsiSkParagraph,
119
+ getGlyphPositionAtCoordinate),
120
+ JSI_EXPORT_FUNC(JsiSkParagraph, getRectsForRange),
121
+ JSI_EXPORT_FUNC(JsiSkParagraph, getLineMetrics))
122
+
123
+ explicit JsiSkParagraph(std::shared_ptr<RNSkPlatformContext> context,
124
+ para::ParagraphBuilder *paragraphBuilder)
125
+ : JsiSkHostObject(std::move(context)) {
126
+ _paragraph = paragraphBuilder->Build();
127
+ }
128
+
129
+ para::Paragraph *getParagraph() { return _paragraph.get(); }
130
+
131
+ private:
132
+ std::unique_ptr<para::Paragraph> _paragraph;
133
+ };
134
+
135
+ } // namespace RNSkia