Skip to content

Commit

Permalink
Merge branch 'Automattic:master' into feature/convertToBlob
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmywarting committed Jul 24, 2023
2 parents 2631428 + adf73ee commit 2719837
Show file tree
Hide file tree
Showing 26 changed files with 712 additions and 306 deletions.
17 changes: 9 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ on:
paths-ignore:
- ".github/workflows/prebuild.yaml"

jobs:
jobs:
Linux:
name: Test on Linux
runs-on: ubuntu-latest
strategy:
matrix:
node: [10, 12, 14, 16]
node: [10, 12, 14, 16, 18, 20]
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
sudo apt update
Expand All @@ -33,12 +33,12 @@ jobs:
runs-on: windows-2019
strategy:
matrix:
node: [10, 12, 14, 16]
node: [10, 12, 14, 16, 18, 20]
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
Invoke-WebRequest "https://ftp-osl.osuosl.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip" -OutFile "gtk.zip"
Expand All @@ -57,15 +57,16 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
node: [10, 12, 14, 16]
node: [10, 12, 14, 16, 18, 20]
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
brew update
brew install python3 || : # python doesn't need to be linked
brew install pkg-config cairo pango libpng jpeg giflib librsvg
- name: Install
run: npm install --build-from-source
Expand All @@ -79,7 +80,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 14
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install
run: npm install --ignore-scripts
- name: Lint
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/prebuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
Linux:
strategy:
matrix:
node: [8, 9, 10, 11, 12, 13, 14]
node: [8, 9, 10, 11, 12, 13, 14, 16, 18, 20]
canvas_tag: [] # e.g. "v2.6.1"
name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, Linux
runs-on: ubuntu-latest
Expand Down Expand Up @@ -97,7 +97,7 @@ jobs:
macOS:
strategy:
matrix:
node: [8, 9, 10, 11, 12, 13, 14]
node: [8, 9, 10, 11, 12, 13, 14, 16, 18, 20]
canvas_tag: [] # e.g. "v2.6.1"
name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, macOS
runs-on: macos-latest
Expand Down Expand Up @@ -163,7 +163,7 @@ jobs:
Win:
strategy:
matrix:
node: [8, 9, 10, 11, 12, 13, 14]
node: [8, 9, 10, 11, 12, 13, 14, 16, 18, 20]
canvas_tag: [] # e.g. "v2.6.1"
name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, Windows
runs-on: windows-latest
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,45 @@ project adheres to [Semantic Versioning](http://semver.org/).
(Unreleased)
==================
### Changed
* Defer the initialization of the `op` variable to the `default` switch case to avoid a compiler warning. (#2229)
* Use a `default` switch case with a null statement if some enum values aren't suppsed to be handled, this avoids a compiler warning. (#2229)
* Migrate from librsvg's deprecated `rsvg_handle_get_dimensions()` and `rsvg_handle_render_cairo()` functions to the new `rsvg_handle_get_intrinsic_size_in_pixels()` and `rsvg_handle_render_document()` respectively. (#2229)
* Avoid calling virtual methods in constructors/destructors to avoid bypassing virtual dispatch. (#2229)
* Remove unused private field `backend` in the `Backend` class. (#2229)
* Add Node.js v20 to CI. (#2237)
### Added
* Added string tags to support class detection
### Fixed
* Fix a case of use-after-free. (#2229)
* Fix usage of garbage value by filling the allocated memory entirely with zeros if it's not modified. (#2229)
* Fix a potential memory leak. (#2229)

2.11.2
==================
### Fixed
* Building on Windows in CI (and maybe other Windows configurations?) (#2216)

2.11.1
==================
### Fixed
* Add missing property `canvas` to the `CanvasRenderingContext2D` type
* Fixed glyph positions getting rounded, resulting text having a slight `letter-spacing` effect
* Fixed `ctx.font` not being restored correctly after `ctx.restore()` (#1946)

2.11.0
==================
### Fixed
* Replace triple-slash directive in types with own types to avoid polluting TS modules with globals ([#1656](https://github.com/Automattic/node-canvas/issues/1656))

2.10.2
==================
### Fixed
* Fix `Assertion failed: (object->InternalFieldCount() > 0), function Unwrap, file nan_object_wrap.h, line 32.` ([#2025](https://github.com/Automattic/node-canvas/issues/2025))
* `textBaseline` and `textAlign` were not saved/restored by `save()`/`restore()`. ([#1936](https://github.com/Automattic/node-canvas/issues/2029))
* Update nan to v2.17.0 to ensure Node.js v18+ support.
### Changed
* Improve performance and memory usage of `save()`/`restore()`.
* `save()`/`restore()` no longer have a maximum depth (previously 64 states).

2.10.1
==================
Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ This project is an implementation of the Web Canvas API and implements that API
* [CanvasRenderingContext2D#patternQuality](#canvasrenderingcontext2dpatternquality)
* [CanvasRenderingContext2D#quality](#canvasrenderingcontext2dquality)
* [CanvasRenderingContext2D#textDrawingMode](#canvasrenderingcontext2dtextdrawingmode)
* [CanvasRenderingContext2D#globalCompositeOperator = 'saturate'](#canvasrenderingcontext2dglobalcompositeoperator--saturate)
* [CanvasRenderingContext2D#globalCompositeOperation = 'saturate'](#canvasrenderingcontext2dglobalcompositeoperation--saturate)
* [CanvasRenderingContext2D#antialias](#canvasrenderingcontext2dantialias)

### createCanvas()
Expand Down
12 changes: 12 additions & 0 deletions benchmarks/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ function done (benchmark, times, start, isAsync) {

// node-canvas

bm('save/restore', function () {
for (let i = 0; i < 1000; i++) {
const max = i & 15
for (let j = 0; j < max; ++j) {
ctx.save()
}
for (let j = 0; j < max; ++j) {
ctx.restore()
}
}
})

bm('fillStyle= name', function () {
for (let i = 0; i < 10000; i++) {
ctx.fillStyle = '#fefefe'
Expand Down
30 changes: 30 additions & 0 deletions lib/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,40 @@ const bindings = require('../build/Release/canvas.node')

module.exports = bindings

Object.defineProperty(bindings.Canvas.prototype, Symbol.toStringTag, {
value: 'HTMLCanvasElement',
configurable: true
})

Object.defineProperty(bindings.Image.prototype, Symbol.toStringTag, {
value: 'HTMLImageElement',
configurable: true
})

bindings.ImageData.prototype.toString = function () {
return '[object ImageData]'
}

Object.defineProperty(bindings.ImageData.prototype, Symbol.toStringTag, {
value: 'ImageData',
configurable: true
})

bindings.CanvasGradient.prototype.toString = function () {
return '[object CanvasGradient]'
}

Object.defineProperty(bindings.CanvasGradient.prototype, Symbol.toStringTag, {
value: 'CanvasGradient',
configurable: true
})

Object.defineProperty(bindings.CanvasPattern.prototype, Symbol.toStringTag, {
value: 'CanvasPattern',
configurable: true
})

Object.defineProperty(bindings.CanvasRenderingContext2d.prototype, Symbol.toStringTag, {
value: 'CanvasRenderingContext2d',
configurable: true
})
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "canvas",
"description": "Canvas graphics API backed by Cairo",
"version": "2.10.1",
"version": "2.11.2",
"author": "TJ Holowaychuk <tj@learnboost.com>",
"main": "index.js",
"browser": "browser.js",
Expand Down Expand Up @@ -51,7 +51,7 @@
"types": "types/index.d.ts",
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.15.0",
"nan": "^2.17.0",
"simple-get": "^3.0.3"
},
"devDependencies": {
Expand Down
29 changes: 22 additions & 7 deletions src/Canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"with at least a family (string) and optionally weight (string/number) " \
"and style (string)."

#define CHECK_RECEIVER(prop) \
if (!Canvas::constructor.Get(info.GetIsolate())->HasInstance(info.This())) { \
Nan::ThrowTypeError("Method " #prop " called on incompatible receiver"); \
return; \
}

using namespace v8;
using namespace std;

Expand Down Expand Up @@ -64,10 +70,10 @@ Canvas::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
#ifdef HAVE_JPEG
Nan::SetPrototypeMethod(ctor, "streamJPEGSync", StreamJPEGSync);
#endif
SetProtoAccessor(proto, Nan::New("type").ToLocalChecked(), GetType, NULL, ctor);
SetProtoAccessor(proto, Nan::New("stride").ToLocalChecked(), GetStride, NULL, ctor);
SetProtoAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth, SetWidth, ctor);
SetProtoAccessor(proto, Nan::New("height").ToLocalChecked(), GetHeight, SetHeight, ctor);
Nan::SetAccessor(proto, Nan::New("type").ToLocalChecked(), GetType);
Nan::SetAccessor(proto, Nan::New("stride").ToLocalChecked(), GetStride);
Nan::SetAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth, SetWidth);
Nan::SetAccessor(proto, Nan::New("height").ToLocalChecked(), GetHeight, SetHeight);

Nan::SetTemplate(proto, "PNG_NO_FILTERS", Nan::New<Uint32>(PNG_NO_FILTERS));
Nan::SetTemplate(proto, "PNG_FILTER_NONE", Nan::New<Uint32>(PNG_FILTER_NONE));
Expand Down Expand Up @@ -127,8 +133,9 @@ NAN_METHOD(Canvas::New) {
}

if (!backend->isSurfaceValid()) {
const char *error = backend->getError();
delete backend;
return Nan::ThrowError(backend->getError());
return Nan::ThrowError(error);
}

Canvas* canvas = new Canvas(backend);
Expand All @@ -144,6 +151,7 @@ NAN_METHOD(Canvas::New) {
*/

NAN_GETTER(Canvas::GetType) {
CHECK_RECEIVER(Canvas.GetType);
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(info.This());
info.GetReturnValue().Set(Nan::New<String>(canvas->backend()->getName()).ToLocalChecked());
}
Expand All @@ -152,6 +160,7 @@ NAN_GETTER(Canvas::GetType) {
* Get stride.
*/
NAN_GETTER(Canvas::GetStride) {
CHECK_RECEIVER(Canvas.GetStride);
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(info.This());
info.GetReturnValue().Set(Nan::New<Number>(canvas->stride()));
}
Expand All @@ -161,6 +170,7 @@ NAN_GETTER(Canvas::GetStride) {
*/

NAN_GETTER(Canvas::GetWidth) {
CHECK_RECEIVER(Canvas.GetWidth);
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(info.This());
info.GetReturnValue().Set(Nan::New<Number>(canvas->getWidth()));
}
Expand All @@ -170,6 +180,7 @@ NAN_GETTER(Canvas::GetWidth) {
*/

NAN_SETTER(Canvas::SetWidth) {
CHECK_RECEIVER(Canvas.SetWidth);
if (value->IsNumber()) {
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(info.This());
canvas->backend()->setWidth(Nan::To<uint32_t>(value).FromMaybe(0));
Expand All @@ -182,6 +193,7 @@ NAN_SETTER(Canvas::SetWidth) {
*/

NAN_GETTER(Canvas::GetHeight) {
CHECK_RECEIVER(Canvas.GetHeight);
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(info.This());
info.GetReturnValue().Set(Nan::New<Number>(canvas->getHeight()));
}
Expand All @@ -191,6 +203,7 @@ NAN_GETTER(Canvas::GetHeight) {
*/

NAN_SETTER(Canvas::SetHeight) {
CHECK_RECEIVER(Canvas.SetHeight);
if (value->IsNumber()) {
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(info.This());
canvas->backend()->setHeight(Nan::To<uint32_t>(value).FromMaybe(0));
Expand Down Expand Up @@ -773,13 +786,13 @@ NAN_METHOD(Canvas::RegisterFont) {
NAN_METHOD(Canvas::DeregisterAllFonts) {
// Unload all fonts from pango to free up memory
bool success = true;

std::for_each(font_face_list.begin(), font_face_list.end(), [&](FontFace& f) {
if (!deregister_font( (unsigned char *)f.file_path )) success = false;
pango_font_description_free(f.user_desc);
pango_font_description_free(f.sys_desc);
});

font_face_list.clear();
if (!success) Nan::ThrowError("Could not deregister one or more fonts");
}
Expand Down Expand Up @@ -949,3 +962,5 @@ Local<Value>
Canvas::Error(cairo_status_t status) {
return Exception::Error(Nan::New<String>(cairo_status_to_string(status)).ToLocalChecked());
}

#undef CHECK_RECEIVER
32 changes: 23 additions & 9 deletions src/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@
#include <vector>
#include <cstddef>

/*
* Maxmimum states per context.
* TODO: remove/resize
*/

#ifndef CANVAS_MAX_STATES
#define CANVAS_MAX_STATES 64
#endif

/*
* FontFace describes a font file in terms of one PangoFontDescription that
* will resolve to it and one that the user describes it as (like @font-face)
Expand All @@ -31,6 +22,29 @@ class FontFace {
unsigned char file_path[1024];
};

enum text_baseline_t : uint8_t {
TEXT_BASELINE_ALPHABETIC = 0,
TEXT_BASELINE_TOP = 1,
TEXT_BASELINE_BOTTOM = 2,
TEXT_BASELINE_MIDDLE = 3,
TEXT_BASELINE_IDEOGRAPHIC = 4,
TEXT_BASELINE_HANGING = 5
};

enum text_align_t : int8_t {
TEXT_ALIGNMENT_LEFT = -1,
TEXT_ALIGNMENT_CENTER = 0,
TEXT_ALIGNMENT_RIGHT = 1,
// Currently same as LEFT and RIGHT without RTL support:
TEXT_ALIGNMENT_START = -2,
TEXT_ALIGNMENT_END = 2
};

enum canvas_draw_mode_t : uint8_t {
TEXT_DRAW_PATHS,
TEXT_DRAW_GLYPHS
};

/*
* Canvas.
*/
Expand Down

0 comments on commit 2719837

Please sign in to comment.