@shqld/canvas 2.11.2-rc.3 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/Readme.md +86 -32
  2. package/binding.gyp +6 -7
  3. package/browser.js +0 -4
  4. package/{types/index.d.ts → index.d.ts} +34 -11
  5. package/index.js +2 -2
  6. package/lib/DOMMatrix.js +58 -0
  7. package/lib/bindings.js +33 -0
  8. package/lib/context2d.js +0 -3
  9. package/lib/image.js +16 -15
  10. package/lib/pattern.js +0 -2
  11. package/package.json +21 -15
  12. package/src/Backends.h +3 -4
  13. package/src/Canvas.cc +479 -418
  14. package/src/Canvas.h +68 -36
  15. package/src/CanvasError.h +14 -0
  16. package/src/CanvasGradient.cc +59 -69
  17. package/src/CanvasGradient.h +8 -10
  18. package/src/CanvasPattern.cc +65 -72
  19. package/src/CanvasPattern.h +8 -12
  20. package/src/CanvasRenderingContext2d.cc +1146 -979
  21. package/src/CanvasRenderingContext2d.h +126 -113
  22. package/src/CharData.h +233 -0
  23. package/src/FontParser.cc +605 -0
  24. package/src/FontParser.h +115 -0
  25. package/src/Image.cc +473 -188
  26. package/src/Image.h +39 -20
  27. package/src/ImageData.cc +74 -82
  28. package/src/ImageData.h +12 -13
  29. package/src/InstanceData.h +12 -0
  30. package/src/JPEGStream.h +11 -21
  31. package/src/bmp/BMPParser.cc +3 -1
  32. package/src/closure.cc +26 -0
  33. package/src/closure.h +19 -2
  34. package/src/color.cc +23 -6
  35. package/src/init.cc +38 -18
  36. package/src/register_font.cc +8 -64
  37. package/lib/parse-font.js +0 -101
  38. package/src/Backends.cc +0 -18
  39. package/src/backend/Backend.cc +0 -112
  40. package/src/backend/Backend.h +0 -69
  41. package/src/backend/ImageBackend.cc +0 -74
  42. package/src/backend/ImageBackend.h +0 -26
  43. package/src/backend/PdfBackend.cc +0 -53
  44. package/src/backend/PdfBackend.h +0 -24
  45. package/src/backend/SvgBackend.cc +0 -61
  46. package/src/backend/SvgBackend.h +0 -24
package/Readme.md CHANGED
@@ -1,29 +1,34 @@
1
- # node-canvas
1
+ # @shqld/canvas
2
2
 
