@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.
- package/Readme.md +86 -32
- package/binding.gyp +6 -7
- package/browser.js +0 -4
- package/{types/index.d.ts → index.d.ts} +34 -11
- package/index.js +2 -2
- package/lib/DOMMatrix.js +58 -0
- package/lib/bindings.js +33 -0
- package/lib/context2d.js +0 -3
- package/lib/image.js +16 -15
- package/lib/pattern.js +0 -2
- package/package.json +21 -15
- package/src/Backends.h +3 -4
- package/src/Canvas.cc +479 -418
- package/src/Canvas.h +68 -36
- package/src/CanvasError.h +14 -0
- package/src/CanvasGradient.cc +59 -69
- package/src/CanvasGradient.h +8 -10
- package/src/CanvasPattern.cc +65 -72
- package/src/CanvasPattern.h +8 -12
- package/src/CanvasRenderingContext2d.cc +1146 -979
- package/src/CanvasRenderingContext2d.h +126 -113
- package/src/CharData.h +233 -0
- package/src/FontParser.cc +605 -0
- package/src/FontParser.h +115 -0
- package/src/Image.cc +473 -188
- package/src/Image.h +39 -20
- package/src/ImageData.cc +74 -82
- package/src/ImageData.h +12 -13
- package/src/InstanceData.h +12 -0
- package/src/JPEGStream.h +11 -21
- package/src/bmp/BMPParser.cc +3 -1
- package/src/closure.cc +26 -0
- package/src/closure.h +19 -2
- package/src/color.cc +23 -6
- package/src/init.cc +38 -18
- package/src/register_font.cc +8 -64
- package/lib/parse-font.js +0 -101
- package/src/Backends.cc +0 -18
- package/src/backend/Backend.cc +0 -112
- package/src/backend/Backend.h +0 -69
- package/src/backend/ImageBackend.cc +0 -74
- package/src/backend/ImageBackend.h +0 -26
- package/src/backend/PdfBackend.cc +0 -53
- package/src/backend/PdfBackend.h +0 -24
- package/src/backend/SvgBackend.cc +0 -61
- package/src/backend/SvgBackend.h +0 -24
package/src/Canvas.h
CHANGED
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
#pragma once
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
struct Closure;
|
|
6
|
+
struct PdfSvgClosure;
|
|
7
|
+
|
|
8
|
+
#include "closure.h"
|
|
6
9
|
#include <cairo.h>
|
|
7
10
|
#include "dll_visibility.h"
|
|
8
|
-
#include <
|
|
11
|
+
#include <napi.h>
|
|
9
12
|
#include <pango/pangocairo.h>
|
|
10
|
-
#include <v8.h>
|
|
11
13
|
#include <vector>
|
|
12
14
|
#include <cstddef>
|
|
13
15
|
|
|
16
|
+
/*
|
|
17
|
+
* Canvas types.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
typedef enum {
|
|
21
|
+
CANVAS_TYPE_IMAGE,
|
|
22
|
+
CANVAS_TYPE_PDF,
|
|
23
|
+
CANVAS_TYPE_SVG
|
|
24
|
+
} canvas_type_t;
|
|
25
|
+
|
|
26
|
+
|
|
14
27
|
/*
|
|
15
28
|
* FontFace describes a font file in terms of one PangoFontDescription that
|
|
16
29
|
* will resolve to it and one that the user describes it as (like @font-face)
|
|
@@ -35,7 +48,6 @@ enum text_align_t : int8_t {
|
|
|
35
48
|
TEXT_ALIGNMENT_LEFT = -1,
|
|
36
49
|
TEXT_ALIGNMENT_CENTER = 0,
|
|
37
50
|
TEXT_ALIGNMENT_RIGHT = 1,
|
|
38
|
-
// Currently same as LEFT and RIGHT without RTL support:
|
|
39
51
|
TEXT_ALIGNMENT_START = -2,
|
|
40
52
|
TEXT_ALIGNMENT_END = 2
|
|
41
53
|
};
|
|
@@ -49,48 +61,68 @@ enum canvas_draw_mode_t : uint8_t {
|
|
|
49
61
|
* Canvas.
|
|
50
62
|
*/
|
|
51
63
|
|
|
52
|
-
class Canvas: public
|
|
64
|
+
class Canvas : public Napi::ObjectWrap<Canvas> {
|
|
53
65
|
public:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
static
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
static
|
|
69
|
-
static
|
|
70
|
-
static
|
|
71
|
-
|
|
72
|
-
static void
|
|
66
|
+
Canvas(const Napi::CallbackInfo& info);
|
|
67
|
+
~Canvas();
|
|
68
|
+
static void Initialize(Napi::Env& env, Napi::Object& target);
|
|
69
|
+
|
|
70
|
+
Napi::Value ToBuffer(const Napi::CallbackInfo& info);
|
|
71
|
+
Napi::Value GetType(const Napi::CallbackInfo& info);
|
|
72
|
+
Napi::Value GetStride(const Napi::CallbackInfo& info);
|
|
73
|
+
Napi::Value GetWidth(const Napi::CallbackInfo& info);
|
|
74
|
+
Napi::Value GetHeight(const Napi::CallbackInfo& info);
|
|
75
|
+
void SetWidth(const Napi::CallbackInfo& info, const Napi::Value& value);
|
|
76
|
+
void SetHeight(const Napi::CallbackInfo& info, const Napi::Value& value);
|
|
77
|
+
void StreamPNGSync(const Napi::CallbackInfo& info);
|
|
78
|
+
void StreamPDFSync(const Napi::CallbackInfo& info);
|
|
79
|
+
void StreamJPEGSync(const Napi::CallbackInfo& info);
|
|
80
|
+
static void RegisterFont(const Napi::CallbackInfo& info);
|
|
81
|
+
static void DeregisterAllFonts(const Napi::CallbackInfo& info);
|
|
82
|
+
static Napi::Value ParseFont(const Napi::CallbackInfo& info);
|
|
83
|
+
Napi::Error CairoError(cairo_status_t status);
|
|
84
|
+
static void ToPngBufferAsync(Closure* closure);
|
|
85
|
+
static void ToJpegBufferAsync(Closure* closure);
|
|
73
86
|
static PangoWeight GetWeightFromCSSString(const char *weight);
|
|
74
87
|
static PangoStyle GetStyleFromCSSString(const char *style);
|
|
75
88
|
static PangoFontDescription *ResolveFontDescription(const PangoFontDescription *desc);
|
|
76
89
|
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
inline bool isPDF() { return type == CANVAS_TYPE_PDF; }
|
|
91
|
+
inline bool isSVG() { return type == CANVAS_TYPE_SVG; }
|
|
92
|
+
inline bool isImage() { return type == CANVAS_TYPE_IMAGE; }
|
|
93
|
+
inline void *closure() { return _closure; }
|
|
94
|
+
|
|
79
95
|
cairo_t* createCairoContext();
|
|
80
96
|
|
|
81
|
-
DLL_PUBLIC inline uint8_t *data(){ return cairo_image_surface_get_data(
|
|
82
|
-
DLL_PUBLIC inline int stride(){ return cairo_image_surface_get_stride(
|
|
83
|
-
DLL_PUBLIC inline std::size_t nBytes(){
|
|
84
|
-
return static_cast<std::size_t>(
|
|
97
|
+
DLL_PUBLIC inline uint8_t *data() { return cairo_image_surface_get_data(ensureSurface()); }
|
|
98
|
+
DLL_PUBLIC inline int stride() { return cairo_image_surface_get_stride(ensureSurface()); }
|
|
99
|
+
DLL_PUBLIC inline std::size_t nBytes() {
|
|
100
|
+
return static_cast<std::size_t>(height) * stride();
|
|
85
101
|
}
|
|
86
102
|
|
|
87
|
-
DLL_PUBLIC inline
|
|
88
|
-
DLL_PUBLIC inline
|
|
103
|
+
DLL_PUBLIC inline uint16_t getWidth() { return width; }
|
|
104
|
+
DLL_PUBLIC inline uint16_t getHeight() { return height; }
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
void
|
|
106
|
+
uint8_t approxBytesPerPixel();
|
|
107
|
+
void setFormat(cairo_format_t format);
|
|
108
|
+
cairo_format_t getFormat();
|
|
109
|
+
void resurface(Napi::Object This, uint16_t width, uint16_t height);
|
|
110
|
+
cairo_surface_t *ensureSurface();
|
|
111
|
+
void destroySurface();
|
|
112
|
+
|
|
113
|
+
Napi::Env env;
|
|
114
|
+
static int fontSerial;
|
|
92
115
|
|
|
93
116
|
private:
|
|
94
|
-
|
|
95
|
-
|
|
117
|
+
|
|
118
|
+
cairo_surface_t *_surface;
|
|
119
|
+
PdfSvgClosure *_closure;
|
|
120
|
+
|
|
121
|
+
Napi::FunctionReference ctor;
|
|
122
|
+
static std::vector<FontFace> font_face_list;
|
|
123
|
+
|
|
124
|
+
uint16_t width;
|
|
125
|
+
uint16_t height;
|
|
126
|
+
canvas_type_t type;
|
|
127
|
+
cairo_format_t format;
|
|
96
128
|
};
|
package/src/CanvasError.h
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include <string>
|
|
4
|
+
#include <napi.h>
|
|
4
5
|
|
|
5
6
|
class CanvasError {
|
|
6
7
|
public:
|
|
@@ -20,4 +21,17 @@ class CanvasError {
|
|
|
20
21
|
path.clear();
|
|
21
22
|
cerrno = 0;
|
|
22
23
|
}
|
|
24
|
+
bool empty() {
|
|
25
|
+
return cerrno == 0 && message.empty();
|
|
26
|
+
}
|
|
27
|
+
Napi::Error toError(Napi::Env env) {
|
|
28
|
+
if (cerrno) {
|
|
29
|
+
Napi::Error err = Napi::Error::New(env, strerror(cerrno));
|
|
30
|
+
if (!syscall.empty()) err.Value().Set("syscall", syscall);
|
|
31
|
+
if (!path.empty()) err.Value().Set("path", path);
|
|
32
|
+
return err;
|
|
33
|
+
} else {
|
|
34
|
+
return Napi::Error::New(env, message);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
23
37
|
};
|
package/src/CanvasGradient.cc
CHANGED
|
@@ -1,123 +1,113 @@
|
|
|
1
1
|
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|
2
2
|
|
|
3
3
|
#include "CanvasGradient.h"
|
|
4
|
+
#include "InstanceData.h"
|
|
4
5
|
|
|
5
6
|
#include "Canvas.h"
|
|
6
7
|
#include "color.h"
|
|
7
8
|
|
|
8
|
-
using namespace
|
|
9
|
-
|
|
10
|
-
Nan::Persistent<FunctionTemplate> Gradient::constructor;
|
|
9
|
+
using namespace Napi;
|
|
11
10
|
|
|
12
11
|
/*
|
|
13
12
|
* Initialize CanvasGradient.
|
|
14
13
|
*/
|
|
15
14
|
|
|
16
15
|
void
|
|
17
|
-
Gradient::Initialize(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Nan::SetPrototypeMethod(ctor, "addColorStop", AddColorStop);
|
|
28
|
-
Local<Context> ctx = Nan::GetCurrentContext();
|
|
29
|
-
Nan::Set(target,
|
|
30
|
-
Nan::New("CanvasGradient").ToLocalChecked(),
|
|
31
|
-
ctor->GetFunction(ctx).ToLocalChecked());
|
|
16
|
+
Gradient::Initialize(Napi::Env& env, Napi::Object& exports) {
|
|
17
|
+
Napi::HandleScope scope(env);
|
|
18
|
+
InstanceData* data = env.GetInstanceData<InstanceData>();
|
|
19
|
+
|
|
20
|
+
Napi::Function ctor = DefineClass(env, "CanvasGradient", {
|
|
21
|
+
InstanceMethod<&Gradient::AddColorStop>("addColorStop", napi_default_method)
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
exports.Set("CanvasGradient", ctor);
|
|
25
|
+
data->CanvasGradientCtor = Napi::Persistent(ctor);
|
|
32
26
|
}
|
|
33
27
|
|
|
34
28
|
/*
|
|
35
29
|
* Initialize a new CanvasGradient.
|
|
36
30
|
*/
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
if (!info.IsConstructCall()) {
|
|
40
|
-
return Nan::ThrowTypeError("Class constructors cannot be invoked without 'new'");
|
|
41
|
-
}
|
|
42
|
-
|
|
32
|
+
Gradient::Gradient(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Gradient>(info), env(info.Env()) {
|
|
43
33
|
// Linear
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
info.
|
|
34
|
+
if (
|
|
35
|
+
4 == info.Length() &&
|
|
36
|
+
info[0].IsNumber() &&
|
|
37
|
+
info[1].IsNumber() &&
|
|
38
|
+
info[2].IsNumber() &&
|
|
39
|
+
info[3].IsNumber()
|
|
40
|
+
) {
|
|
41
|
+
double x0 = info[0].As<Napi::Number>().DoubleValue();
|
|
42
|
+
double y0 = info[1].As<Napi::Number>().DoubleValue();
|
|
43
|
+
double x1 = info[2].As<Napi::Number>().DoubleValue();
|
|
44
|
+
double y1 = info[3].As<Napi::Number>().DoubleValue();
|
|
45
|
+
_pattern = cairo_pattern_create_linear(x0, y0, x1, y1);
|
|
52
46
|
return;
|
|
53
47
|
}
|
|
54
48
|
|
|
55
49
|
// Radial
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
info.
|
|
50
|
+
if (
|
|
51
|
+
6 == info.Length() &&
|
|
52
|
+
info[0].IsNumber() &&
|
|
53
|
+
info[1].IsNumber() &&
|
|
54
|
+
info[2].IsNumber() &&
|
|
55
|
+
info[3].IsNumber() &&
|
|
56
|
+
info[4].IsNumber() &&
|
|
57
|
+
info[5].IsNumber()
|
|
58
|
+
) {
|
|
59
|
+
double x0 = info[0].As<Napi::Number>().DoubleValue();
|
|
60
|
+
double y0 = info[1].As<Napi::Number>().DoubleValue();
|
|
61
|
+
double r0 = info[2].As<Napi::Number>().DoubleValue();
|
|
62
|
+
double x1 = info[3].As<Napi::Number>().DoubleValue();
|
|
63
|
+
double y1 = info[4].As<Napi::Number>().DoubleValue();
|
|
64
|
+
double r1 = info[5].As<Napi::Number>().DoubleValue();
|
|
65
|
+
_pattern = cairo_pattern_create_radial(x0, y0, r0, x1, y1, r1);
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
Napi::TypeError::New(env, "invalid arguments").ThrowAsJavaScriptException();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/*
|
|
73
73
|
* Add color stop.
|
|
74
74
|
*/
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return
|
|
76
|
+
void
|
|
77
|
+
Gradient::AddColorStop(const Napi::CallbackInfo& info) {
|
|
78
|
+
if (!info[0].IsNumber()) {
|
|
79
|
+
Napi::TypeError::New(env, "offset required").ThrowAsJavaScriptException();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!info[1].IsString()) {
|
|
84
|
+
Napi::TypeError::New(env, "color string required").ThrowAsJavaScriptException();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
81
87
|
|
|
82
|
-
Gradient *grad = Nan::ObjectWrap::Unwrap<Gradient>(info.This());
|
|
83
88
|
short ok;
|
|
84
|
-
|
|
85
|
-
uint32_t rgba = rgba_from_string(
|
|
89
|
+
std::string str = info[1].As<Napi::String>();
|
|
90
|
+
uint32_t rgba = rgba_from_string(str.c_str(), &ok);
|
|
86
91
|
|
|
87
92
|
if (ok) {
|
|
88
93
|
rgba_t color = rgba_create(rgba);
|
|
89
94
|
cairo_pattern_add_color_stop_rgba(
|
|
90
|
-
|
|
91
|
-
,
|
|
95
|
+
_pattern
|
|
96
|
+
, info[0].As<Napi::Number>().DoubleValue()
|
|
92
97
|
, color.r
|
|
93
98
|
, color.g
|
|
94
99
|
, color.b
|
|
95
100
|
, color.a);
|
|
96
101
|
} else {
|
|
97
|
-
|
|
102
|
+
Napi::TypeError::New(env, "parse color failed").ThrowAsJavaScriptException();
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
/*
|
|
102
|
-
* Initialize linear gradient.
|
|
103
|
-
*/
|
|
104
|
-
|
|
105
|
-
Gradient::Gradient(double x0, double y0, double x1, double y1) {
|
|
106
|
-
_pattern = cairo_pattern_create_linear(x0, y0, x1, y1);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/*
|
|
110
|
-
* Initialize radial gradient.
|
|
111
|
-
*/
|
|
112
|
-
|
|
113
|
-
Gradient::Gradient(double x0, double y0, double r0, double x1, double y1, double r1) {
|
|
114
|
-
_pattern = cairo_pattern_create_radial(x0, y0, r0, x1, y1, r1);
|
|
115
|
-
}
|
|
116
106
|
|
|
117
107
|
/*
|
|
118
108
|
* Destroy the pattern.
|
|
119
109
|
*/
|
|
120
110
|
|
|
121
111
|
Gradient::~Gradient() {
|
|
122
|
-
cairo_pattern_destroy(_pattern);
|
|
112
|
+
if (_pattern) cairo_pattern_destroy(_pattern);
|
|
123
113
|
}
|
package/src/CanvasGradient.h
CHANGED
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
#pragma once
|
|
4
4
|
|
|
5
|
-
#include <
|
|
6
|
-
#include <v8.h>
|
|
5
|
+
#include <napi.h>
|
|
7
6
|
#include <cairo.h>
|
|
8
7
|
|
|
9
|
-
class Gradient: public
|
|
8
|
+
class Gradient : public Napi::ObjectWrap<Gradient> {
|
|
10
9
|
public:
|
|
11
|
-
static
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
static NAN_METHOD(AddColorStop);
|
|
15
|
-
Gradient(double x0, double y0, double x1, double y1);
|
|
16
|
-
Gradient(double x0, double y0, double r0, double x1, double y1, double r1);
|
|
10
|
+
static void Initialize(Napi::Env& env, Napi::Object& target);
|
|
11
|
+
Gradient(const Napi::CallbackInfo& info);
|
|
12
|
+
void AddColorStop(const Napi::CallbackInfo& info);
|
|
17
13
|
inline cairo_pattern_t *pattern(){ return _pattern; }
|
|
14
|
+
~Gradient();
|
|
15
|
+
|
|
16
|
+
Napi::Env env;
|
|
18
17
|
|
|
19
18
|
private:
|
|
20
|
-
~Gradient();
|
|
21
19
|
cairo_pattern_t *_pattern;
|
|
22
20
|
};
|
package/src/CanvasPattern.cc
CHANGED
|
@@ -4,122 +4,115 @@
|
|
|
4
4
|
|
|
5
5
|
#include "Canvas.h"
|
|
6
6
|
#include "Image.h"
|
|
7
|
+
#include "InstanceData.h"
|
|
7
8
|
|
|
8
|
-
using namespace
|
|
9
|
+
using namespace Napi;
|
|
9
10
|
|
|
10
11
|
const cairo_user_data_key_t *pattern_repeat_key;
|
|
11
12
|
|
|
12
|
-
Nan::Persistent<FunctionTemplate> Pattern::constructor;
|
|
13
|
-
Nan::Persistent<Function> Pattern::_DOMMatrix;
|
|
14
|
-
|
|
15
13
|
/*
|
|
16
14
|
* Initialize CanvasPattern.
|
|
17
15
|
*/
|
|
18
16
|
|
|
19
17
|
void
|
|
20
|
-
Pattern::Initialize(
|
|
21
|
-
|
|
18
|
+
Pattern::Initialize(Napi::Env& env, Napi::Object& exports) {
|
|
19
|
+
Napi::HandleScope scope(env);
|
|
20
|
+
InstanceData* data = env.GetInstanceData<InstanceData>();
|
|
22
21
|
|
|
23
22
|
// Constructor
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
ctor->SetClassName(Nan::New("CanvasPattern").ToLocalChecked());
|
|
28
|
-
Nan::SetPrototypeMethod(ctor, "setTransform", SetTransform);
|
|
23
|
+
Napi::Function ctor = DefineClass(env, "CanvasPattern", {
|
|
24
|
+
InstanceMethod<&Pattern::setTransform>("setTransform", napi_default_method)
|
|
25
|
+
});
|
|
29
26
|
|
|
30
27
|
// Prototype
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Nan::Set(target, Nan::New("CanvasPatternInit").ToLocalChecked(), Nan::New<Function>(SaveExternalModules));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/*
|
|
37
|
-
* Save some external modules as private references.
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
NAN_METHOD(Pattern::SaveExternalModules) {
|
|
41
|
-
_DOMMatrix.Reset(Nan::To<Function>(info[0]).ToLocalChecked());
|
|
28
|
+
exports.Set("CanvasPattern", ctor);
|
|
29
|
+
data->CanvasPatternCtor = Napi::Persistent(ctor);
|
|
42
30
|
}
|
|
43
31
|
|
|
44
32
|
/*
|
|
45
33
|
* Initialize a new CanvasPattern.
|
|
46
34
|
*/
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
if (!info.
|
|
50
|
-
|
|
36
|
+
Pattern::Pattern(const Napi::CallbackInfo& info) : ObjectWrap<Pattern>(info), env(info.Env()) {
|
|
37
|
+
if (!info[0].IsObject()) {
|
|
38
|
+
Napi::TypeError::New(env, "Image or Canvas expected").ThrowAsJavaScriptException();
|
|
39
|
+
return;
|
|
51
40
|
}
|
|
52
41
|
|
|
42
|
+
Napi::Object obj = info[0].As<Napi::Object>();
|
|
43
|
+
InstanceData* data = env.GetInstanceData<InstanceData>();
|
|
53
44
|
cairo_surface_t *surface;
|
|
54
45
|
|
|
55
|
-
Local<Object> obj = Nan::To<Object>(info[0]).ToLocalChecked();
|
|
56
|
-
|
|
57
46
|
// Image
|
|
58
|
-
if (
|
|
59
|
-
Image *img =
|
|
47
|
+
if (obj.InstanceOf(data->ImageCtor.Value()).UnwrapOr(false)) {
|
|
48
|
+
Image *img = Image::Unwrap(obj);
|
|
60
49
|
if (!img->isComplete()) {
|
|
61
|
-
|
|
50
|
+
Napi::Error::New(env, "Image given has not completed loading").ThrowAsJavaScriptException();
|
|
51
|
+
return;
|
|
62
52
|
}
|
|
63
53
|
surface = img->surface();
|
|
64
54
|
|
|
65
55
|
// Canvas
|
|
66
|
-
} else if (
|
|
67
|
-
Canvas *canvas =
|
|
68
|
-
surface = canvas->
|
|
56
|
+
} else if (obj.InstanceOf(data->CanvasCtor.Value()).UnwrapOr(false)) {
|
|
57
|
+
Canvas *canvas = Canvas::Unwrap(obj);
|
|
58
|
+
surface = canvas->ensureSurface();
|
|
69
59
|
// Invalid
|
|
70
60
|
} else {
|
|
71
|
-
|
|
61
|
+
if (!env.IsExceptionPending()) {
|
|
62
|
+
Napi::TypeError::New(env, "Image or Canvas expected").ThrowAsJavaScriptException();
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
72
65
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
66
|
+
_pattern = cairo_pattern_create_for_surface(surface);
|
|
67
|
+
|
|
68
|
+
if (info[1].IsString()) {
|
|
69
|
+
if ("no-repeat" == info[1].As<Napi::String>().Utf8Value()) {
|
|
70
|
+
_repeat = NO_REPEAT;
|
|
71
|
+
} else if ("repeat-x" == info[1].As<Napi::String>().Utf8Value()) {
|
|
72
|
+
_repeat = REPEAT_X;
|
|
73
|
+
} else if ("repeat-y" == info[1].As<Napi::String>().Utf8Value()) {
|
|
74
|
+
_repeat = REPEAT_Y;
|
|
75
|
+
}
|
|
80
76
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
info.GetReturnValue().Set(info.This());
|
|
77
|
+
|
|
78
|
+
cairo_pattern_set_user_data(_pattern, pattern_repeat_key, &_repeat, NULL);
|
|
84
79
|
}
|
|
85
80
|
|
|
86
81
|
/*
|
|
87
82
|
* Set the pattern-space to user-space transform.
|
|
88
83
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
#if NODE_MAJOR_VERSION >= 8
|
|
95
|
-
if (!mat->InstanceOf(ctx, _DOMMatrix.Get(Isolate::GetCurrent())).ToChecked()) {
|
|
96
|
-
return Nan::ThrowTypeError("Expected DOMMatrix");
|
|
84
|
+
void
|
|
85
|
+
Pattern::setTransform(const Napi::CallbackInfo& info) {
|
|
86
|
+
if (!info[0].IsObject()) {
|
|
87
|
+
Napi::TypeError::New(env, "Expected DOMMatrix").ThrowAsJavaScriptException();
|
|
88
|
+
return;
|
|
97
89
|
}
|
|
98
|
-
|
|
90
|
+
|
|
91
|
+
Napi::Object mat = info[0].As<Napi::Object>();
|
|
92
|
+
|
|
93
|
+
InstanceData* data = env.GetInstanceData<InstanceData>();
|
|
94
|
+
if (!mat.InstanceOf(data->DOMMatrixCtor.Value()).UnwrapOr(false)) {
|
|
95
|
+
if (!env.IsExceptionPending()) {
|
|
96
|
+
Napi::TypeError::New(env, "Expected DOMMatrix").ThrowAsJavaScriptException();
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Napi::Value one = Napi::Number::New(env, 1);
|
|
102
|
+
Napi::Value zero = Napi::Number::New(env, 0);
|
|
99
103
|
|
|
100
104
|
cairo_matrix_t matrix;
|
|
101
105
|
cairo_matrix_init(&matrix,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
mat.Get("a").UnwrapOr(one).As<Napi::Number>().DoubleValue(),
|
|
107
|
+
mat.Get("b").UnwrapOr(zero).As<Napi::Number>().DoubleValue(),
|
|
108
|
+
mat.Get("c").UnwrapOr(zero).As<Napi::Number>().DoubleValue(),
|
|
109
|
+
mat.Get("d").UnwrapOr(one).As<Napi::Number>().DoubleValue(),
|
|
110
|
+
mat.Get("e").UnwrapOr(zero).As<Napi::Number>().DoubleValue(),
|
|
111
|
+
mat.Get("f").UnwrapOr(zero).As<Napi::Number>().DoubleValue()
|
|
108
112
|
);
|
|
109
113
|
|
|
110
114
|
cairo_matrix_invert(&matrix);
|
|
111
|
-
cairo_pattern_set_matrix(
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
/*
|
|
116
|
-
* Initialize pattern.
|
|
117
|
-
*/
|
|
118
|
-
|
|
119
|
-
Pattern::Pattern(cairo_surface_t *surface, repeat_type_t repeat) {
|
|
120
|
-
_pattern = cairo_pattern_create_for_surface(surface);
|
|
121
|
-
_repeat = repeat;
|
|
122
|
-
cairo_pattern_set_user_data(_pattern, pattern_repeat_key, &_repeat, NULL);
|
|
115
|
+
cairo_pattern_set_matrix(_pattern, &matrix);
|
|
123
116
|
}
|
|
124
117
|
|
|
125
118
|
repeat_type_t Pattern::get_repeat_type_for_cairo_pattern(cairo_pattern_t *pattern) {
|
|
@@ -132,5 +125,5 @@ repeat_type_t Pattern::get_repeat_type_for_cairo_pattern(cairo_pattern_t *patter
|
|
|
132
125
|
*/
|
|
133
126
|
|
|
134
127
|
Pattern::~Pattern() {
|
|
135
|
-
cairo_pattern_destroy(_pattern);
|
|
128
|
+
if (_pattern) cairo_pattern_destroy(_pattern);
|
|
136
129
|
}
|
package/src/CanvasPattern.h
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
#pragma once
|
|
4
4
|
|
|
5
5
|
#include <cairo.h>
|
|
6
|
-
#include <
|
|
7
|
-
#include <v8.h>
|
|
6
|
+
#include <napi.h>
|
|
8
7
|
|
|
9
8
|
/*
|
|
10
9
|
* Canvas types.
|
|
@@ -19,19 +18,16 @@ typedef enum {
|
|
|
19
18
|
|
|
20
19
|
extern const cairo_user_data_key_t *pattern_repeat_key;
|
|
21
20
|
|
|
22
|
-
class Pattern: public
|
|
21
|
+
class Pattern : public Napi::ObjectWrap<Pattern> {
|
|
23
22
|
public:
|
|
24
|
-
|
|
25
|
-
static
|
|
26
|
-
|
|
27
|
-
static NAN_METHOD(New);
|
|
28
|
-
static NAN_METHOD(SaveExternalModules);
|
|
29
|
-
static NAN_METHOD(SetTransform);
|
|
23
|
+
Pattern(const Napi::CallbackInfo& info);
|
|
24
|
+
static void Initialize(Napi::Env& env, Napi::Object& target);
|
|
25
|
+
void setTransform(const Napi::CallbackInfo& info);
|
|
30
26
|
static repeat_type_t get_repeat_type_for_cairo_pattern(cairo_pattern_t *pattern);
|
|
31
|
-
Pattern(cairo_surface_t *surface, repeat_type_t repeat);
|
|
32
27
|
inline cairo_pattern_t *pattern(){ return _pattern; }
|
|
33
|
-
private:
|
|
34
28
|
~Pattern();
|
|
29
|
+
Napi::Env env;
|
|
30
|
+
private:
|
|
35
31
|
cairo_pattern_t *_pattern;
|
|
36
|
-
repeat_type_t _repeat;
|
|
32
|
+
repeat_type_t _repeat = REPEAT;
|
|
37
33
|
};
|