@shopify/react-native-skia 2.2.9 → 2.2.11
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.
- package/cpp/api/JsiSkParagraph.h +24 -23
- package/cpp/api/recorder/DrawingCtx.h +2 -2
- package/cpp/api/recorder/JsiRecorder.h +3 -4
- package/cpp/api/recorder/Shaders.h +3 -2
- package/cpp/rnskia/RNSkJsiViewApi.h +19 -10
- package/lib/commonjs/renderer/Canvas.d.ts +1 -0
- package/lib/commonjs/renderer/Canvas.js +18 -1
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/commonjs/sksg/Container.d.ts +1 -1
- package/lib/commonjs/sksg/Container.js +2 -2
- package/lib/commonjs/sksg/Container.js.map +1 -1
- package/lib/commonjs/sksg/Container.native.js +2 -5
- package/lib/commonjs/sksg/Container.native.js.map +1 -1
- package/lib/commonjs/sksg/Container.web.d.ts +2 -3
- package/lib/commonjs/sksg/Container.web.js +7 -14
- package/lib/commonjs/sksg/Container.web.js.map +1 -1
- package/lib/commonjs/sksg/StaticContainer.d.ts +2 -4
- package/lib/commonjs/sksg/StaticContainer.js +1 -8
- package/lib/commonjs/sksg/StaticContainer.js.map +1 -1
- package/lib/commonjs/specs/NativeSkiaModule.web.d.ts +3 -3
- package/lib/commonjs/specs/NativeSkiaModule.web.js +1 -0
- package/lib/commonjs/specs/NativeSkiaModule.web.js.map +1 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +1 -2
- package/lib/commonjs/views/SkiaPictureView.web.d.ts +10 -6
- package/lib/commonjs/views/SkiaPictureView.web.js +253 -20
- package/lib/commonjs/views/SkiaPictureView.web.js.map +1 -1
- package/lib/commonjs/views/types.d.ts +1 -0
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/renderer/Canvas.d.ts +1 -0
- package/lib/module/renderer/Canvas.js +19 -2
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/lib/module/sksg/Container.d.ts +1 -1
- package/lib/module/sksg/Container.js +2 -2
- package/lib/module/sksg/Container.js.map +1 -1
- package/lib/module/sksg/Container.native.js +2 -5
- package/lib/module/sksg/Container.native.js.map +1 -1
- package/lib/module/sksg/Container.web.d.ts +2 -3
- package/lib/module/sksg/Container.web.js +7 -14
- package/lib/module/sksg/Container.web.js.map +1 -1
- package/lib/module/sksg/StaticContainer.d.ts +2 -4
- package/lib/module/sksg/StaticContainer.js +1 -8
- package/lib/module/sksg/StaticContainer.js.map +1 -1
- package/lib/module/specs/NativeSkiaModule.web.d.ts +3 -3
- package/lib/module/specs/NativeSkiaModule.web.js +1 -0
- package/lib/module/specs/NativeSkiaModule.web.js.map +1 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +1 -2
- package/lib/module/views/SkiaPictureView.web.d.ts +10 -6
- package/lib/module/views/SkiaPictureView.web.js +251 -18
- package/lib/module/views/SkiaPictureView.web.js.map +1 -1
- package/lib/module/views/types.d.ts +1 -0
- package/lib/module/views/types.js.map +1 -1
- package/lib/typescript/lib/commonjs/sksg/Container.d.ts +1 -1
- package/lib/typescript/lib/commonjs/sksg/Container.web.d.ts +2 -3
- package/lib/typescript/lib/commonjs/sksg/StaticContainer.d.ts +1 -2
- package/lib/typescript/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +11 -1
- package/lib/typescript/lib/commonjs/views/SkiaPictureView.web.d.ts +1 -6
- package/lib/typescript/lib/module/sksg/Container.d.ts +1 -1
- package/lib/typescript/lib/module/sksg/Container.web.d.ts +2 -3
- package/lib/typescript/lib/module/sksg/StaticContainer.d.ts +1 -2
- package/lib/typescript/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +1 -2
- package/lib/typescript/lib/module/views/SkiaPictureView.web.d.ts +2 -6
- package/lib/typescript/src/renderer/Canvas.d.ts +1 -0
- package/lib/typescript/src/sksg/Container.d.ts +1 -1
- package/lib/typescript/src/sksg/Container.web.d.ts +2 -3
- package/lib/typescript/src/sksg/StaticContainer.d.ts +2 -4
- package/lib/typescript/src/specs/NativeSkiaModule.web.d.ts +3 -3
- package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.web.d.ts +1 -2
- package/lib/typescript/src/views/SkiaPictureView.web.d.ts +10 -6
- package/lib/typescript/src/views/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/renderer/Canvas.tsx +18 -0
- package/src/renderer/__tests__/e2e/ParagraphMethods.spec.tsx +115 -110
- package/src/sksg/Container.native.ts +2 -9
- package/src/sksg/Container.ts +2 -2
- package/src/sksg/Container.web.ts +7 -25
- package/src/sksg/StaticContainer.ts +2 -17
- package/src/specs/NativeSkiaModule.web.ts +5 -4
- package/src/views/SkiaPictureView.web.tsx +312 -18
- package/src/views/types.ts +4 -0
- package/lib/commonjs/views/SkiaBaseWebView.d.ts +0 -40
- package/lib/commonjs/views/SkiaBaseWebView.js +0 -143
- package/lib/commonjs/views/SkiaBaseWebView.js.map +0 -1
- package/lib/module/views/SkiaBaseWebView.d.ts +0 -40
- package/lib/module/views/SkiaBaseWebView.js +0 -136
- package/lib/module/views/SkiaBaseWebView.js.map +0 -1
- package/lib/typescript/lib/commonjs/views/SkiaBaseWebView.d.ts +0 -39
- package/lib/typescript/lib/module/views/SkiaBaseWebView.d.ts +0 -36
- package/lib/typescript/src/views/SkiaBaseWebView.d.ts +0 -40
- package/src/views/SkiaBaseWebView.tsx +0 -140
@@ -1,5 +1,4 @@
|
|
1
|
-
import type {
|
2
|
-
import type { Skia, SkCanvas, SkSize } from "../skia/types";
|
1
|
+
import type { Skia, SkCanvas } from "../skia/types";
|
3
2
|
import type { Node } from "./Node";
|
4
3
|
import type { Recording } from "./Recorder/Recorder";
|
5
4
|
import "../views/api";
|
@@ -18,7 +17,6 @@ export declare abstract class Container {
|
|
18
17
|
}
|
19
18
|
export declare class StaticContainer extends Container {
|
20
19
|
private nativeId;
|
21
|
-
|
22
|
-
constructor(Skia: Skia, nativeId: number, onSize?: SharedValue<SkSize> | undefined);
|
20
|
+
constructor(Skia: Skia, nativeId: number);
|
23
21
|
redraw(): void;
|
24
22
|
}
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import type { SkPicture } from "../skia/types";
|
2
2
|
import type { ISkiaViewApi } from "../views/types";
|
3
|
-
import type {
|
3
|
+
import type { SkiaPictureViewHandle } from "../views/SkiaPictureView.web";
|
4
4
|
export type ISkiaViewApiWeb = ISkiaViewApi & {
|
5
|
-
views: Record<string,
|
5
|
+
views: Record<string, SkiaPictureViewHandle>;
|
6
6
|
deferedPictures: Record<string, SkPicture>;
|
7
|
-
registerView(nativeId: string, view:
|
7
|
+
registerView(nativeId: string, view: SkiaPictureViewHandle): void;
|
8
8
|
};
|
9
9
|
declare const _default: {};
|
10
10
|
export default _default;
|
@@ -1,9 +1,8 @@
|
|
1
1
|
import type { ViewProps } from "react-native";
|
2
|
-
import { SkiaPictureView } from "../views/SkiaPictureView.web";
|
3
2
|
export interface NativeProps extends ViewProps {
|
4
3
|
debug?: boolean;
|
5
4
|
opaque?: boolean;
|
6
5
|
nativeID: string;
|
7
6
|
}
|
8
|
-
declare const SkiaPictureViewNativeComponent: ({ nativeID, debug, opaque, onLayout, ...viewProps }: NativeProps) => import("react").
|
7
|
+
declare const SkiaPictureViewNativeComponent: ({ nativeID, debug, opaque, onLayout, ...viewProps }: NativeProps) => import("react").FunctionComponentElement<import("..").SkiaPictureViewNativeProps & import("react").RefAttributes<import("../views/SkiaPictureView.web").SkiaPictureViewHandle>>;
|
9
8
|
export default SkiaPictureViewNativeComponent;
|
@@ -1,9 +1,13 @@
|
|
1
|
-
import
|
1
|
+
import React from "react";
|
2
|
+
import type { SkRect, SkPicture, SkImage } from "../skia/types";
|
2
3
|
import type { SkiaPictureViewNativeProps } from "./types";
|
3
|
-
|
4
|
-
export declare class SkiaPictureView extends SkiaBaseWebView<SkiaPictureViewNativeProps> {
|
5
|
-
private picture;
|
6
|
-
constructor(props: SkiaPictureViewNativeProps);
|
4
|
+
export interface SkiaPictureViewHandle {
|
7
5
|
setPicture(picture: SkPicture): void;
|
8
|
-
|
6
|
+
getSize(): {
|
7
|
+
width: number;
|
8
|
+
height: number;
|
9
|
+
};
|
10
|
+
redraw(): void;
|
11
|
+
makeImageSnapshot(rect?: SkRect): SkImage | null;
|
9
12
|
}
|
13
|
+
export declare const SkiaPictureView: React.ForwardRefExoticComponent<SkiaPictureViewNativeProps & React.RefAttributes<SkiaPictureViewHandle>>;
|
@@ -26,6 +26,7 @@ export interface SkiaBaseViewProps extends ViewProps {
|
|
26
26
|
*/
|
27
27
|
onSize?: SharedValue<SkSize>;
|
28
28
|
opaque?: boolean;
|
29
|
+
__destroyWebGLContextAfterRender?: boolean;
|
29
30
|
}
|
30
31
|
export interface SkiaPictureViewNativeProps extends SkiaBaseViewProps {
|
31
32
|
picture?: SkPicture;
|
package/package.json
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
"setup-skia-web": "scripts/setup-canvaskit.js"
|
9
9
|
},
|
10
10
|
"title": "React Native Skia",
|
11
|
-
"version": "2.2.
|
11
|
+
"version": "2.2.11",
|
12
12
|
"description": "High-performance React Native Graphics using Skia",
|
13
13
|
"main": "lib/module/index.js",
|
14
14
|
"react-native": "src/index.ts",
|
package/src/renderer/Canvas.tsx
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import type { FC, RefObject } from "react";
|
2
2
|
import React, {
|
3
|
+
useCallback,
|
3
4
|
useEffect,
|
4
5
|
useImperativeHandle,
|
5
6
|
useLayoutEffect,
|
@@ -8,6 +9,7 @@ import React, {
|
|
8
9
|
useState,
|
9
10
|
} from "react";
|
10
11
|
import type {
|
12
|
+
LayoutChangeEvent,
|
11
13
|
MeasureInWindowOnSuccessCallback,
|
12
14
|
MeasureOnSuccessCallback,
|
13
15
|
View,
|
@@ -20,6 +22,7 @@ import SkiaPictureViewNativeComponent from "../specs/SkiaPictureViewNativeCompon
|
|
20
22
|
import type { SkImage, SkRect, SkSize } from "../skia/types";
|
21
23
|
import { SkiaSGRoot } from "../sksg/Reconciler";
|
22
24
|
import { Skia } from "../skia";
|
25
|
+
import { Platform } from "../Platform";
|
23
26
|
|
24
27
|
export interface CanvasRef extends FC<CanvasProps> {
|
25
28
|
makeImageSnapshot(rect?: SkRect): SkImage;
|
@@ -56,6 +59,7 @@ export interface CanvasProps extends Omit<ViewProps, "onLayout"> {
|
|
56
59
|
onSize?: SharedValue<SkSize>;
|
57
60
|
colorSpace?: "p3" | "srgb";
|
58
61
|
ref?: React.Ref<CanvasRef>;
|
62
|
+
__destroyWebGLContextAfterRender?: boolean;
|
59
63
|
}
|
60
64
|
|
61
65
|
export const Canvas = ({
|
@@ -126,6 +130,19 @@ export const Canvas = ({
|
|
126
130
|
} as CanvasRef)
|
127
131
|
);
|
128
132
|
|
133
|
+
const onLayoutWeb = useCallback(
|
134
|
+
(e: LayoutChangeEvent) => {
|
135
|
+
if (onLayout) {
|
136
|
+
onLayout(e);
|
137
|
+
}
|
138
|
+
if (Platform.OS === "web" && onSize) {
|
139
|
+
const { width, height } = e.nativeEvent.layout;
|
140
|
+
onSize.value = { width, height };
|
141
|
+
}
|
142
|
+
},
|
143
|
+
[onLayout, onSize]
|
144
|
+
);
|
145
|
+
|
129
146
|
return (
|
130
147
|
<SkiaPictureViewNativeComponent
|
131
148
|
ref={viewRef}
|
@@ -134,6 +151,7 @@ export const Canvas = ({
|
|
134
151
|
debug={debug}
|
135
152
|
opaque={opaque}
|
136
153
|
colorSpace={colorSpace}
|
154
|
+
onLayout={onLayoutWeb}
|
137
155
|
{...viewProps}
|
138
156
|
/>
|
139
157
|
);
|
@@ -11,109 +11,109 @@ const RobotoRegular = Array.from(
|
|
11
11
|
|
12
12
|
describe("Paragraph Methods", () => {
|
13
13
|
describe("getRectsForPlaceholders", () => {
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
14
|
+
it("should handle multiple placeholders with different alignments", async () => {
|
15
|
+
const placeholderRects = await surface.eval(
|
16
|
+
(Skia, ctx) => {
|
17
|
+
const robotoRegular = Skia.Typeface.MakeFreeTypeFaceFromData(
|
18
|
+
Skia.Data.fromBytes(new Uint8Array(ctx.RobotoRegular))
|
19
|
+
)!;
|
20
|
+
const provider = Skia.TypefaceFontProvider.Make();
|
21
|
+
provider.registerFont(robotoRegular, "Roboto");
|
22
|
+
|
23
|
+
const builder = Skia.ParagraphBuilder.Make(
|
24
|
+
{
|
25
|
+
textStyle: {
|
26
|
+
color: Skia.Color("black"),
|
27
|
+
fontFamilies: ["Roboto"],
|
28
|
+
fontSize: 16,
|
29
|
+
},
|
29
30
|
},
|
30
|
-
|
31
|
-
|
32
|
-
);
|
33
|
-
|
34
|
-
builder.addText("Start ");
|
35
|
-
builder.addPlaceholder(
|
36
|
-
20,
|
37
|
-
20,
|
38
|
-
ctx.PlaceholderAlignment.Baseline,
|
39
|
-
ctx.TextBaseline.Alphabetic
|
40
|
-
);
|
41
|
-
builder.addText(" middle ");
|
42
|
-
builder.addPlaceholder(
|
43
|
-
15,
|
44
|
-
15,
|
45
|
-
ctx.PlaceholderAlignment.Top,
|
46
|
-
ctx.TextBaseline.Alphabetic
|
47
|
-
);
|
48
|
-
builder.addText(" end");
|
49
|
-
|
50
|
-
const paragraph = builder.build();
|
51
|
-
paragraph.layout(200);
|
52
|
-
|
53
|
-
const rects = paragraph.getRectsForPlaceholders();
|
54
|
-
return rects.map((r) => ({
|
55
|
-
x: r.rect.x,
|
56
|
-
y: r.rect.y,
|
57
|
-
width: r.rect.width,
|
58
|
-
height: r.rect.height,
|
59
|
-
direction: r.direction,
|
60
|
-
}));
|
61
|
-
},
|
62
|
-
{
|
63
|
-
RobotoRegular,
|
64
|
-
PlaceholderAlignment,
|
65
|
-
TextBaseline,
|
66
|
-
}
|
67
|
-
);
|
68
|
-
|
69
|
-
expect(placeholderRects).toHaveLength(2);
|
70
|
-
expect(placeholderRects[0].width).toBe(20);
|
71
|
-
expect(placeholderRects[0].height).toBe(20);
|
72
|
-
expect(placeholderRects[1].width).toBeCloseTo(15);
|
73
|
-
expect(placeholderRects[1].height).toBeCloseTo(15);
|
74
|
-
});
|
31
|
+
provider
|
32
|
+
);
|
75
33
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
34
|
+
builder.addText("Start ");
|
35
|
+
builder.addPlaceholder(
|
36
|
+
20,
|
37
|
+
20,
|
38
|
+
ctx.PlaceholderAlignment.Baseline,
|
39
|
+
ctx.TextBaseline.Alphabetic
|
40
|
+
);
|
41
|
+
builder.addText(" middle ");
|
42
|
+
builder.addPlaceholder(
|
43
|
+
15,
|
44
|
+
15,
|
45
|
+
ctx.PlaceholderAlignment.Top,
|
46
|
+
ctx.TextBaseline.Alphabetic
|
47
|
+
);
|
48
|
+
builder.addText(" end");
|
49
|
+
|
50
|
+
const paragraph = builder.build();
|
51
|
+
paragraph.layout(200);
|
52
|
+
|
53
|
+
const rects = paragraph.getRectsForPlaceholders();
|
54
|
+
return rects.map((r) => ({
|
55
|
+
x: r.rect.x,
|
56
|
+
y: r.rect.y,
|
57
|
+
width: r.rect.width,
|
58
|
+
height: r.rect.height,
|
59
|
+
direction: r.direction,
|
60
|
+
}));
|
61
|
+
},
|
62
|
+
{
|
63
|
+
RobotoRegular,
|
64
|
+
PlaceholderAlignment,
|
65
|
+
TextBaseline,
|
66
|
+
}
|
67
|
+
);
|
68
|
+
|
69
|
+
expect(placeholderRects).toHaveLength(2);
|
70
|
+
expect(placeholderRects[0].width).toBe(20);
|
71
|
+
expect(placeholderRects[0].height).toBe(20);
|
72
|
+
expect(placeholderRects[1].width).toBeCloseTo(15);
|
73
|
+
expect(placeholderRects[1].height).toBeCloseTo(15);
|
74
|
+
});
|
75
|
+
|
76
|
+
it("should return correct direction for placeholders", async () => {
|
77
|
+
const placeholderInfo = await surface.eval(
|
78
|
+
(Skia, ctx) => {
|
79
|
+
const robotoRegular = Skia.Typeface.MakeFreeTypeFaceFromData(
|
80
|
+
Skia.Data.fromBytes(new Uint8Array(ctx.RobotoRegular))
|
81
|
+
)!;
|
82
|
+
const provider = Skia.TypefaceFontProvider.Make();
|
83
|
+
provider.registerFont(robotoRegular, "Roboto");
|
84
|
+
|
85
|
+
const builder = Skia.ParagraphBuilder.Make(
|
86
|
+
{
|
87
|
+
textStyle: {
|
88
|
+
color: Skia.Color("black"),
|
89
|
+
fontFamilies: ["Roboto"],
|
90
|
+
fontSize: 16,
|
91
|
+
},
|
91
92
|
},
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
}
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
});
|
93
|
+
provider
|
94
|
+
);
|
95
|
+
|
96
|
+
builder.addText("Text with ");
|
97
|
+
builder.addPlaceholder(30, 30);
|
98
|
+
builder.addText(" placeholder");
|
99
|
+
|
100
|
+
const paragraph = builder.build();
|
101
|
+
paragraph.layout(300);
|
102
|
+
|
103
|
+
const rects = paragraph.getRectsForPlaceholders();
|
104
|
+
return rects.map((r) => ({
|
105
|
+
direction: r.direction === ctx.TextDirection.LTR ? "LTR" : "RTL",
|
106
|
+
}));
|
107
|
+
},
|
108
|
+
{
|
109
|
+
RobotoRegular,
|
110
|
+
TextDirection,
|
111
|
+
}
|
112
|
+
);
|
113
|
+
|
114
|
+
expect(placeholderInfo).toHaveLength(1);
|
115
|
+
expect(placeholderInfo[0].direction).toBe("LTR");
|
116
|
+
});
|
117
117
|
|
118
118
|
it("should return empty array when no placeholders", async () => {
|
119
119
|
const placeholderCount = await surface.eval(
|
@@ -194,7 +194,7 @@ describe("Paragraph Methods", () => {
|
|
194
194
|
expect(lineMetrics[0].ascent).toBeGreaterThan(0);
|
195
195
|
expect(lineMetrics[0].descent).toBeGreaterThan(0);
|
196
196
|
// Note: Even single lines without explicit breaks may report isHardBreak as true
|
197
|
-
expect(typeof lineMetrics[0].isHardBreak).toBe(
|
197
|
+
expect(typeof lineMetrics[0].isHardBreak).toBe("boolean");
|
198
198
|
});
|
199
199
|
|
200
200
|
it("should return line metrics for multi-line text with wrapping", async () => {
|
@@ -232,12 +232,12 @@ describe("Paragraph Methods", () => {
|
|
232
232
|
);
|
233
233
|
|
234
234
|
expect(lineMetrics.length).toBeGreaterThan(1);
|
235
|
-
|
235
|
+
|
236
236
|
// Check first line
|
237
237
|
expect(lineMetrics[0].lineNumber).toBe(0);
|
238
238
|
expect(lineMetrics[0].startIndex).toBe(0);
|
239
239
|
expect(lineMetrics[0].width).toBeLessThanOrEqual(100);
|
240
|
-
|
240
|
+
|
241
241
|
// Check second line
|
242
242
|
expect(lineMetrics[1].lineNumber).toBe(1);
|
243
243
|
expect(lineMetrics[1].startIndex).toBeGreaterThan(0);
|
@@ -277,12 +277,12 @@ describe("Paragraph Methods", () => {
|
|
277
277
|
);
|
278
278
|
|
279
279
|
expect(lineMetrics).toHaveLength(3);
|
280
|
-
|
280
|
+
|
281
281
|
// All lines report isHardBreak as true in this implementation
|
282
282
|
expect(lineMetrics[0].isHardBreak).toBe(true);
|
283
283
|
expect(lineMetrics[1].isHardBreak).toBe(true);
|
284
284
|
expect(lineMetrics[2].isHardBreak).toBe(true);
|
285
|
-
|
285
|
+
|
286
286
|
// Check line numbers
|
287
287
|
expect(lineMetrics[0].lineNumber).toBe(0);
|
288
288
|
expect(lineMetrics[1].lineNumber).toBe(1);
|
@@ -322,19 +322,24 @@ describe("Paragraph Methods", () => {
|
|
322
322
|
);
|
323
323
|
|
324
324
|
expect(lineMetrics).toHaveLength(2);
|
325
|
-
|
325
|
+
|
326
326
|
// First line
|
327
327
|
const firstLine = lineMetrics[0];
|
328
328
|
// Height should be close to ascent + descent
|
329
329
|
expect(firstLine.height).toBeGreaterThan(0);
|
330
|
-
expect(
|
330
|
+
expect(
|
331
|
+
Math.abs(firstLine.height - (firstLine.ascent + firstLine.descent))
|
332
|
+
).toBeLessThan(1);
|
331
333
|
expect(firstLine.left).toBe(0);
|
332
334
|
expect(firstLine.baseline).toBeGreaterThan(0);
|
333
|
-
|
335
|
+
|
334
336
|
// Second line should be below the first
|
335
337
|
const secondLine = lineMetrics[1];
|
336
338
|
expect(secondLine.baseline).toBeGreaterThan(firstLine.baseline);
|
337
|
-
expect(secondLine.baseline - firstLine.baseline).toBeCloseTo(
|
339
|
+
expect(secondLine.baseline - firstLine.baseline).toBeCloseTo(
|
340
|
+
firstLine.height,
|
341
|
+
1
|
342
|
+
);
|
338
343
|
});
|
339
344
|
|
340
345
|
it("should handle empty lines correctly", async () => {
|
@@ -370,7 +375,7 @@ describe("Paragraph Methods", () => {
|
|
370
375
|
);
|
371
376
|
|
372
377
|
expect(lineMetrics).toHaveLength(3);
|
373
|
-
|
378
|
+
|
374
379
|
// Middle line should be empty but still have metrics
|
375
380
|
const emptyLine = lineMetrics[1];
|
376
381
|
// Empty line might have startIndex != endIndex depending on implementation
|
@@ -18,17 +18,10 @@ const nativeDrawOnscreen = (
|
|
18
18
|
onSize?: SharedValue<SkSize>
|
19
19
|
) => {
|
20
20
|
"worklet";
|
21
|
-
|
22
|
-
//const start = performance.now();
|
23
21
|
if (onSize) {
|
24
|
-
|
25
|
-
if (
|
26
|
-
size.width !== onSize.value.width ||
|
27
|
-
size.height !== onSize.value.height
|
28
|
-
) {
|
29
|
-
onSize.value = size;
|
30
|
-
}
|
22
|
+
SkiaViewApi.setJsiProperty(nativeId, "onSize", onSize);
|
31
23
|
}
|
24
|
+
//const start = performance.now();
|
32
25
|
const picture = recorder.play();
|
33
26
|
//const end = performance.now();
|
34
27
|
//console.log("Recording time: ", end - start);
|
package/src/sksg/Container.ts
CHANGED
@@ -7,7 +7,7 @@ import { StaticContainer } from "./StaticContainer";
|
|
7
7
|
export const createContainer = (
|
8
8
|
Skia: Skia,
|
9
9
|
nativeId: number,
|
10
|
-
|
10
|
+
_onSize?: SharedValue<SkSize>
|
11
11
|
) => {
|
12
|
-
return new StaticContainer(Skia, nativeId
|
12
|
+
return new StaticContainer(Skia, nativeId);
|
13
13
|
};
|
@@ -14,22 +14,8 @@ import { Container, StaticContainer } from "./StaticContainer";
|
|
14
14
|
import "../skia/NativeSetup";
|
15
15
|
import "../views/api";
|
16
16
|
|
17
|
-
const drawOnscreen = (
|
18
|
-
Skia: Skia,
|
19
|
-
nativeId: number,
|
20
|
-
recording: Recording,
|
21
|
-
onSize?: SharedValue<SkSize>
|
22
|
-
) => {
|
17
|
+
const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
|
23
18
|
"worklet";
|
24
|
-
if (onSize) {
|
25
|
-
const size = SkiaViewApi.size(nativeId);
|
26
|
-
if (
|
27
|
-
size.width !== onSize.value.width ||
|
28
|
-
size.height !== onSize.value.height
|
29
|
-
) {
|
30
|
-
onSize.value = size;
|
31
|
-
}
|
32
|
-
}
|
33
19
|
const rec = Skia.PictureRecorder();
|
34
20
|
const canvas = rec.beginRecording();
|
35
21
|
//const start = performance.now();
|
@@ -45,11 +31,7 @@ const drawOnscreen = (
|
|
45
31
|
class ReanimatedContainer extends Container {
|
46
32
|
private mapperId: number | null = null;
|
47
33
|
|
48
|
-
constructor(
|
49
|
-
Skia: Skia,
|
50
|
-
private nativeId: number,
|
51
|
-
private onSize?: SharedValue<SkSize>
|
52
|
-
) {
|
34
|
+
constructor(Skia: Skia, private nativeId: number) {
|
53
35
|
super(Skia);
|
54
36
|
}
|
55
37
|
|
@@ -75,20 +57,20 @@ class ReanimatedContainer extends Container {
|
|
75
57
|
drawOnscreen(Skia, nativeId, recording!);
|
76
58
|
}, Array.from(animationValues));
|
77
59
|
}
|
78
|
-
Rea.runOnUI((
|
60
|
+
Rea.runOnUI(() => {
|
79
61
|
"worklet";
|
80
|
-
drawOnscreen(Skia, nativeId, recording
|
81
|
-
})(
|
62
|
+
drawOnscreen(Skia, nativeId, recording!);
|
63
|
+
})();
|
82
64
|
}
|
83
65
|
}
|
84
66
|
|
85
67
|
export const createContainer = (
|
86
68
|
Skia: Skia,
|
87
69
|
nativeId: number,
|
88
|
-
|
70
|
+
_onSize?: SharedValue<SkSize>
|
89
71
|
) => {
|
90
72
|
if (HAS_REANIMATED_3 && nativeId !== -1) {
|
91
|
-
return new ReanimatedContainer(Skia, nativeId
|
73
|
+
return new ReanimatedContainer(Skia, nativeId);
|
92
74
|
} else {
|
93
75
|
return new StaticContainer(Skia, nativeId);
|
94
76
|
}
|
@@ -1,6 +1,4 @@
|
|
1
|
-
import type {
|
2
|
-
|
3
|
-
import type { Skia, SkCanvas, SkSize } from "../skia/types";
|
1
|
+
import type { Skia, SkCanvas } from "../skia/types";
|
4
2
|
|
5
3
|
import type { Node } from "./Node";
|
6
4
|
import type { Recording } from "./Recorder/Recorder";
|
@@ -50,11 +48,7 @@ export abstract class Container {
|
|
50
48
|
}
|
51
49
|
|
52
50
|
export class StaticContainer extends Container {
|
53
|
-
constructor(
|
54
|
-
Skia: Skia,
|
55
|
-
private nativeId: number,
|
56
|
-
private onSize?: SharedValue<SkSize>
|
57
|
-
) {
|
51
|
+
constructor(Skia: Skia, private nativeId: number) {
|
58
52
|
super(Skia);
|
59
53
|
}
|
60
54
|
|
@@ -64,15 +58,6 @@ export class StaticContainer extends Container {
|
|
64
58
|
this.recording = recorder.getRecording();
|
65
59
|
const isOnScreen = this.nativeId !== -1;
|
66
60
|
if (isOnScreen) {
|
67
|
-
if (this.onSize) {
|
68
|
-
const size = SkiaViewApi.size(this.nativeId);
|
69
|
-
if (
|
70
|
-
size.width !== this.onSize.value.width ||
|
71
|
-
size.height !== this.onSize.value.height
|
72
|
-
) {
|
73
|
-
this.onSize.value = size;
|
74
|
-
}
|
75
|
-
}
|
76
61
|
const rec = this.Skia.PictureRecorder();
|
77
62
|
const canvas = rec.beginRecording();
|
78
63
|
this.drawOnCanvas(canvas);
|
@@ -1,19 +1,20 @@
|
|
1
1
|
/* eslint-disable import/no-anonymous-default-export */
|
2
2
|
import type { SkPicture, SkRect } from "../skia/types";
|
3
3
|
import type { ISkiaViewApi } from "../views/types";
|
4
|
-
import type {
|
4
|
+
import type { SkiaPictureViewHandle } from "../views/SkiaPictureView.web";
|
5
5
|
|
6
6
|
export type ISkiaViewApiWeb = ISkiaViewApi & {
|
7
|
-
views: Record<string,
|
7
|
+
views: Record<string, SkiaPictureViewHandle>;
|
8
8
|
deferedPictures: Record<string, SkPicture>;
|
9
|
-
registerView(nativeId: string, view:
|
9
|
+
registerView(nativeId: string, view: SkiaPictureViewHandle): void;
|
10
10
|
};
|
11
11
|
|
12
12
|
global.SkiaViewApi = {
|
13
13
|
views: {},
|
14
14
|
deferedPictures: {},
|
15
|
+
deferedOnSize: {},
|
15
16
|
web: true,
|
16
|
-
registerView(nativeId: string, view:
|
17
|
+
registerView(nativeId: string, view: SkiaPictureViewHandle) {
|
17
18
|
// Maybe a picture for this view was already set
|
18
19
|
if (this.deferedPictures[nativeId]) {
|
19
20
|
view.setPicture(this.deferedPictures[nativeId] as SkPicture);
|