blob: bec3942f38b0d24be1572ccc40ffaa1e2ef362b5 [file] [log] [blame]
Kevin Lubick11194ab2018-08-17 13:52:56 -04001// Adds JS functions to allow for chaining w/o leaking by re-using 'this' path.
2(function(PathKit){
3 // PathKit.onRuntimeInitialized is called after the WASM library has loaded.
4 // when onRuntimeInitialized is called, PathKit.SkPath is defined with many
5 // functions on it (see pathkit_wasm_bindings.cpp@EMSCRIPTEN_BINDINGS)
6 PathKit.onRuntimeInitialized = function() {
7 // All calls to 'this' need to go in externs.js so closure doesn't minify them away.
8
9 PathKit.SkPath.prototype.addPath = function() {
10 // Takes 1, 2, 7 or 10 args, where the first arg is always the path.
11 // The options for the remaining args are:
12 // - an SVGMatrix
13 // - the 6 parameters of an SVG Matrix
14 // - the 9 parameters of a full Matrix
Kevin Lubick1a05fce2018-11-20 12:51:16 -050015 var path = arguments[0];
Kevin Lubick11194ab2018-08-17 13:52:56 -040016 if (arguments.length === 1) {
Kevin Lubick1a05fce2018-11-20 12:51:16 -050017 // Add path, unchanged. Use identity matrix
18 this._addPath(path, 1, 0, 0,
19 0, 1, 0,
20 0, 0, 1);
Kevin Lubick11194ab2018-08-17 13:52:56 -040021 } else if (arguments.length === 2) {
22 // Takes SVGMatrix, which has its args in a counter-intuitive order
23 // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#Transform_functions
Kevin Lubick11194ab2018-08-17 13:52:56 -040024 var sm = arguments[1];
Kevin Lubick6f65f062022-11-28 12:27:21 -050025 this._addPath(path, sm['a'], sm['c'], sm['e'],
26 sm['b'], sm['d'], sm['f'],
27 0, 0, 1);
Kevin Lubick11194ab2018-08-17 13:52:56 -040028 } else if (arguments.length === 7) {
29 // User provided the 6 params for an SVGMatrix directly.
30 var a = arguments;
Kevin Lubick1a05fce2018-11-20 12:51:16 -050031 this._addPath(path, a[1], a[3], a[5],
32 a[2], a[4], a[6],
33 0 , 0 , 1 );
Kevin Lubick11194ab2018-08-17 13:52:56 -040034 } else if (arguments.length === 10) {
35 // User provided the 9 params of a (full) matrix directly.
36 // These are in the same order as what Skia expects.
37 var a = arguments;
Kevin Lubick1a05fce2018-11-20 12:51:16 -050038 this._addPath(path, a[1], a[2], a[3],
39 a[4], a[5], a[6],
40 a[7], a[8], a[9]);
Kevin Lubick11194ab2018-08-17 13:52:56 -040041 } else {
42 console.err('addPath expected to take 1, 2, 7, or 10 args. Got ' + arguments.length);
43 return null;
44 }
45 return this;
46 };
47
48 // ccw (counter clock wise) is optional and defaults to false.
49 PathKit.SkPath.prototype.arc = function(x, y, radius, startAngle, endAngle, ccw) {
50 this._arc(x, y, radius, startAngle, endAngle, !!ccw);
51 return this;
52 };
53
54 PathKit.SkPath.prototype.arcTo = function(x1, y1, x2, y2, radius) {
55 this._arcTo(x1, y1, x2, y2, radius);
56 return this;
57 };
58
59 PathKit.SkPath.prototype.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
60 this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
61 return this;
62 };
63
64 PathKit.SkPath.prototype.close = function() {
65 this._close();
66 return this;
67 };
68
69 // Reminder, we have some duplicate definitions because we want to be a
70 // superset of Path2D and also work like the original SkPath C++ object.
71 PathKit.SkPath.prototype.closePath = function() {
72 this._close();
73 return this;
74 };
75
76 PathKit.SkPath.prototype.conicTo = function(x1, y1, x2, y2, w) {
77 this._conicTo(x1, y1, x2, y2, w);
78 return this;
79 };
80
81 PathKit.SkPath.prototype.cubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
82 this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
83 return this;
84 };
85
86 PathKit.SkPath.prototype.dash = function(on, off, phase) {
87 if (this._dash(on, off, phase)) {
88 return this;
89 }
90 return null;
91 };
92
93 // ccw (counter clock wise) is optional and defaults to false.
94 PathKit.SkPath.prototype.ellipse = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, ccw) {
95 this._ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, !!ccw);
96 return this;
97 };
98
99 PathKit.SkPath.prototype.lineTo = function(x, y) {
100 this._lineTo(x, y);
101 return this;
102 };
103
104 PathKit.SkPath.prototype.moveTo = function(x, y) {
105 this._moveTo(x, y);
106 return this;
107 };
108
109 PathKit.SkPath.prototype.op = function(otherPath, op) {
110 if (this._op(otherPath, op)) {
111 return this;
112 }
113 return null;
114 };
115
Kevin Lubickd9936482018-08-24 10:44:16 -0400116 PathKit.SkPath.prototype.quadraticCurveTo = function(cpx, cpy, x, y) {
117 this._quadTo(cpx, cpy, x, y);
Kevin Lubick11194ab2018-08-17 13:52:56 -0400118 return this;
119 };
120
Kevin Lubickd9936482018-08-24 10:44:16 -0400121 PathKit.SkPath.prototype.quadTo = function(cpx, cpy, x, y) {
122 this._quadTo(cpx, cpy, x, y);
Kevin Lubick11194ab2018-08-17 13:52:56 -0400123 return this;
124 };
125
126 PathKit.SkPath.prototype.rect = function(x, y, w, h) {
127 this._rect(x, y, w, h);
128 return this;
129 };
130
131 PathKit.SkPath.prototype.simplify = function() {
132 if (this._simplify()) {
133 return this;
134 }
135 return null;
136 };
137
138 PathKit.SkPath.prototype.stroke = function(opts) {
139 // Fill out any missing values with the default values.
140 /**
141 * See externs.js for this definition
142 * @type {StrokeOpts}
143 */
144 opts = opts || {};
Kevin Lubick7ca19d22022-05-23 12:46:04 -0400145 opts['width'] = opts['width'] || 1;
146 opts['miter_limit'] = opts['miter_limit'] || 4;
147 opts['cap'] = opts['cap'] || PathKit.StrokeCap.BUTT;
148 opts['join'] = opts['join'] || PathKit.StrokeJoin.MITER;
149 opts['res_scale'] = opts['res_scale'] || 1;
Kevin Lubick11194ab2018-08-17 13:52:56 -0400150 if (this._stroke(opts)) {
151 return this;
152 }
153 return null;
154 };
155
156 PathKit.SkPath.prototype.transform = function() {
157 // Takes 1 or 9 args
158 if (arguments.length === 1) {
159 // argument 1 should be a 9 element array (which is transformed on the C++ side
160 // to a SimpleMatrix)
161 this._transform(arguments[0]);
162 } else if (arguments.length === 9) {
163 // these arguments are the 9 members of the matrix
164 var a = arguments;
165 this._transform(a[0], a[1], a[2],
166 a[3], a[4], a[5],
167 a[6], a[7], a[8]);
168 } else {
169 console.err('transform expected to take 1 or 9 arguments. Got ' + arguments.length);
170 return null;
171 }
172 return this;
173 };
174
175 // isComplement is optional, defaults to false
176 PathKit.SkPath.prototype.trim = function(startT, stopT, isComplement) {
177 if (this._trim(startT, stopT, !!isComplement)) {
178 return this;
179 }
180 return null;
181 };
182 };
183
184}(Module)); // When this file is loaded in, the high level object is "Module";
185