@napi-rs/canvas 0.1.81 → 0.1.83

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%2Fm142-hotpink)
4
+ ![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm143-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
@@ -5,20 +5,21 @@ export function clearAllCache(): void
5
5
 
6
6
  interface CanvasRenderingContext2D
7
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 {}
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
+ CanvasPDFAnnotations { }
22
23
 
23
24
  interface CanvasState {
24
25
  isContextLost(): boolean
@@ -120,6 +121,40 @@ interface CanvasTransform {
120
121
  transform(a: number, b: number, c: number, d: number, e: number, f: number): void
121
122
  translate(x: number, y: number): void
122
123
  }
124
+
125
+ interface CanvasPDFAnnotations {
126
+ /**
127
+ * Create a clickable URL link annotation in a PDF document.
128
+ * This is only effective when used with PDF documents.
129
+ * @param left - Left coordinate of the link rectangle
130
+ * @param top - Top coordinate of the link rectangle
131
+ * @param right - Right coordinate of the link rectangle
132
+ * @param bottom - Bottom coordinate of the link rectangle
133
+ * @param url - The URL to link to
134
+ */
135
+ annotateLinkUrl(left: number, top: number, right: number, bottom: number, url: string): void
136
+
137
+ /**
138
+ * Create a named destination at a specific point in a PDF document.
139
+ * This destination can be used as a target for internal links.
140
+ * @param x - X coordinate of the destination point
141
+ * @param y - Y coordinate of the destination point
142
+ * @param name - Name identifier for the destination
143
+ */
144
+ annotateNamedDestination(x: number, y: number, name: string): void
145
+
146
+ /**
147
+ * Create a link to a named destination within the PDF document.
148
+ * This is only effective when used with PDF documents.
149
+ * @param left - Left coordinate of the link rectangle
150
+ * @param top - Top coordinate of the link rectangle
151
+ * @param right - Right coordinate of the link rectangle
152
+ * @param bottom - Bottom coordinate of the link rectangle
153
+ * @param name - Name of the destination to link to
154
+ */
155
+ annotateLinkToDestination(left: number, top: number, right: number, bottom: number, name: string): void
156
+ }
157
+
123
158
  type PredefinedColorSpace = 'display-p3' | 'srgb'
124
159
 
125
160
  interface ImageDataSettings {
@@ -176,6 +211,7 @@ interface CanvasTextDrawingStyles {
176
211
  textBaseline: CanvasTextBaseline
177
212
  textRendering: CanvasTextRendering
178
213
  wordSpacing: string
214
+ fontVariationSettings: string
179
215
  }
180
216
 
181
217
  interface CanvasFilters {
@@ -386,7 +422,7 @@ type OmitNeverOfMatrix = OmitMatrixMethod[keyof OmitMatrixMethod]
386
422
 
387
423
  export const DOMMatrix: {
388
424
  prototype: DOMMatrix
389
- new (init?: string | number[]): DOMMatrix
425
+ new(init?: string | number[]): DOMMatrix
390
426
  fromFloat32Array(array32: Float32Array): DOMMatrix
391
427
  fromFloat64Array(array64: Float64Array): DOMMatrix
392
428
  fromMatrix(other?: DOMMatrixInit): DOMMatrix
@@ -413,7 +449,7 @@ export interface DOMRect extends DOMRectReadOnly {
413
449
 
414
450
  export const DOMRect: {
415
451
  prototype: DOMRect
416
- new (x?: number, y?: number, width?: number, height?: number): DOMRect
452
+ new(x?: number, y?: number, width?: number, height?: number): DOMRect
417
453
  fromRect(other?: DOMRectInit): DOMRect
418
454
  }
419
455
 
@@ -435,7 +471,7 @@ export interface DOMPoint extends DOMPointReadOnly {
435
471
 
436
472
  export const DOMPoint: {
437
473
  prototype: DOMPoint
438
- new (x?: number, y?: number, z?: number, w?: number): DOMPoint
474
+ new(x?: number, y?: number, z?: number, w?: number): DOMPoint
439
475
  fromPoint(other?: DOMPointInit): DOMPoint
440
476
  }
441
477
 
@@ -455,7 +491,7 @@ export class ImageData {
455
491
 
456
492
  constructor(sw: number, sh: number, attr?: { colorSpace?: ColorSpace })
457
493
  constructor(imageData: ImageData, attr?: { colorSpace?: ColorSpace })
458
- constructor(data: Uint8ClampedArray, sw: number, sh?: number)
494
+ constructor(data: Uint8ClampedArray | Uint16Array | Float16Array | Float32Array, sw: number, sh?: number)
459
495
  }
460
496
 
461
497
  export class Image {
@@ -673,6 +709,21 @@ export declare class FontKey {
673
709
  private readonly key: symbol
674
710
  }
675
711
 
712
+ export interface FontVariationAxis {
713
+ /** OpenType tag as a 32-bit integer (e.g., 0x77676874 for 'wght') */
714
+ tag: number
715
+ /** Current value for this axis */
716
+ value: number
717
+ /** Minimum value for this axis */
718
+ min: number
719
+ /** Maximum value for this axis */
720
+ max: number
721
+ /** Default value for this axis */
722
+ def: number
723
+ /** Whether this axis should be hidden from UI */
724
+ hidden: boolean
725
+ }
726
+
676
727
  interface IGlobalFonts {
677
728
  readonly families: { family: string; styles: { weight: number; width: string; style: string }[] }[]
678
729
  // return true if succeeded
@@ -682,6 +733,24 @@ interface IGlobalFonts {
682
733
  has(name: string): boolean
683
734
  loadFontsFromDir(path: string): number
684
735
  remove(key: FontKey): void
736
+ /**
737
+ * Get variation axes for a specific font instance
738
+ * @param familyName The font family name
739
+ * @param weight Font weight (100-900)
740
+ * @param width Font width/stretch value
741
+ * @param slant Font slant (0 = upright, 1 = italic, 2 = oblique)
742
+ * @returns Array of variation axes or empty array if not a variable font
743
+ */
744
+ getVariationAxes(familyName: string, weight: number, width: number, slant: number): FontVariationAxis[]
745
+ /**
746
+ * Check if a font has variable font capabilities
747
+ * @param familyName The font family name
748
+ * @param weight Font weight (100-900)
749
+ * @param width Font width/stretch value
750
+ * @param slant Font slant (0 = upright, 1 = italic, 2 = oblique)
751
+ * @returns true if the font is a variable font
752
+ */
753
+ hasVariations(familyName: string, weight: number, width: number, slant: number): boolean
685
754
  }
686
755
 
687
756
  export const GlobalFonts: IGlobalFonts
@@ -731,3 +800,40 @@ export function loadImage(
731
800
  source: string | URL | Buffer | ArrayBufferLike | Uint8Array | Image | import('stream').Readable,
732
801
  options?: LoadImageOptions,
733
802
  ): Promise<Image>
803
+
804
+ export interface PDFMetadata {
805
+ /// The document's title
806
+ title?: string
807
+ /// The name of the person who created the document
808
+ author?: string
809
+ /// The subject of the document
810
+ subject?: string
811
+ /// Keywords associated with the document
812
+ keywords?: string
813
+ /// The product that created the original document
814
+ creator?: string
815
+ /// The product that is converting this document to PDF (defaults to "Skia/PDF")
816
+ producer?: string
817
+ /// The DPI for rasterization (default: 72.0)
818
+ rasterDPI?: number
819
+ /// Encoding quality: 0-100 for lossy JPEG, 101 for lossless (default: 101)
820
+ encodingQuality?: number
821
+ /// Whether to conform to PDF/A-2b standard (default: false)
822
+ pdfa?: boolean
823
+ /// Compression level: -1 (default), 0 (none), 1 (low/fast), 6 (average), 9 (high/slow)
824
+ compressionLevel?: number
825
+ }
826
+
827
+ export interface Rect {
828
+ left: number
829
+ top: number
830
+ right: number
831
+ bottom: number
832
+ }
833
+
834
+ export declare class PDFDocument {
835
+ constructor(metadata?: PDFMetadata | undefined | null)
836
+ beginPage(width: number, height: number, rect?: Rect | undefined | null): CanvasRenderingContext2D
837
+ endPage(): void
838
+ close(): Buffer
839
+ }
package/index.js CHANGED
@@ -16,6 +16,7 @@ const {
16
16
  StrokeJoin,
17
17
  StrokeCap,
18
18
  convertSVGTextToPath,
19
+ PdfDocument,
19
20
  } = require('./js-binding')
20
21
 
21
22
  const { DOMPoint, DOMMatrix, DOMRect } = require('./geometry')
@@ -176,4 +177,5 @@ module.exports = {
176
177
  // Export these for better webpack compatibility
177
178
  CanvasElement,
178
179
  SVGCanvas,
180
+ PDFDocument: PdfDocument,
179
181
  }
package/js-binding.js CHANGED
@@ -32,7 +32,11 @@ const isMuslFromFilesystem = () => {
32
32
  }
33
33
 
34
34
  const isMuslFromReport = () => {
35
- const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
35
+ let report = null
36
+ if (typeof process.report?.getReport === 'function') {
37
+ process.report.excludeNetwork = true
38
+ report = process.report.getReport()
39
+ }
36
40
  if (!report) {
37
41
  return null
38
42
  }
@@ -59,7 +63,7 @@ const isMuslFromChildProcess = () => {
59
63
  function requireNative() {
60
64
  if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
61
65
  try {
62
- nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
66
+ return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
63
67
  } catch (err) {
64
68
  loadErrors.push(err)
65
69
  }
@@ -91,15 +95,31 @@ function requireNative() {
91
95
  }
92
96
  } else if (process.platform === 'win32') {
93
97
  if (process.arch === 'x64') {
94
- try {
95
- return require('./skia.win32-x64-msvc.node')
96
- } catch (e) {
97
- loadErrors.push(e)
98
- }
99
- try {
100
- return require('@napi-rs/canvas-win32-x64-msvc')
101
- } catch (e) {
102
- loadErrors.push(e)
98
+ if (
99
+ process.config?.variables?.shlib_suffix === 'dll.a' ||
100
+ process.config?.variables?.node_target_type === 'shared_library'
101
+ ) {
102
+ try {
103
+ return require('./skia.win32-x64-gnu.node')
104
+ } catch (e) {
105
+ loadErrors.push(e)
106
+ }
107
+ try {
108
+ return require('@napi-rs/canvas-win32-x64-gnu')
109
+ } catch (e) {
110
+ loadErrors.push(e)
111
+ }
112
+ } else {
113
+ try {
114
+ return require('./skia.win32-x64-msvc.node')
115
+ } catch (e) {
116
+ loadErrors.push(e)
117
+ }
118
+ try {
119
+ return require('@napi-rs/canvas-win32-x64-msvc')
120
+ } catch (e) {
121
+ loadErrors.push(e)
122
+ }
103
123
  }
104
124
  } else if (process.arch === 'ia32') {
105
125
  try {
@@ -137,7 +157,6 @@ function requireNative() {
137
157
  } catch (e) {
138
158
  loadErrors.push(e)
139
159
  }
140
-
141
160
  if (process.arch === 'x64') {
142
161
  try {
143
162
  return require('./skia.darwin-x64.node')
@@ -262,6 +281,30 @@ function requireNative() {
262
281
  loadErrors.push(e)
263
282
  }
264
283
  }
284
+ } else if (process.arch === 'loong64') {
285
+ if (isMusl()) {
286
+ try {
287
+ return require('./skia.linux-loong64-musl.node')
288
+ } catch (e) {
289
+ loadErrors.push(e)
290
+ }
291
+ try {
292
+ return require('@napi-rs/canvas-linux-loong64-musl')
293
+ } catch (e) {
294
+ loadErrors.push(e)
295
+ }
296
+ } else {
297
+ try {
298
+ return require('./skia.linux-loong64-gnu.node')
299
+ } catch (e) {
300
+ loadErrors.push(e)
301
+ }
302
+ try {
303
+ return require('@napi-rs/canvas-linux-loong64-gnu')
304
+ } catch (e) {
305
+ loadErrors.push(e)
306
+ }
307
+ }
265
308
  } else if (process.arch === 'riscv64') {
266
309
  if (isMusl()) {
267
310
  try {
@@ -311,6 +354,44 @@ function requireNative() {
311
354
  } else {
312
355
  loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
313
356
  }
357
+ } else if (process.platform === 'openharmony') {
358
+ if (process.arch === 'arm64') {
359
+ try {
360
+ return require('./skia.openharmony-arm64.node')
361
+ } catch (e) {
362
+ loadErrors.push(e)
363
+ }
364
+ try {
365
+ return require('@napi-rs/canvas-openharmony-arm64')
366
+ } catch (e) {
367
+ loadErrors.push(e)
368
+ }
369
+ } else if (process.arch === 'x64') {
370
+ try {
371
+ return require('./skia.openharmony-x64.node')
372
+ } catch (e) {
373
+ loadErrors.push(e)
374
+ }
375
+ try {
376
+ return require('@napi-rs/canvas-openharmony-x64')
377
+ } catch (e) {
378
+ loadErrors.push(e)
379
+ }
380
+ } else if (process.arch === 'arm') {
381
+ try {
382
+ return require('./skia.openharmony-arm.node')
383
+ } catch (e) {
384
+ loadErrors.push(e)
385
+ }
386
+ try {
387
+ const binding = require('@napi-rs/canvas-openharmony-arm')
388
+ return binding
389
+ } catch (e) {
390
+ loadErrors.push(e)
391
+ }
392
+ } else {
393
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
394
+ }
314
395
  } else {
315
396
  loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
316
397
  }
@@ -319,18 +400,23 @@ function requireNative() {
319
400
  nativeBinding = requireNative()
320
401
 
321
402
  if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
403
+ let wasiBinding = null
404
+ let wasiBindingError = null
322
405
  try {
323
- nativeBinding = require('./skia.wasi.cjs')
406
+ wasiBinding = require('./skia.wasi.cjs')
407
+ nativeBinding = wasiBinding
324
408
  } catch (err) {
325
409
  if (process.env.NAPI_RS_FORCE_WASI) {
326
- loadErrors.push(err)
410
+ wasiBindingError = err
327
411
  }
328
412
  }
329
413
  if (!nativeBinding) {
330
414
  try {
331
- nativeBinding = require('@napi-rs/canvas-wasm32-wasi')
415
+ wasiBinding = require('@napi-rs/canvas-wasm32-wasi')
416
+ nativeBinding = wasiBinding
332
417
  } catch (err) {
333
418
  if (process.env.NAPI_RS_FORCE_WASI) {
419
+ wasiBindingError.cause = err
334
420
  loadErrors.push(err)
335
421
  }
336
422
  }
@@ -339,15 +425,22 @@ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
339
425
 
340
426
  if (!nativeBinding) {
341
427
  if (loadErrors.length > 0) {
342
- // TODO Link to documentation with potential fixes
343
- // - The package owner could build/publish bindings for this arch
344
- // - The user may need to bundle the correct files
345
- // - The user may need to re-install node_modules to get new packages
346
- throw new Error('Failed to load native binding', { cause: loadErrors })
428
+ throw new Error(
429
+ `Cannot find native binding. ` +
430
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
431
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
432
+ {
433
+ cause: loadErrors.reduce((err, cur) => {
434
+ cur.cause = err
435
+ return cur
436
+ }),
437
+ },
438
+ )
347
439
  }
348
440
  throw new Error(`Failed to load native binding`)
349
441
  }
350
442
 
443
+ module.exports = nativeBinding
351
444
  module.exports.GlobalFonts = nativeBinding.GlobalFonts
352
445
  module.exports.CanvasElement = nativeBinding.CanvasElement
353
446
  module.exports.CanvasGradient = nativeBinding.CanvasGradient
@@ -357,6 +450,7 @@ module.exports.FontKey = nativeBinding.FontKey
357
450
  module.exports.Image = nativeBinding.Image
358
451
  module.exports.ImageData = nativeBinding.ImageData
359
452
  module.exports.Path = nativeBinding.Path
453
+ module.exports.PdfDocument = nativeBinding.PdfDocument
360
454
  module.exports.SVGCanvas = nativeBinding.SVGCanvas
361
455
  module.exports.ChromaSubsampling = nativeBinding.ChromaSubsampling
362
456
  module.exports.clearAllCache = nativeBinding.clearAllCache
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napi-rs/canvas",
3
- "version": "0.1.81",
3
+ "version": "0.1.83",
4
4
  "description": "Canvas for Node.js with skia backend",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -77,10 +77,10 @@
77
77
  "@jimp/png": "^0.22.12",
78
78
  "@napi-rs/cli": "^3.1.1",
79
79
  "@octokit/rest": "^22.0.0",
80
- "@oxc-node/core": "^0.0.32",
80
+ "@oxc-node/core": "^0.0.34",
81
81
  "@taplo/cli": "^0.7.0",
82
82
  "@types/lodash": "^4.17.17",
83
- "@types/node": "^22.15.30",
83
+ "@types/node": "^24.0.0",
84
84
  "@types/semver": "^7",
85
85
  "ava": "^6.3.0",
86
86
  "canvas": "^3.1.0",
@@ -89,7 +89,7 @@
89
89
  "conventional-changelog-cli": "^5.0.0",
90
90
  "core-js": "^3.42.0",
91
91
  "echarts": "^6.0.0",
92
- "electron": "^38.0.0",
92
+ "electron": "^39.0.0",
93
93
  "husky": "^9.1.7",
94
94
  "lint-staged": "^16.1.0",
95
95
  "lodash": "^4.17.21",
@@ -140,17 +140,17 @@
140
140
  "singleQuote": true,
141
141
  "arrowParens": "always"
142
142
  },
143
- "packageManager": "yarn@4.10.3",
143
+ "packageManager": "yarn@4.12.0",
144
144
  "optionalDependencies": {
145
- "@napi-rs/canvas-linux-x64-gnu": "0.1.81",
146
- "@napi-rs/canvas-darwin-x64": "0.1.81",
147
- "@napi-rs/canvas-win32-x64-msvc": "0.1.81",
148
- "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.81",
149
- "@napi-rs/canvas-linux-x64-musl": "0.1.81",
150
- "@napi-rs/canvas-linux-arm64-gnu": "0.1.81",
151
- "@napi-rs/canvas-linux-arm64-musl": "0.1.81",
152
- "@napi-rs/canvas-darwin-arm64": "0.1.81",
153
- "@napi-rs/canvas-android-arm64": "0.1.81",
154
- "@napi-rs/canvas-linux-riscv64-gnu": "0.1.81"
145
+ "@napi-rs/canvas-linux-x64-gnu": "0.1.83",
146
+ "@napi-rs/canvas-darwin-x64": "0.1.83",
147
+ "@napi-rs/canvas-win32-x64-msvc": "0.1.83",
148
+ "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.83",
149
+ "@napi-rs/canvas-linux-x64-musl": "0.1.83",
150
+ "@napi-rs/canvas-linux-arm64-gnu": "0.1.83",
151
+ "@napi-rs/canvas-linux-arm64-musl": "0.1.83",
152
+ "@napi-rs/canvas-darwin-arm64": "0.1.83",
153
+ "@napi-rs/canvas-android-arm64": "0.1.83",
154
+ "@napi-rs/canvas-linux-riscv64-gnu": "0.1.83"
155
155
  }
156
156
  }