xref: /aosp_15_r20/external/skia/modules/pathkit/chaining.js (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1// 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
15      var path = arguments[0];
16      if (arguments.length === 1) {
17        // Add path, unchanged.  Use identity matrix
18        this._addPath(path, 1, 0, 0,
19                            0, 1, 0,
20                            0, 0, 1);
21      } 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
24        var sm = arguments[1];
25        this._addPath(path, sm['a'], sm['c'], sm['e'],
26                            sm['b'], sm['d'], sm['f'],
27                                  0,       0,       1);
28      } else if (arguments.length === 7) {
29        // User provided the 6 params for an SVGMatrix directly.
30        var a = arguments;
31        this._addPath(path, a[1], a[3], a[5],
32                            a[2], a[4], a[6],
33                              0 ,   0 ,   1 );
34      } 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;
38        this._addPath(path, a[1], a[2], a[3],
39                            a[4], a[5], a[6],
40                            a[7], a[8], a[9]);
41      } 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    PathKit.SkPath.prototype.reverseAddPath = function() {
49      this._reverseAddPath(arguments[0]);
50      return this;
51    };
52
53    // ccw (counter clock wise) is optional and defaults to false.
54    PathKit.SkPath.prototype.arc = function(x, y, radius, startAngle, endAngle, ccw) {
55      this._arc(x, y, radius, startAngle, endAngle, !!ccw);
56      return this;
57    };
58
59    PathKit.SkPath.prototype.arcTo = function(x1, y1, x2, y2, radius) {
60      this._arcTo(x1, y1, x2, y2, radius);
61      return this;
62    };
63
64    PathKit.SkPath.prototype.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
65      this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
66      return this;
67    };
68
69    PathKit.SkPath.prototype.close = function() {
70      this._close();
71      return this;
72    };
73
74    // Reminder, we have some duplicate definitions because we want to be a
75    // superset of Path2D and also work like the original SkPath C++ object.
76    PathKit.SkPath.prototype.closePath = function() {
77      this._close();
78      return this;
79    };
80
81    PathKit.SkPath.prototype.conicTo = function(x1, y1, x2, y2, w) {
82      this._conicTo(x1, y1, x2, y2, w);
83      return this;
84    };
85
86    PathKit.SkPath.prototype.cubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
87      this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
88      return this;
89    };
90
91    PathKit.SkPath.prototype.dash = function(on, off, phase) {
92      if (this._dash(on, off, phase)) {
93        return this;
94      }
95      return null;
96    };
97
98    // ccw (counter clock wise) is optional and defaults to false.
99    PathKit.SkPath.prototype.ellipse = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, ccw) {
100      this._ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, !!ccw);
101      return this;
102    };
103
104    PathKit.SkPath.prototype.lineTo = function(x, y) {
105      this._lineTo(x, y);
106      return this;
107    };
108
109    PathKit.SkPath.prototype.moveTo = function(x, y) {
110      this._moveTo(x, y);
111      return this;
112    };
113
114    PathKit.SkPath.prototype.op = function(otherPath, op) {
115      if (this._op(otherPath, op)) {
116        return this;
117      }
118      return null;
119    };
120
121    PathKit.SkPath.prototype.quadraticCurveTo = function(cpx, cpy, x, y) {
122      this._quadTo(cpx, cpy, x, y);
123      return this;
124    };
125
126    PathKit.SkPath.prototype.quadTo = function(cpx, cpy, x, y) {
127      this._quadTo(cpx, cpy, x, y);
128      return this;
129    };
130
131    PathKit.SkPath.prototype.rect = function(x, y, w, h) {
132      this._rect(x, y, w, h);
133      return this;
134    };
135
136    PathKit.SkPath.prototype.simplify = function() {
137      if (this._simplify()) {
138        return this;
139      }
140      return null;
141    };
142
143    PathKit.SkPath.prototype.asWinding = function() {
144      if (this._asWinding()) {
145        return this;
146      }
147      return null;
148    }
149
150    PathKit.SkPath.prototype.isEmpty = function() {
151      return this._isEmpty();
152    };
153
154    PathKit.SkPath.prototype.stroke = function(opts) {
155      // Fill out any missing values with the default values.
156      /**
157       * See externs.js for this definition
158       * @type {StrokeOpts}
159       */
160      opts = opts || {};
161      opts['width'] = opts['width'] || 1;
162      opts['miter_limit'] = opts['miter_limit'] || 4;
163      opts['cap'] = opts['cap'] || PathKit.StrokeCap.BUTT;
164      opts['join'] = opts['join'] || PathKit.StrokeJoin.MITER;
165      opts['res_scale'] = opts['res_scale'] || 1;
166      if (this._stroke(opts)) {
167        return this;
168      }
169      return null;
170    };
171
172    PathKit.SkPath.prototype.transform = function() {
173      // Takes 1 or 9 args
174      if (arguments.length === 1) {
175        // argument 1 should be a 9 element array (which is transformed on the C++ side
176        // to a SimpleMatrix)
177        this._transform(arguments[0]);
178      } else if (arguments.length === 9) {
179        // these arguments are the 9 members of the matrix
180        var a = arguments;
181        this._transform(a[0], a[1], a[2],
182                        a[3], a[4], a[5],
183                        a[6], a[7], a[8]);
184      } else {
185        console.err('transform expected to take 1 or 9 arguments. Got ' + arguments.length);
186        return null;
187      }
188      return this;
189    };
190
191    // isComplement is optional, defaults to false
192    PathKit.SkPath.prototype.trim = function(startT, stopT, isComplement) {
193      if (this._trim(startT, stopT, !!isComplement)) {
194        return this;
195      }
196      return null;
197    };
198  };
199
200}(Module)); // When this file is loaded in, the high level object is "Module";
201
202