3
- ![Test](https://github.com/Automattic/node-canvas/workflows/Test/badge.svg)
4
- [![NPM version](https://badge.fury.io/js/canvas.svg)](http://badge.fury.io/js/canvas)
5
-
6
- node-canvas is a [Cairo](http://cairographics.org/)-backed Canvas implementation for [Node.js](http://nodejs.org).
3
+ Fork of [node-canvas](https://github.com/Automattic/node-canvas) with prebuilt binaries distributed as platform-specific npm packages. No compiler or system dependencies required.
7
4
 
8
5
  ## Installation
9
6
 
10
7
  ```bash
11
- $ npm install canvas
8
+ npm install @shqld/canvas
12
9
  ```
13
10
 
14
- By default, binaries for macOS, Linux and Windows will be downloaded. If you want to build from source, use `npm install --build-from-source` and see the **Compiling** section below.
11
+ Prebuilt binaries are available for:
15
12
 
16
- The minimum version of Node.js required is **6.0.0**.
13
+ - Linux x64 (glibc)
14
+ - Linux arm64 (glibc)
15
+ - macOS arm64 (Apple Silicon)
16
+ - macOS x64 (Intel)
17
+ - Windows x64
17
18
 
18
- ### Compiling
19
+ No C++ compiler, Cairo, or Pango installation needed. Just `npm install` and go.
20
+
21
+ If you're on an unsupported platform, the install script falls back to building from source (see **Compiling** below).
19
22
 
20
- If you don't have a supported OS or processor architecture, or you use `--build-from-source`, the module will be compiled on your system. This requires several dependencies, including Cairo and Pango.
23
+ The minimum version of Node.js required is **18.12.0**.
24
+
25
+ ### Compiling
21
26
 
22
- For detailed installation information, see the [wiki](https://github.com/Automattic/node-canvas/wiki/_pages). One-line installation instructions for common OSes are below. Note that libgif/giflib, librsvg and libjpeg are optional and only required if you need GIF, SVG and JPEG support, respectively. Cairo v1.10.0 or later is required.
27
+ On unsupported platforms, the module will be compiled from source automatically. This requires several dependencies, including Cairo and Pango.
23
28
 
24
29
  OS | Command
25
30
  ----- | -----
26
- OS X | Using [Homebrew](https://brew.sh/):<br/>`brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman`
31
+ macOS | Using [Homebrew](https://brew.sh/):<br/>`brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman python-setuptools`
27
32
  Ubuntu | `sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev`
28
33
  Fedora | `sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel`
29
34
  Solaris | `pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto`
@@ -31,13 +36,10 @@ OpenBSD | `doas pkg_add cairo pango png jpeg giflib`
31
36
  Windows | See the [wiki](https://github.com/Automattic/node-canvas/wiki/Installation:-Windows)
32
37
  Others | See the [wiki](https://github.com/Automattic/node-canvas/wiki)
33
38
 
34
- **Mac OS X v10.11+:** If you have recently updated to Mac OS X v10.11+ and are experiencing trouble when compiling, run the following command: `xcode-select --install`. Read more about the problem [on Stack Overflow](http://stackoverflow.com/a/32929012/148072).
35
- If you have xcode 10.0 or higher installed, in order to build from source you need NPM 6.4.1 or higher.
36
-
37
39
  ## Quick Example
38
40
 
39
41
  ```javascript
40
- const { createCanvas, loadImage } = require('canvas')
42
+ const { createCanvas, loadImage } = require('@shqld/canvas')
41
43
  const canvas = createCanvas(200, 200)
42
44
  const ctx = canvas.getContext('2d')
43
45
 
@@ -62,11 +64,16 @@ loadImage('examples/images/lime-cat.jpg').then((image) => {
62
64
  })
63
65
  ```
64
66
 
65
- ## Upgrading from 1.x to 2.x
67
+ ## Migrating from `canvas`
68
+
69
+ Replace the package name in your imports:
66
70
 
67
- See the [changelog](https://github.com/Automattic/node-canvas/blob/master/CHANGELOG.md) for a guide to upgrading from 1.x to 2.x.
71
+ ```diff
72
+ - const { createCanvas, loadImage } = require('canvas')
73
+ + const { createCanvas, loadImage } = require('@shqld/canvas')
74
+ ```
68
75
 
69
- For version 1.x documentation, see [the v1.x branch](https://github.com/Automattic/node-canvas/tree/v1.x).
76
+ The API is identical. This fork only changes the distribution method (prebuilt binaries via npm optional dependencies instead of prebuild-install).
70
77
 
71
78
  ## Documentation
72
79
 
@@ -78,6 +85,8 @@ This project is an implementation of the Web Canvas API and implements that API
78
85
  * [createImageData()](#createimagedata)
79
86
  * [loadImage()](#loadimage)
80
87
  * [registerFont()](#registerfont)
88
+ * [deregisterAllFonts()](#deregisterAllFonts)
89
+
81
90
 
82
91
  ### Non-standard APIs
83
92
 
@@ -103,7 +112,7 @@ This project is an implementation of the Web Canvas API and implements that API
103
112
  Creates a Canvas instance. This method works in both Node.js and Web browsers, where there is no Canvas constructor. (See `browser.js` for the implementation that runs in browsers.)
104
113
 
105
114
  ```js
106
- const { createCanvas } = require('canvas')
115
+ const { createCanvas } = require('@shqld/canvas')
107
116
  const mycanvas = createCanvas(200, 200)
108
117
  const myPDFcanvas = createCanvas(600, 800, 'pdf') // see "PDF Support" section
109
118
  ```
@@ -120,7 +129,7 @@ const myPDFcanvas = createCanvas(600, 800, 'pdf') // see "PDF Support" section
120
129
  Creates an ImageData instance. This method works in both Node.js and Web browsers.
121
130
 
122
131
  ```js
123
- const { createImageData } = require('canvas')
132
+ const { createImageData } = require('@shqld/canvas')
124
133
  const width = 20, height = 20
125
134
  const arraySize = width * height * 4
126
135
  const mydata = createImageData(new Uint8ClampedArray(arraySize), width)
@@ -135,7 +144,7 @@ const mydata = createImageData(new Uint8ClampedArray(arraySize), width)
135
144
  Convenience method for loading images. This method works in both Node.js and Web browsers.
136
145
 
137
146
  ```js
138
- const { loadImage } = require('canvas')
147
+ const { loadImage } = require('@shqld/canvas')
139
148
  const myimg = loadImage('http://server.com/image.png')
140
149
 
141
150
  myimg.then(() => {
@@ -155,10 +164,10 @@ const myimg = await loadImage('http://server.com/image.png')
155
164
  > registerFont(path: string, { family: string, weight?: string, style?: string }) => void
156
165
  > ```
157
166
 
158
- To use a font file that is not installed as a system font, use `registerFont()` to register the font with Canvas. *This must be done before the Canvas is created.*
167
+ To use a font file that is not installed as a system font, use `registerFont()` to register the font with Canvas.
159
168
 
160
169
  ```js
161
- const { registerFont, createCanvas } = require('canvas')
170
+ const { registerFont, createCanvas } = require('@shqld/canvas')
162
171
  registerFont('comicsans.ttf', { family: 'Comic Sans' })
163
172
 
164
173
  const canvas = createCanvas(500, 500)
@@ -170,6 +179,35 @@ ctx.fillText('Everyone hates this font :(', 250, 10)
170
179
 
171
180
  The second argument is an object with properties that resemble the CSS properties that are specified in `@font-face` rules. You must specify at least `family`. `weight`, and `style` are optional and default to `'normal'`.
172
181
 
182
+ ### deregisterAllFonts()
183
+
184
+ > ```ts
185
+ > deregisterAllFonts() => void
186
+ > ```
187
+
188
+ Use `deregisterAllFonts` to unregister all fonts that have been previously registered. This method is useful when you want to remove all registered fonts, such as when using the canvas in tests
189
+
190
+ ```ts
191
+ const { registerFont, createCanvas, deregisterAllFonts } = require('@shqld/canvas')
192
+
193
+ describe('text rendering', () => {
194
+ afterEach(() => {
195
+ deregisterAllFonts();
196
+ })
197
+ it('should render text with Comic Sans', () => {
198
+ registerFont('comicsans.ttf', { family: 'Comic Sans' })
199
+
200
+ const canvas = createCanvas(500, 500)
201
+ const ctx = canvas.getContext('2d')
202
+
203
+ ctx.font = '12px "Comic Sans"'
204
+ ctx.fillText('Everyone loves this font :)', 250, 10)
205
+
206
+ // assertScreenshot()
207
+ })
208
+ })
209
+ ```
210
+
173
211
  ### Image#src
174
212
 
175
213
  > ```ts
@@ -179,7 +217,7 @@ The second argument is an object with properties that resemble the CSS propertie
179
217
  As in browsers, `img.src` can be set to a `data:` URI or a remote URL. In addition, node-canvas allows setting `src` to a local file path or `Buffer` instance.
180
218
 
181
219
  ```javascript
182
- const { Image } = require('canvas')
220
+ const { Image } = require('@shqld/canvas')
183
221
 
184
222
  // From a buffer:
185
223
  fs.readFile('images/squid.png', (err, squid) => {
@@ -218,7 +256,7 @@ Applies to JPEG images drawn to PDF canvases only.
218
256
  Setting `img.dataMode = Image.MODE_MIME` or `Image.MODE_MIME|Image.MODE_IMAGE` enables MIME data tracking of images. When MIME data is tracked, PDF canvases can embed JPEGs directly into the output, rather than re-encoding into PNG. This can drastically reduce filesize and speed up rendering.
219
257
 
220
258
  ```javascript
221
- const { Image, createCanvas } = require('canvas')
259
+ const { Image, createCanvas } = require('@shqld/canvas')
222
260
  const canvas = createCanvas(w, h, 'pdf')
223
261
  const img = new Image()
224
262
  img.dataMode = Image.MODE_IMAGE // Only image data tracked
@@ -478,6 +516,26 @@ ctx.addPage(400, 800)
478
516
  ctx.fillText('Hello World 2', 50, 80)
479
517
  ```
480
518
 
519
+ It is possible to add hyperlinks using `.beginTag()` and `.endTag()`:
520
+
521
+ ```js
522
+ ctx.beginTag('Link', "uri='https://google.com'")
523
+ ctx.font = '22px Helvetica'
524
+ ctx.fillText('Hello World', 50, 80)
525
+ ctx.endTag('Link')
526
+ ```
527
+
528
+ Or with a defined rectangle:
529
+
530
+ ```js
531
+ ctx.beginTag('Link', "uri='https://google.com' rect=[50 80 100 20]")
532
+ ctx.endTag('Link')
533
+ ```
534
+
535
+ Note that the syntax for attributes is unique to Cairo. See [cairo_tag_begin](https://www.cairographics.org/manual/cairo-Tags-and-Links.html#cairo-tag-begin) for the full documentation.
536
+
537
+ You can create areas on the canvas using the "cairo.dest" tag, and then link to them using the "Link" tag with the `dest=` attribute. You can also define PDF structure for accessibility by using tag names like "P", "H1", and "TABLE". The standard tags are defined in §14.8.4 of the [PDF 1.7](https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf) specification.
538
+
481
539
  See also:
482
540
 
483
541
  * [Image#dataMode](#imagedatamode) for embedding JPEGs in PDFs
@@ -543,15 +601,11 @@ Notes and caveats:
543
601
 
544
602
  ## Testing
545
603
 
546
- First make sure you've built the latest version. Get all the deps you need (see [compiling](#compiling) above), and run:
547
-
548
- ```
549
- npm install --build-from-source
550
- ```
604
+ For unit tests: `npm run test`.
551
605
 
552
606
  For visual tests: `npm run test-server` and point your browser to http://localhost:4000.
553
607
 
554
- For unit tests: `npm run test`.
608
+ For smoke testing prebuilt binaries: `node test/smoke.js`.
555
609
 
556
610
  ## Benchmarks
557
611
 
package/binding.gyp CHANGED
@@ -57,14 +57,10 @@
57
57
  },
58
58
  {
59
59
  'target_name': 'canvas',
60
- 'include_dirs': ["<!(node -e \"require('nan')\")"],
60
+ 'include_dirs': ["<!(node -p \"require('node-addon-api').include_dir\")"],
61
+ 'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS', 'NODE_ADDON_API_ENABLE_MAYBE' ],
61
62
  'sources': [
62
- 'src/backend/Backend.cc',
63
- 'src/backend/ImageBackend.cc',
64
- 'src/backend/PdfBackend.cc',
65
- 'src/backend/SvgBackend.cc',
66
63
  'src/bmp/BMPParser.cc',
67
- 'src/Backends.cc',
68
64
  'src/Canvas.cc',
69
65
  'src/CanvasGradient.cc',
70
66
  'src/CanvasPattern.cc',
@@ -74,7 +70,8 @@
74
70
  'src/Image.cc',
75
71
  'src/ImageData.cc',
76
72
  'src/init.cc',
77
- 'src/register_font.cc'
73
+ 'src/register_font.cc',
74
+ 'src/FontParser.cc'
78
75
  ],
79
76
  'conditions': [
80
77
  ['OS=="win"', {
@@ -142,7 +139,9 @@
142
139
  'cflags_cc!': ['-fno-exceptions']
143
140
  }],
144
141
  ['OS=="mac"', {
142
+ 'cflags+': ['-fvisibility=hidden'],
145
143
  'xcode_settings': {
144
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
146
145
  'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
147
146
  }
148
147
  }],
package/browser.js CHANGED
@@ -1,9 +1,5 @@
1
1
  /* globals document, ImageData */
2
2
 
3
- const parseFont = require('./lib/parse-font')
4
-
5
- exports.parseFont = parseFont
6
-
7
3
  exports.createCanvas = function (width, height) {
8
4
  return Object.assign(document.createElement('canvas'), { width: width, height: height })
9
5
  }
@@ -63,19 +63,19 @@ export class Canvas {
63
63
  readonly stride: number;
64
64
 
65
65
  /** Constant used in PNG encoding methods. */
66
- readonly PNG_NO_FILTERS: number
66
+ static readonly PNG_NO_FILTERS: number
67
67
  /** Constant used in PNG encoding methods. */
68
- readonly PNG_ALL_FILTERS: number
68
+ static readonly PNG_ALL_FILTERS: number
69
69
  /** Constant used in PNG encoding methods. */
70
- readonly PNG_FILTER_NONE: number
70
+ static readonly PNG_FILTER_NONE: number
71
71
  /** Constant used in PNG encoding methods. */
72
- readonly PNG_FILTER_SUB: number
72
+ static readonly PNG_FILTER_SUB: number
73
73
  /** Constant used in PNG encoding methods. */
74
- readonly PNG_FILTER_UP: number
74
+ static readonly PNG_FILTER_UP: number
75
75
  /** Constant used in PNG encoding methods. */
76
- readonly PNG_FILTER_AVG: number
76
+ static readonly PNG_FILTER_AVG: number
77
77
  /** Constant used in PNG encoding methods. */
78
- readonly PNG_FILTER_PAETH: number
78
+ static readonly PNG_FILTER_PAETH: number
79
79
 
80
80
  constructor(width: number, height: number, type?: 'image'|'pdf'|'svg')
81
81
 
@@ -128,10 +128,13 @@ export class Canvas {
128
128
  }
129
129
 
130
130
  export interface TextMetrics {
131
+ readonly alphabeticBaseline: number;
131
132
  readonly actualBoundingBoxAscent: number;
132
133
  readonly actualBoundingBoxDescent: number;
133
134
  readonly actualBoundingBoxLeft: number;
134
135
  readonly actualBoundingBoxRight: number;
136
+ readonly emHeightAscent: number;
137
+ readonly emHeightDescent: number;
135
138
  readonly fontBoundingBoxAscent: number;
136
139
  readonly fontBoundingBoxDescent: number;
137
140
  readonly width: number;
@@ -201,6 +204,7 @@ export class CanvasRenderingContext2D {
201
204
  getTransform(): DOMMatrix;
202
205
  resetTransform(): void;
203
206
  setTransform(transform?: DOMMatrix): void;
207
+ setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;
204
208
  isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;
205
209
  scale(x: number, y: number): void;
206
210
  clip(fillRule?: CanvasFillRule): void;
@@ -228,6 +232,8 @@ export class CanvasRenderingContext2D {
228
232
  createPattern(image: Canvas|Image, repetition: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' | '' | null): CanvasPattern
229
233
  createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
230
234
  createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
235
+ beginTag(tagName: string, attributes?: string): void;
236
+ endTag(tagName: string): void;
231
237
  /**
232
238
  * _Non-standard_. Defaults to 'good'. Affects pattern (gradient, image,
233
239
  * etc.) rendering quality.
@@ -284,6 +290,8 @@ export class CanvasRenderingContext2D {
284
290
  textBaseline: CanvasTextBaseline;
285
291
  textAlign: CanvasTextAlign;
286
292
  canvas: Canvas;
293
+ direction: 'ltr' | 'rtl';
294
+ lang: string;
287
295
  }
288
296
 
289
297
  export class CanvasGradient {
@@ -391,15 +399,28 @@ export class JPEGStream extends Readable {}
391
399
  /** This class must not be constructed directly; use `canvas.createPDFStream()`. */
392
400
  export class PDFStream extends Readable {}
393
401
 
402
+ // TODO: this is wrong. See matrixTransform in lib/DOMMatrix.js
403
+ type DOMMatrixInit = DOMMatrix | string | number[];
404
+
405
+ interface DOMPointInit {
406
+ w?: number;
407
+ x?: number;
408
+ y?: number;
409
+ z?: number;
410
+ }
411
+
394
412
  export class DOMPoint {
395
413
  w: number;
396
414
  x: number;
397
415
  y: number;
398
416
  z: number;
417
+ matrixTransform(matrix?: DOMMatrixInit): DOMPoint;
418
+ toJSON(): any;
419
+ static fromPoint(other?: DOMPointInit): DOMPoint;
399
420
  }
400
421
 
401
422
  export class DOMMatrix {
402
- constructor(init: string | number[]);
423
+ constructor(init?: string | number[]);
403
424
  toString(): string;
404
425
  multiply(other?: DOMMatrix): DOMMatrix;
405
426
  multiplySelf(other?: DOMMatrix): DOMMatrix;
@@ -410,6 +431,10 @@ export class DOMMatrix {
410
431
  scale3d(scale?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;
411
432
  scale3dSelf(scale?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;
412
433
  scaleSelf(scaleX?: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;
434
+ /**
435
+ * @deprecated
436
+ */
437
+ scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix;
413
438
  rotateFromVector(x?: number, y?: number): DOMMatrix;
414
439
  rotateFromVectorSelf(x?: number, y?: number): DOMMatrix;
415
440
  rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix;
@@ -426,6 +451,7 @@ export class DOMMatrix {
426
451
  invertSelf(): DOMMatrix;
427
452
  setMatrixValue(transformList: string): DOMMatrix;
428
453
  transformPoint(point?: DOMPoint): DOMPoint;
454
+ toJSON(): any;
429
455
  toFloat32Array(): Float32Array;
430
456
  toFloat64Array(): Float64Array;
431
457
  readonly is2D: boolean;
@@ -465,9 +491,6 @@ export class ImageData {
465
491
  readonly width: number;
466
492
  }
467
493
 
468
- // This is marked private, but is exported...
469
- // export function parseFont(description: string): object
470
-
471
494
  // Not documented: backends
472
495
 
473
496
  /** Library version. */
package/index.js CHANGED
@@ -2,7 +2,6 @@ const Canvas = require('./lib/canvas')
2
2
  const Image = require('./lib/image')
3
3
  const CanvasRenderingContext2D = require('./lib/context2d')
4
4
  const CanvasPattern = require('./lib/pattern')
5
- const parseFont = require('./lib/parse-font')
6
5
  const packageJson = require('./package.json')
7
6
  const bindings = require('./lib/bindings')
8
7
  const fs = require('fs')
@@ -11,6 +10,8 @@ const PDFStream = require('./lib/pdfstream')
11
10
  const JPEGStream = require('./lib/jpegstream')
12
11
  const { DOMPoint, DOMMatrix } = require('./lib/DOMMatrix')
13
12
 
13
+ bindings.setDOMMatrix(DOMMatrix)
14
+
14
15
  function createCanvas (width, height, type) {
15
16
  return new Canvas(width, height, type)
16
17
  }
@@ -70,7 +71,6 @@ exports.DOMPoint = DOMPoint
70
71
 
71
72
  exports.registerFont = registerFont
72
73
  exports.deregisterAllFonts = deregisterAllFonts
73
- exports.parseFont = parseFont
74
74
 
75
75
  exports.createCanvas = createCanvas
76
76
  exports.createImageData = createImageData
package/lib/DOMMatrix.js CHANGED
@@ -17,6 +17,26 @@ class DOMPoint {
17
17
  this.z = typeof z === 'number' ? z : 0
18
18
  this.w = typeof w === 'number' ? w : 1
19
19
  }
20
+
21
+ matrixTransform(init) {
22
+ // TODO: this next line is wrong. matrixTransform is supposed to only take
23
+ // an object with the DOMMatrix properties called DOMMatrixInit
24
+ const m = init instanceof DOMMatrix ? init : new DOMMatrix(init)
25
+ return m.transformPoint(this)
26
+ }
27
+
28
+ toJSON() {
29
+ return {
30
+ x: this.x,
31
+ y: this.y,
32
+ z: this.z,
33
+ w: this.w
34
+ }
35
+ }
36
+
37
+ static fromPoint(other) {
38
+ return new this(other.x, other.y, other.z, other.w)
39
+ }
20
40
  }
21
41
 
22
42
  // Constants to index into _values (col-major)
@@ -163,6 +183,13 @@ class DOMMatrix {
163
183
  return this.scaleSelf(scale, scale, scale, originX, originY, originZ)
164
184
  }
165
185
 
186
+ /**
187
+ * @deprecated
188
+ */
189
+ scaleNonUniform(scaleX, scaleY) {
190
+ return this.scale(scaleX, scaleY)
191
+ }
192
+
166
193
  scaleSelf (scaleX, scaleY, scaleZ, originX, originY, originZ) {
167
194
  // Not redundant with translate's checks because we need to negate the values later.
168
195
  if (typeof originX !== 'number') originX = 0
@@ -587,6 +614,37 @@ Object.defineProperties(DOMMatrix.prototype, {
587
614
  values[M31] === 0 && values[M32] === 0 && values[M33] === 1 && values[M34] === 0 &&
588
615
  values[M41] === 0 && values[M42] === 0 && values[M43] === 0 && values[M44] === 1)
589
616
  }
617
+ },
618
+
619
+ toJSON: {
620
+ value() {
621
+ return {
622
+ a: this.a,
623
+ b: this.b,
624
+ c: this.c,
625
+ d: this.d,
626
+ e: this.e,
627
+ f: this.f,
628
+ m11: this.m11,
629
+ m12: this.m12,
630
+ m13: this.m13,
631
+ m14: this.m14,
632
+ m21: this.m21,
633
+ m22: this.m22,
634
+ m23: this.m23,
635
+ m23: this.m23,
636
+ m31: this.m31,
637
+ m32: this.m32,
638
+ m33: this.m33,
639
+ m34: this.m34,
640
+ m41: this.m41,
641
+ m42: this.m42,
642
+ m43: this.m43,
643
+ m44: this.m44,
644
+ is2D: this.is2D,
645
+ isIdentity: this.isIdentity,
646
+ }
647
+ }
590
648
  }
591
649
  })
592
650
 
package/lib/bindings.js CHANGED
@@ -31,6 +31,7 @@ function isMuslLinux () {
31
31
  })
32
32
  return output.includes('musl')
33
33
  } catch (e) {
34
+ // ldd --version exits non-zero on musl and prints to stderr
34
35
  return e.stderr ? e.stderr.includes('musl') : false
35
36
  }
36
37
  }
@@ -41,6 +42,7 @@ function loadBinding () {
41
42
 
42
43
  if (packageName) {
43
44
  try {
45
+ // Windows: DLLs are next to canvas.node, add to search path
44
46
  if (process.platform === 'win32') {
45
47
  const pkgDir = path.dirname(require.resolve(`${packageName}/package.json`))
46
48
  process.env.PATH = pkgDir + path.delimiter + process.env.PATH
@@ -51,6 +53,7 @@ function loadBinding () {
51
53
  }
52
54
  }
53
55
 
56
+ // Fallback: locally built binary
54
57
  try {
55
58
  const localPath = path.resolve(__dirname, '..', 'build', 'Release')
56
59
  if (process.platform === 'win32') {
@@ -71,10 +74,40 @@ const bindings = loadBinding()
71
74
 
72
75
  module.exports = bindings
73
76
 
77
+ Object.defineProperty(bindings.Canvas.prototype, Symbol.toStringTag, {
78
+ value: 'HTMLCanvasElement',
79
+ configurable: true
80
+ })
81
+
82
+ Object.defineProperty(bindings.Image.prototype, Symbol.toStringTag, {
83
+ value: 'HTMLImageElement',
84
+ configurable: true
85
+ })
86
+
74
87
  bindings.ImageData.prototype.toString = function () {
75
88
  return '[object ImageData]'
76
89
  }
77
90
 
91
+ Object.defineProperty(bindings.ImageData.prototype, Symbol.toStringTag, {
92
+ value: 'ImageData',
93
+ configurable: true
94
+ })
95
+
78
96
  bindings.CanvasGradient.prototype.toString = function () {
79
97
  return '[object CanvasGradient]'
80
98
  }
99
+
100
+ Object.defineProperty(bindings.CanvasGradient.prototype, Symbol.toStringTag, {
101
+ value: 'CanvasGradient',
102
+ configurable: true
103
+ })
104
+
105
+ Object.defineProperty(bindings.CanvasPattern.prototype, Symbol.toStringTag, {
106
+ value: 'CanvasPattern',
107
+ configurable: true
108
+ })
109
+
110
+ Object.defineProperty(bindings.CanvasRenderingContext2d.prototype, Symbol.toStringTag, {
111
+ value: 'CanvasRenderingContext2d',
112
+ configurable: true
113
+ })
package/lib/context2d.js CHANGED
@@ -7,8 +7,5 @@
7
7
  */
8
8
 
9
9
  const bindings = require('./bindings')
10
- const parseFont = require('./parse-font')
11
- const { DOMMatrix } = require('./DOMMatrix')
12
10
 
13
- bindings.CanvasRenderingContext2dInit(DOMMatrix, parseFont)
14
11
  module.exports = bindings.CanvasRenderingContext2d
package/lib/image.js CHANGED
@@ -14,9 +14,6 @@ const bindings = require('./bindings')
14
14
  const Image = module.exports = bindings.Image
15
15
  const util = require('util')
16
16
 
17
- // Lazily loaded simple-get
18
- let get
19
-
20
17
  const { GetSource, SetSource } = bindings
21
18
 
22
19
  Object.defineProperty(Image.prototype, 'src', {
@@ -47,25 +44,29 @@ Object.defineProperty(Image.prototype, 'src', {
47
44
  }
48
45
  }
49
46
 
50
- if (!get) get = require('simple-get')
51
-
52
- get.concat({
53
- url: val,
47
+ fetch(val, {
48
+ method: 'GET',
54
49
  headers: { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36' }
55
- }, (err, res, data) => {
56
- if (err) return onerror(err)
57
-
58
- if (res.statusCode < 200 || res.statusCode >= 300) {
59
- return onerror(new Error(`Server responded with ${res.statusCode}`))
60
- }
61
-
62
- setSource(this, data)
63
50
  })
51
+ .then(res => {
52
+ if (!res.ok) {
53
+ throw new Error(`Server responded with ${res.status}`)
54
+ }
55
+ return res.arrayBuffer()
56
+ })
57
+ .then(data => {
58
+ setSource(this, Buffer.from(data))
59
+ })
60
+ .catch(onerror)
64
61
  } else { // local file path assumed
65
62
  setSource(this, val)
66
63
  }
67
64
  } else if (Buffer.isBuffer(val)) {
68
65
  setSource(this, val)
66
+ } else {
67
+ const err = new Error("Invalid image source")
68
+ if (typeof this.onerror === 'function') this.onerror(err)
69
+ else throw err
69
70
  }
70
71
  },
71
72
 
package/lib/pattern.js CHANGED
@@ -7,9 +7,7 @@
7
7
  */
8
8
 
9
9
  const bindings = require('./bindings')
10
- const { DOMMatrix } = require('./DOMMatrix')
11
10
 
12
- bindings.CanvasPatternInit(DOMMatrix)
13
11
  module.exports = bindings.CanvasPattern
14
12
 
15
13
  bindings.CanvasPattern.prototype.toString = function () {