@napi-rs/canvas 0.1.67 → 0.1.69

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # `skr canvas`
2
2
 
3
3
  [![CI](https://github.com/Brooooooklyn/canvas/actions/workflows/CI.yaml/badge.svg)](https://github.com/Brooooooklyn/canvas/actions/workflows/CI.yaml)
4
- ![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm133-hotpink)
4
+ ![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm136-hotpink)
5
5
  [![install size](https://packagephobia.com/badge?p=@napi-rs/canvas)](https://packagephobia.com/result?p=@napi-rs/canvas)
6
6
  [![Downloads](https://img.shields.io/npm/dm/@napi-rs/canvas.svg?sanitize=true)](https://npmcharts.com/compare/@napi-rs/canvas?minimal=true)
7
7
 
package/index.d.ts CHANGED
@@ -3,6 +3,279 @@ import { ReadableStream } from 'node:stream/web'
3
3
  // Clear all type of caches in Skia
4
4
  export function clearAllCache(): void
5
5
 
6
+ interface CanvasRenderingContext2D
7
+ extends CanvasCompositing,
8
+ CanvasDrawPath,
9
+ CanvasFillStrokeStyles,
10
+ CanvasFilters,
11
+ CanvasImageData,
12
+ CanvasImageSmoothing,
13
+ CanvasPath,
14
+ CanvasPathDrawingStyles,
15
+ CanvasRect,
16
+ CanvasSettings,
17
+ CanvasShadowStyles,
18
+ CanvasState,
19
+ CanvasText,
20
+ CanvasTextDrawingStyles,
21
+ CanvasTransform {}
22
+
23
+ interface CanvasState {
24
+ isContextLost(): boolean
25
+ reset(): void
26
+ restore(): void
27
+ save(): void
28
+ }
29
+ interface CanvasShadowStyles {
30
+ shadowBlur: number
31
+ shadowColor: string
32
+ shadowOffsetX: number
33
+ shadowOffsetY: number
34
+ }
35
+ interface CanvasRenderingContext2DSettings {
36
+ alpha?: boolean
37
+ colorSpace?: PredefinedColorSpace
38
+ desynchronized?: boolean
39
+ willReadFrequently?: boolean
40
+ }
41
+ interface CanvasSettings {
42
+ getContextAttributes(): CanvasRenderingContext2DSettings
43
+ }
44
+
45
+ interface CanvasRect {
46
+ clearRect(x: number, y: number, w: number, h: number): void
47
+ fillRect(x: number, y: number, w: number, h: number): void
48
+ strokeRect(x: number, y: number, w: number, h: number): void
49
+ }
50
+
51
+ interface TextMetrics {
52
+ readonly actualBoundingBoxAscent: number
53
+ readonly actualBoundingBoxDescent: number
54
+ readonly actualBoundingBoxLeft: number
55
+ readonly actualBoundingBoxRight: number
56
+ readonly alphabeticBaseline: number
57
+ readonly emHeightAscent: number
58
+ readonly emHeightDescent: number
59
+ readonly fontBoundingBoxAscent: number
60
+ readonly fontBoundingBoxDescent: number
61
+ readonly hangingBaseline: number
62
+ readonly ideographicBaseline: number
63
+ readonly width: number
64
+ }
65
+
66
+ interface CanvasText {
67
+ fillText(text: string, x: number, y: number, maxWidth?: number): void
68
+ measureText(text: string): TextMetrics
69
+ strokeText(text: string, x: number, y: number, maxWidth?: number): void
70
+ }
71
+
72
+ type CanvasLineCap = 'butt' | 'round' | 'square'
73
+ type CanvasLineJoin = 'bevel' | 'miter' | 'round'
74
+
75
+ interface CanvasPathDrawingStyles {
76
+ lineCap: CanvasLineCap
77
+ lineDashOffset: number
78
+ lineJoin: CanvasLineJoin
79
+ lineWidth: number
80
+ miterLimit: number
81
+ getLineDash(): number[]
82
+ setLineDash(segments: number[]): void
83
+ }
84
+
85
+ interface CanvasPath {
86
+ arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void
87
+ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void
88
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void
89
+ closePath(): void
90
+ ellipse(
91
+ x: number,
92
+ y: number,
93
+ radiusX: number,
94
+ radiusY: number,
95
+ rotation: number,
96
+ startAngle: number,
97
+ endAngle: number,
98
+ counterclockwise?: boolean,
99
+ ): void
100
+ lineTo(x: number, y: number): void
101
+ moveTo(x: number, y: number): void
102
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void
103
+ rect(x: number, y: number, w: number, h: number): void
104
+ roundRect(x: number, y: number, w: number, h: number, radii?: number | DOMPointInit | (number | DOMPointInit)[]): void
105
+ }
106
+
107
+ type ImageSmoothingQuality = 'high' | 'low' | 'medium'
108
+
109
+ interface CanvasImageSmoothing {
110
+ imageSmoothingEnabled: boolean
111
+ imageSmoothingQuality: ImageSmoothingQuality
112
+ }
113
+
114
+ interface CanvasTransform {
115
+ resetTransform(): void
116
+ rotate(angle: number): void
117
+ scale(x: number, y: number): void
118
+ setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void
119
+ setTransform(transform?: DOMMatrix2DInit): void
120
+ transform(a: number, b: number, c: number, d: number, e: number, f: number): void
121
+ translate(x: number, y: number): void
122
+ }
123
+ type PredefinedColorSpace = 'display-p3' | 'srgb'
124
+
125
+ interface ImageDataSettings {
126
+ colorSpace?: PredefinedColorSpace
127
+ }
128
+ interface CanvasImageData {
129
+ createImageData(sw: number, sh: number, settings?: ImageDataSettings): ImageData
130
+ createImageData(imagedata: ImageData): ImageData
131
+ getImageData(sx: number, sy: number, sw: number, sh: number, settings?: ImageDataSettings): ImageData
132
+ putImageData(imagedata: ImageData, dx: number, dy: number): void
133
+ putImageData(
134
+ imagedata: ImageData,
135
+ dx: number,
136
+ dy: number,
137
+ dirtyX: number,
138
+ dirtyY: number,
139
+ dirtyWidth: number,
140
+ dirtyHeight: number,
141
+ ): void
142
+ }
143
+
144
+ type CanvasDirection = 'inherit' | 'ltr' | 'rtl'
145
+ type CanvasFontKerning = 'auto' | 'none' | 'normal'
146
+ type CanvasFontStretch =
147
+ | 'condensed'
148
+ | 'expanded'
149
+ | 'extra-condensed'
150
+ | 'extra-expanded'
151
+ | 'normal'
152
+ | 'semi-condensed'
153
+ | 'semi-expanded'
154
+ | 'ultra-condensed'
155
+ | 'ultra-expanded'
156
+ type CanvasFontVariantCaps =
157
+ | 'all-petite-caps'
158
+ | 'all-small-caps'
159
+ | 'normal'
160
+ | 'petite-caps'
161
+ | 'small-caps'
162
+ | 'titling-caps'
163
+ | 'unicase'
164
+ type CanvasTextAlign = 'center' | 'end' | 'left' | 'right' | 'start'
165
+ type CanvasTextBaseline = 'alphabetic' | 'bottom' | 'hanging' | 'ideographic' | 'middle' | 'top'
166
+ type CanvasTextRendering = 'auto' | 'geometricPrecision' | 'optimizeLegibility' | 'optimizeSpeed'
167
+
168
+ interface CanvasTextDrawingStyles {
169
+ direction: CanvasDirection
170
+ font: string
171
+ fontKerning: CanvasFontKerning
172
+ fontStretch: CanvasFontStretch
173
+ fontVariantCaps: CanvasFontVariantCaps
174
+ letterSpacing: string
175
+ textAlign: CanvasTextAlign
176
+ textBaseline: CanvasTextBaseline
177
+ textRendering: CanvasTextRendering
178
+ wordSpacing: string
179
+ }
180
+
181
+ interface CanvasFilters {
182
+ filter: string
183
+ }
184
+
185
+ interface CanvasFillStrokeStyles {
186
+ fillStyle: string | CanvasGradient | CanvasPattern
187
+ strokeStyle: string | CanvasGradient | CanvasPattern
188
+ createConicGradient(startAngle: number, x: number, y: number): CanvasGradient
189
+ createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient
190
+ createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient
191
+ }
192
+
193
+ type CanvasFillRule = 'evenodd' | 'nonzero'
194
+
195
+ interface CanvasDrawPath {
196
+ beginPath(): void
197
+ clip(fillRule?: CanvasFillRule): void
198
+ clip(path: Path2D, fillRule?: CanvasFillRule): void
199
+ fill(fillRule?: CanvasFillRule): void
200
+ fill(path: Path2D, fillRule?: CanvasFillRule): void
201
+ isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean
202
+ isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean
203
+ isPointInStroke(x: number, y: number): boolean
204
+ isPointInStroke(path: Path2D, x: number, y: number): boolean
205
+ stroke(): void
206
+ stroke(path: Path2D): void
207
+ }
208
+
209
+ type GlobalCompositeOperation =
210
+ | 'color'
211
+ | 'color-burn'
212
+ | 'color-dodge'
213
+ | 'copy'
214
+ | 'darken'
215
+ | 'destination-atop'
216
+ | 'destination-in'
217
+ | 'destination-out'
218
+ | 'destination-over'
219
+ | 'difference'
220
+ | 'exclusion'
221
+ | 'hard-light'
222
+ | 'hue'
223
+ | 'lighten'
224
+ | 'lighter'
225
+ | 'luminosity'
226
+ | 'multiply'
227
+ | 'overlay'
228
+ | 'saturation'
229
+ | 'screen'
230
+ | 'soft-light'
231
+ | 'source-atop'
232
+ | 'source-in'
233
+ | 'source-out'
234
+ | 'source-over'
235
+ | 'xor'
236
+
237
+ interface CanvasCompositing {
238
+ globalAlpha: number
239
+ globalCompositeOperation: GlobalCompositeOperation
240
+ }
241
+
242
+ interface DOMPointInit {
243
+ w?: number
244
+ x?: number
245
+ y?: number
246
+ z?: number
247
+ }
248
+ interface CanvasPattern {
249
+ setTransform(transform?: DOMMatrix2DInit): void
250
+ }
251
+
252
+ interface CanvasGradient {
253
+ addColorStop(offset: number, color: string): void
254
+ }
255
+
256
+ interface DOMRectInit {
257
+ height?: number
258
+ width?: number
259
+ x?: number
260
+ y?: number
261
+ }
262
+
263
+ interface DOMMatrixInit extends DOMMatrix2DInit {
264
+ is2D?: boolean
265
+ m13?: number
266
+ m14?: number
267
+ m23?: number
268
+ m24?: number
269
+ m31?: number
270
+ m32?: number
271
+ m33?: number
272
+ m34?: number
273
+ m43?: number
274
+ m44?: number
275
+ }
276
+
277
+ // ----------- added types
278
+
6
279
  export interface DOMMatrix2DInit {
7
280
  a: number
8
281
  b: number
@@ -107,9 +380,7 @@ export interface DOMMatrix extends DOMMatrixReadOnly {
107
380
  toJSON(): { [K in OmitNeverOfMatrix]: DOMMatrix[K] }
108
381
  }
109
382
 
110
- type OmitMatrixMethod = {
111
- [K in keyof DOMMatrix]: DOMMatrix[K] extends (...args: any[]) => any ? never : K
112
- }
383
+ type OmitMatrixMethod = { [K in keyof DOMMatrix]: DOMMatrix[K] extends (...args: any[]) => any ? never : K }
113
384
 
114
385
  type OmitNeverOfMatrix = OmitMatrixMethod[keyof OmitMatrixMethod]
115
386
 
@@ -252,11 +523,7 @@ export interface StrokeOptions {
252
523
  join?: StrokeJoin
253
524
  }
254
525
 
255
- export interface SKRSContext2D
256
- extends Omit<
257
- CanvasRenderingContext2D,
258
- 'drawImage' | 'createPattern' | 'getTransform' | 'drawFocusIfNeeded' | 'scrollPathIntoView' | 'canvas'
259
- > {
526
+ export interface SKRSContext2D extends CanvasRenderingContext2D {
260
527
  canvas: Canvas
261
528
  /**
262
529
  * @param startAngle The angle at which to begin the gradient, in radians. Angle measurements start vertically above the centre and move around clockwise.
@@ -278,7 +545,7 @@ export interface SKRSContext2D
278
545
  dh: number,
279
546
  ): void
280
547
  createPattern(
281
- image: Image | ImageData,
548
+ image: Image | ImageData | Canvas | SvgCanvas,
282
549
  repeat: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' | null,
283
550
  ): CanvasPattern
284
551
  getContextAttributes(): { alpha: boolean; desynchronized: boolean }
@@ -392,21 +659,20 @@ export function createCanvas(width: number, height: number): Canvas
392
659
 
393
660
  export function createCanvas(width: number, height: number, svgExportFlag: SvgExportFlag): SvgCanvas
394
661
 
662
+ export declare class FontKey {
663
+ // make it a unique type
664
+ private readonly key: symbol
665
+ }
666
+
395
667
  interface IGlobalFonts {
396
- readonly families: {
397
- family: string
398
- styles: {
399
- weight: number
400
- width: string
401
- style: string
402
- }[]
403
- }[]
668
+ readonly families: { family: string; styles: { weight: number; width: string; style: string }[] }[]
404
669
  // return true if succeeded
405
- register(font: Buffer, nameAlias?: string): boolean
670
+ register(font: Buffer, nameAlias?: string): FontKey | null
406
671
  // absolute path
407
672
  registerFromPath(path: string, nameAlias?: string): boolean
408
673
  has(name: string): boolean
409
674
  loadFontsFromDir(path: string): number
675
+ remove(key: FontKey): void
410
676
  }
411
677
 
412
678
  export const GlobalFonts: IGlobalFonts
package/index.js CHANGED
@@ -9,7 +9,7 @@ const {
9
9
  Path: Path2D,
10
10
  ImageData,
11
11
  Image,
12
- CanvasPattern,
12
+ FontKey,
13
13
  GlobalFonts,
14
14
  PathOp,
15
15
  FillType,
@@ -28,9 +28,6 @@ const SvgExportFlag = {
28
28
  RelativePathEncoding: 0x04,
29
29
  }
30
30
 
31
- // eslint-disable-next-line sonarjs/no-unused-collection
32
- const Fonts = []
33
-
34
31
  if (!('families' in GlobalFonts)) {
35
32
  Object.defineProperty(GlobalFonts, 'families', {
36
33
  get: function () {
@@ -113,4 +110,5 @@ module.exports = {
113
110
  DOMMatrix,
114
111
  DOMRect,
115
112
  loadImage,
113
+ FontKey,
116
114
  }
package/js-binding.js CHANGED
@@ -1,269 +1,387 @@
1
- const { existsSync, readFileSync } = require('fs')
2
- const { join } = require('path')
3
-
4
- const { platform, arch } = process
1
+ // prettier-ignore
2
+ /* eslint-disable */
3
+ // @ts-nocheck
4
+ /* auto-generated by NAPI-RS */
5
5
 
6
+ const { readFileSync } = require('fs')
6
7
  let nativeBinding = null
7
- let localFileExisted = false
8
- let loadError = null
8
+ const loadErrors = []
9
9
 
10
- function isMusl() {
11
- // For Node 10
12
- if (!process.report || typeof process.report.getReport !== 'function') {
13
- try {
14
- return readFileSync('/usr/bin/ldd', 'utf8').includes('musl')
15
- } catch (e) {
10
+ const isMusl = () => {
11
+ let musl = false
12
+ if (process.platform === 'linux') {
13
+ musl = isMuslFromFilesystem()
14
+ if (musl === null) {
15
+ musl = isMuslFromReport()
16
+ }
17
+ if (musl === null) {
18
+ musl = isMuslFromChildProcess()
19
+ }
20
+ }
21
+ return musl
22
+ }
23
+
24
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
25
+
26
+ const isMuslFromFilesystem = () => {
27
+ try {
28
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
29
+ } catch {
30
+ return null
31
+ }
32
+ }
33
+
34
+ const isMuslFromReport = () => {
35
+ const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
36
+ if (!report) {
37
+ return null
38
+ }
39
+ if (report.header && report.header.glibcVersionRuntime) {
40
+ return false
41
+ }
42
+ if (Array.isArray(report.sharedObjects)) {
43
+ if (report.sharedObjects.some(isFileMusl)) {
16
44
  return true
17
45
  }
18
- } else {
19
- const { glibcVersionRuntime } = process.report.getReport().header
20
- return !glibcVersionRuntime
21
46
  }
47
+ return false
22
48
  }
23
49
 
24
- switch (platform) {
25
- case 'android':
26
- switch (arch) {
27
- case 'arm64':
28
- localFileExisted = existsSync(join(__dirname, 'skia.android-arm64.node'))
50
+ const isMuslFromChildProcess = () => {
51
+ try {
52
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
53
+ } catch (e) {
54
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
55
+ return false
56
+ }
57
+ }
58
+
59
+ function requireNative() {
60
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
61
+ try {
62
+ nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
63
+ } catch (err) {
64
+ loadErrors.push(err);
65
+ }
66
+ } else if (process.platform === 'android') {
67
+ if (process.arch === 'arm64') {
68
+ try {
69
+ return require('./skia.android-arm64.node')
70
+ } catch (e) {
71
+ loadErrors.push(e)
72
+ }
73
+ try {
74
+ return require('@napi-rs/canvas-android-arm64')
75
+ } catch (e) {
76
+ loadErrors.push(e)
77
+ }
78
+
79
+ } else if (process.arch === 'arm') {
80
+ try {
81
+ return require('./skia.android-arm-eabi.node')
82
+ } catch (e) {
83
+ loadErrors.push(e)
84
+ }
85
+ try {
86
+ return require('@napi-rs/canvas-android-arm-eabi')
87
+ } catch (e) {
88
+ loadErrors.push(e)
89
+ }
90
+
91
+ } else {
92
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
93
+ }
94
+ } else if (process.platform === 'win32') {
95
+ if (process.arch === 'x64') {
96
+ try {
97
+ return require('./skia.win32-x64-msvc.node')
98
+ } catch (e) {
99
+ loadErrors.push(e)
100
+ }
101
+ try {
102
+ return require('@napi-rs/canvas-win32-x64-msvc')
103
+ } catch (e) {
104
+ loadErrors.push(e)
105
+ }
106
+
107
+ } else if (process.arch === 'ia32') {
108
+ try {
109
+ return require('./skia.win32-ia32-msvc.node')
110
+ } catch (e) {
111
+ loadErrors.push(e)
112
+ }
113
+ try {
114
+ return require('@napi-rs/canvas-win32-ia32-msvc')
115
+ } catch (e) {
116
+ loadErrors.push(e)
117
+ }
118
+
119
+ } else if (process.arch === 'arm64') {
120
+ try {
121
+ return require('./skia.win32-arm64-msvc.node')
122
+ } catch (e) {
123
+ loadErrors.push(e)
124
+ }
125
+ try {
126
+ return require('@napi-rs/canvas-win32-arm64-msvc')
127
+ } catch (e) {
128
+ loadErrors.push(e)
129
+ }
130
+
131
+ } else {
132
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
133
+ }
134
+ } else if (process.platform === 'darwin') {
135
+ try {
136
+ return require('./skia.darwin-universal.node')
137
+ } catch (e) {
138
+ loadErrors.push(e)
139
+ }
140
+ try {
141
+ return require('@napi-rs/canvas-darwin-universal')
142
+ } catch (e) {
143
+ loadErrors.push(e)
144
+ }
145
+
146
+ if (process.arch === 'x64') {
147
+ try {
148
+ return require('./skia.darwin-x64.node')
149
+ } catch (e) {
150
+ loadErrors.push(e)
151
+ }
152
+ try {
153
+ return require('@napi-rs/canvas-darwin-x64')
154
+ } catch (e) {
155
+ loadErrors.push(e)
156
+ }
157
+
158
+ } else if (process.arch === 'arm64') {
159
+ try {
160
+ return require('./skia.darwin-arm64.node')
161
+ } catch (e) {
162
+ loadErrors.push(e)
163
+ }
164
+ try {
165
+ return require('@napi-rs/canvas-darwin-arm64')
166
+ } catch (e) {
167
+ loadErrors.push(e)
168
+ }
169
+
170
+ } else {
171
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
172
+ }
173
+ } else if (process.platform === 'freebsd') {
174
+ if (process.arch === 'x64') {
175
+ try {
176
+ return require('./skia.freebsd-x64.node')
177
+ } catch (e) {
178
+ loadErrors.push(e)
179
+ }
180
+ try {
181
+ return require('@napi-rs/canvas-freebsd-x64')
182
+ } catch (e) {
183
+ loadErrors.push(e)
184
+ }
185
+
186
+ } else if (process.arch === 'arm64') {
187
+ try {
188
+ return require('./skia.freebsd-arm64.node')
189
+ } catch (e) {
190
+ loadErrors.push(e)
191
+ }
192
+ try {
193
+ return require('@napi-rs/canvas-freebsd-arm64')
194
+ } catch (e) {
195
+ loadErrors.push(e)
196
+ }
197
+
198
+ } else {
199
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
200
+ }
201
+ } else if (process.platform === 'linux') {
202
+ if (process.arch === 'x64') {
203
+ if (isMusl()) {
29
204
  try {
30
- if (localFileExisted) {
31
- nativeBinding = require('./skia.android-arm64.node')
32
- } else {
33
- nativeBinding = require('@napi-rs/canvas-android-arm64')
34
- }
35
- } catch (e) {
36
- loadError = e
37
- }
38
- break
39
- case 'arm':
40
- localFileExisted = existsSync(join(__dirname, 'skia.android-arm-eabi.node'))
205
+ return require('./skia.linux-x64-musl.node')
206
+ } catch (e) {
207
+ loadErrors.push(e)
208
+ }
209
+ try {
210
+ return require('@napi-rs/canvas-linux-x64-musl')
211
+ } catch (e) {
212
+ loadErrors.push(e)
213
+ }
214
+
215
+ } else {
41
216
  try {
42
- if (localFileExisted) {
43
- nativeBinding = require('./skia.android-arm-eabi.node')
44
- } else {
45
- nativeBinding = require('@napi-rs/canvas-android-arm-eabi')
46
- }
47
- } catch (e) {
48
- loadError = e
49
- }
50
- break
51
- default:
52
- throw new Error(`Unsupported architecture on Android ${arch}`)
53
- }
54
- break
55
- case 'win32':
56
- switch (arch) {
57
- case 'x64':
58
- localFileExisted = existsSync(join(__dirname, 'skia.win32-x64-msvc.node'))
217
+ return require('./skia.linux-x64-gnu.node')
218
+ } catch (e) {
219
+ loadErrors.push(e)
220
+ }
221
+ try {
222
+ return require('@napi-rs/canvas-linux-x64-gnu')
223
+ } catch (e) {
224
+ loadErrors.push(e)
225
+ }
226
+
227
+ }
228
+ } else if (process.arch === 'arm64') {
229
+ if (isMusl()) {
59
230
  try {
60
- if (localFileExisted) {
61
- nativeBinding = require('./skia.win32-x64-msvc.node')
62
- } else {
63
- nativeBinding = require('@napi-rs/canvas-win32-x64-msvc')
64
- }
65
- } catch (e) {
66
- loadError = e
67
- }
68
- break
69
- case 'ia32':
70
- localFileExisted = existsSync(join(__dirname, 'skia.win32-ia32-msvc.node'))
231
+ return require('./skia.linux-arm64-musl.node')
232
+ } catch (e) {
233
+ loadErrors.push(e)
234
+ }
235
+ try {
236
+ return require('@napi-rs/canvas-linux-arm64-musl')
237
+ } catch (e) {
238
+ loadErrors.push(e)
239
+ }
240
+
241
+ } else {
71
242
  try {
72
- if (localFileExisted) {
73
- nativeBinding = require('./skia.win32-ia32-msvc.node')
74
- } else {
75
- nativeBinding = require('@napi-rs/canvas-win32-ia32-msvc')
76
- }
77
- } catch (e) {
78
- loadError = e
79
- }
80
- break
81
- case 'arm64':
82
- localFileExisted = existsSync(join(__dirname, 'skia.win32-arm64-msvc.node'))
243
+ return require('./skia.linux-arm64-gnu.node')
244
+ } catch (e) {
245
+ loadErrors.push(e)
246
+ }
247
+ try {
248
+ return require('@napi-rs/canvas-linux-arm64-gnu')
249
+ } catch (e) {
250
+ loadErrors.push(e)
251
+ }
252
+
253
+ }
254
+ } else if (process.arch === 'arm') {
255
+ if (isMusl()) {
83
256
  try {
84
- if (localFileExisted) {
85
- nativeBinding = require('./skia.win32-arm64-msvc.node')
86
- } else {
87
- nativeBinding = require('@napi-rs/canvas-win32-arm64-msvc')
88
- }
89
- } catch (e) {
90
- loadError = e
91
- }
92
- break
93
- default:
94
- throw new Error(`Unsupported architecture on Windows: ${arch}`)
95
- }
96
- break
97
- case 'darwin':
98
- switch (arch) {
99
- case 'x64':
100
- localFileExisted = existsSync(join(__dirname, 'skia.darwin-x64.node'))
257
+ return require('./skia.linux-arm-musleabihf.node')
258
+ } catch (e) {
259
+ loadErrors.push(e)
260
+ }
261
+ try {
262
+ return require('@napi-rs/canvas-linux-arm-musleabihf')
263
+ } catch (e) {
264
+ loadErrors.push(e)
265
+ }
266
+
267
+ } else {
101
268
  try {
102
- if (localFileExisted) {
103
- nativeBinding = require('./skia.darwin-x64.node')
104
- } else {
105
- nativeBinding = require('@napi-rs/canvas-darwin-x64')
106
- }
107
- } catch (e) {
108
- loadError = e
109
- }
110
- break
111
- case 'arm64':
112
- localFileExisted = existsSync(join(__dirname, 'skia.darwin-arm64.node'))
269
+ return require('./skia.linux-arm-gnueabihf.node')
270
+ } catch (e) {
271
+ loadErrors.push(e)
272
+ }
273
+ try {
274
+ return require('@napi-rs/canvas-linux-arm-gnueabihf')
275
+ } catch (e) {
276
+ loadErrors.push(e)
277
+ }
278
+
279
+ }
280
+ } else if (process.arch === 'riscv64') {
281
+ if (isMusl()) {
113
282
  try {
114
- if (localFileExisted) {
115
- nativeBinding = require('./skia.darwin-arm64.node')
116
- } else {
117
- nativeBinding = require('@napi-rs/canvas-darwin-arm64')
118
- }
119
- } catch (e) {
120
- loadError = e
121
- }
122
- break
123
- default:
124
- throw new Error(`Unsupported architecture on macOS: ${arch}`)
283
+ return require('./skia.linux-riscv64-musl.node')
284
+ } catch (e) {
285
+ loadErrors.push(e)
286
+ }
287
+ try {
288
+ return require('@napi-rs/canvas-linux-riscv64-musl')
289
+ } catch (e) {
290
+ loadErrors.push(e)
291
+ }
292
+
293
+ } else {
294
+ try {
295
+ return require('./skia.linux-riscv64-gnu.node')
296
+ } catch (e) {
297
+ loadErrors.push(e)
298
+ }
299
+ try {
300
+ return require('@napi-rs/canvas-linux-riscv64-gnu')
301
+ } catch (e) {
302
+ loadErrors.push(e)
303
+ }
304
+
305
+ }
306
+ } else if (process.arch === 'ppc64') {
307
+ try {
308
+ return require('./skia.linux-ppc64-gnu.node')
309
+ } catch (e) {
310
+ loadErrors.push(e)
311
+ }
312
+ try {
313
+ return require('@napi-rs/canvas-linux-ppc64-gnu')
314
+ } catch (e) {
315
+ loadErrors.push(e)
316
+ }
317
+
318
+ } else if (process.arch === 's390x') {
319
+ try {
320
+ return require('./skia.linux-s390x-gnu.node')
321
+ } catch (e) {
322
+ loadErrors.push(e)
323
+ }
324
+ try {
325
+ return require('@napi-rs/canvas-linux-s390x-gnu')
326
+ } catch (e) {
327
+ loadErrors.push(e)
328
+ }
329
+
330
+ } else {
331
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
125
332
  }
126
- break
127
- case 'freebsd':
128
- if (arch !== 'x64') {
129
- throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
333
+ } else {
334
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
335
+ }
336
+ }
337
+
338
+ nativeBinding = requireNative()
339
+
340
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
341
+ try {
342
+ nativeBinding = require('./skia.wasi.cjs')
343
+ } catch (err) {
344
+ if (process.env.NAPI_RS_FORCE_WASI) {
345
+ loadErrors.push(err)
130
346
  }
131
- localFileExisted = existsSync(join(__dirname, 'skia.freebsd-x64.node'))
347
+ }
348
+ if (!nativeBinding) {
132
349
  try {
133
- if (localFileExisted) {
134
- nativeBinding = require('./skia.freebsd-x64.node')
135
- } else {
136
- nativeBinding = require('@napi-rs/canvas-freebsd-x64')
350
+ nativeBinding = require('@napi-rs/canvas-wasm32-wasi')
351
+ } catch (err) {
352
+ if (process.env.NAPI_RS_FORCE_WASI) {
353
+ loadErrors.push(err)
137
354
  }
138
- } catch (e) {
139
- loadError = e
140
- }
141
- break
142
- case 'linux':
143
- switch (arch) {
144
- case 'x64':
145
- if (isMusl()) {
146
- localFileExisted = existsSync(join(__dirname, 'skia.linux-x64-musl.node'))
147
- try {
148
- if (localFileExisted) {
149
- nativeBinding = require('./skia.linux-x64-musl.node')
150
- } else {
151
- nativeBinding = require('@napi-rs/canvas-linux-x64-musl')
152
- }
153
- } catch (e) {
154
- loadError = e
155
- }
156
- } else {
157
- localFileExisted = existsSync(join(__dirname, 'skia.linux-x64-gnu.node'))
158
- try {
159
- if (localFileExisted) {
160
- nativeBinding = require('./skia.linux-x64-gnu.node')
161
- } else {
162
- nativeBinding = require('@napi-rs/canvas-linux-x64-gnu')
163
- }
164
- } catch (e) {
165
- loadError = e
166
- }
167
- }
168
- break
169
- case 'arm64':
170
- if (isMusl()) {
171
- localFileExisted = existsSync(join(__dirname, 'skia.linux-arm64-musl.node'))
172
- try {
173
- if (localFileExisted) {
174
- nativeBinding = require('./skia.linux-arm64-musl.node')
175
- } else {
176
- nativeBinding = require('@napi-rs/canvas-linux-arm64-musl')
177
- }
178
- } catch (e) {
179
- loadError = e
180
- }
181
- } else {
182
- localFileExisted = existsSync(join(__dirname, 'skia.linux-arm64-gnu.node'))
183
- try {
184
- if (localFileExisted) {
185
- nativeBinding = require('./skia.linux-arm64-gnu.node')
186
- } else {
187
- nativeBinding = require('@napi-rs/canvas-linux-arm64-gnu')
188
- }
189
- } catch (e) {
190
- loadError = e
191
- }
192
- }
193
- break
194
- case 'arm':
195
- localFileExisted = existsSync(join(__dirname, 'skia.linux-arm-gnueabihf.node'))
196
- try {
197
- if (localFileExisted) {
198
- nativeBinding = require('./skia.linux-arm-gnueabihf.node')
199
- } else {
200
- nativeBinding = require('@napi-rs/canvas-linux-arm-gnueabihf')
201
- }
202
- } catch (e) {
203
- loadError = e
204
- }
205
- break
206
- case 'riscv64':
207
- localFileExisted = existsSync(join(__dirname, 'skia.linux-riscv64-gnu.node'))
208
- try {
209
- if (localFileExisted) {
210
- nativeBinding = require('./skia.linux-riscv64-gnu.node')
211
- } else {
212
- nativeBinding = require('@napi-rs/canvas-linux-riscv64-gnu')
213
- }
214
- } catch (e) {
215
- loadError = e
216
- }
217
- break
218
- default:
219
- throw new Error(`Unsupported architecture on Linux: ${arch}`)
220
355
  }
221
- break
222
- default:
223
- throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
356
+ }
224
357
  }
225
358
 
226
359
  if (!nativeBinding) {
227
- if (loadError) {
228
- throw loadError
360
+ if (loadErrors.length > 0) {
361
+ // TODO Link to documentation with potential fixes
362
+ // - The package owner could build/publish bindings for this arch
363
+ // - The user may need to bundle the correct files
364
+ // - The user may need to re-install node_modules to get new packages
365
+ throw new Error('Failed to load native binding', { cause: loadErrors })
229
366
  }
230
367
  throw new Error(`Failed to load native binding`)
231
368
  }
232
369
 
233
- const {
234
- ChromaSubsampling,
235
- SvgExportFlag,
236
- CanvasRenderingContext2D,
237
- CanvasGradient,
238
- ImageData,
239
- Image,
240
- PathOp,
241
- FillType,
242
- StrokeCap,
243
- StrokeJoin,
244
- Path,
245
- CanvasPattern,
246
- convertSVGTextToPath,
247
- CanvasElement,
248
- SVGCanvas,
249
- clearAllCache,
250
- GlobalFonts,
251
- } = nativeBinding
252
-
253
- module.exports.ChromaSubsampling = ChromaSubsampling
254
- module.exports.SvgExportFlag = SvgExportFlag
255
- module.exports.CanvasRenderingContext2D = CanvasRenderingContext2D
256
- module.exports.CanvasGradient = CanvasGradient
257
- module.exports.ImageData = ImageData
258
- module.exports.Image = Image
259
- module.exports.PathOp = PathOp
260
- module.exports.FillType = FillType
261
- module.exports.StrokeCap = StrokeCap
262
- module.exports.StrokeJoin = StrokeJoin
263
- module.exports.Path = Path
264
- module.exports.CanvasPattern = CanvasPattern
265
- module.exports.convertSVGTextToPath = convertSVGTextToPath
266
- module.exports.CanvasElement = CanvasElement
267
- module.exports.SVGCanvas = SVGCanvas
268
- module.exports.clearAllCache = clearAllCache
269
- module.exports.GlobalFonts = GlobalFonts
370
+ module.exports.GlobalFonts = nativeBinding.GlobalFonts
371
+ module.exports.CanvasElement = nativeBinding.CanvasElement
372
+ module.exports.CanvasGradient = nativeBinding.CanvasGradient
373
+ module.exports.CanvasPattern = nativeBinding.CanvasPattern
374
+ module.exports.CanvasRenderingContext2D = nativeBinding.CanvasRenderingContext2D
375
+ module.exports.FontKey = nativeBinding.FontKey
376
+ module.exports.Image = nativeBinding.Image
377
+ module.exports.ImageData = nativeBinding.ImageData
378
+ module.exports.Path = nativeBinding.Path
379
+ module.exports.SVGCanvas = nativeBinding.SVGCanvas
380
+ module.exports.ChromaSubsampling = nativeBinding.ChromaSubsampling
381
+ module.exports.clearAllCache = nativeBinding.clearAllCache
382
+ module.exports.convertSVGTextToPath = nativeBinding.convertSVGTextToPath
383
+ module.exports.FillType = nativeBinding.FillType
384
+ module.exports.PathOp = nativeBinding.PathOp
385
+ module.exports.StrokeCap = nativeBinding.StrokeCap
386
+ module.exports.StrokeJoin = nativeBinding.StrokeJoin
387
+ module.exports.SvgExportFlag = nativeBinding.SvgExportFlag
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napi-rs/canvas",
3
- "version": "0.1.67",
3
+ "version": "0.1.69",
4
4
  "description": "Canvas for Node.js with skia backend",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -81,7 +81,7 @@
81
81
  "@types/semver": "^7",
82
82
  "ava": "^6.1.1",
83
83
  "canvas": "^3.0.0",
84
- "canvaskit-wasm": "^0.39.1",
84
+ "canvaskit-wasm": "^0.40.0",
85
85
  "colorette": "^2.0.20",
86
86
  "conventional-changelog-cli": "^5.0.0",
87
87
  "core-js": "^3.38.0",
@@ -90,7 +90,7 @@
90
90
  "lint-staged": "^15.2.1",
91
91
  "lodash": "^4.17.21",
92
92
  "npm-run-all2": "^7.0.0",
93
- "oxlint": "^0.15.0",
93
+ "oxlint": "^0.16.0",
94
94
  "pinst": "^3.0.0",
95
95
  "png.js": "^0.2.1",
96
96
  "prettier": "^3.2.5",
@@ -98,7 +98,7 @@
98
98
  "semver": "^7.5.4",
99
99
  "skia-canvas": "^2.0.0",
100
100
  "table": "^6.8.1",
101
- "tinybench": "^3.0.6",
101
+ "tinybench": "^4.0.0",
102
102
  "typescript": "^5.3.3"
103
103
  },
104
104
  "lint-staged": {
@@ -136,17 +136,17 @@
136
136
  "singleQuote": true,
137
137
  "arrowParens": "always"
138
138
  },
139
- "packageManager": "yarn@4.6.0",
139
+ "packageManager": "yarn@4.8.1",
140
140
  "optionalDependencies": {
141
- "@napi-rs/canvas-linux-x64-gnu": "0.1.67",
142
- "@napi-rs/canvas-darwin-x64": "0.1.67",
143
- "@napi-rs/canvas-win32-x64-msvc": "0.1.67",
144
- "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.67",
145
- "@napi-rs/canvas-linux-x64-musl": "0.1.67",
146
- "@napi-rs/canvas-linux-arm64-gnu": "0.1.67",
147
- "@napi-rs/canvas-linux-arm64-musl": "0.1.67",
148
- "@napi-rs/canvas-darwin-arm64": "0.1.67",
149
- "@napi-rs/canvas-android-arm64": "0.1.67",
150
- "@napi-rs/canvas-linux-riscv64-gnu": "0.1.67"
141
+ "@napi-rs/canvas-linux-x64-gnu": "0.1.69",
142
+ "@napi-rs/canvas-darwin-x64": "0.1.69",
143
+ "@napi-rs/canvas-win32-x64-msvc": "0.1.69",
144
+ "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.69",
145
+ "@napi-rs/canvas-linux-x64-musl": "0.1.69",
146
+ "@napi-rs/canvas-linux-arm64-gnu": "0.1.69",
147
+ "@napi-rs/canvas-linux-arm64-musl": "0.1.69",
148
+ "@napi-rs/canvas-darwin-arm64": "0.1.69",
149
+ "@napi-rs/canvas-android-arm64": "0.1.69",
150
+ "@napi-rs/canvas-linux-riscv64-gnu": "0.1.69"
151
151
  }
152
152
  }