blob: 25b374e8fef69dab40dbed222d1cfaa8a6390227 [file] [log] [blame]
Kevin Lubick217056c2018-09-20 17:39:31 -04001/*
2 * Copyright 2018 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Kevin Lubick6b921b72019-09-18 16:18:17 -04008#include "include/android/SkAnimatedImage.h"
9#include "include/codec/SkAndroidCodec.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkBlendMode.h"
11#include "include/core/SkBlurTypes.h"
12#include "include/core/SkCanvas.h"
13#include "include/core/SkColor.h"
Kevin Lubickd3729342019-09-12 11:11:25 -040014#include "include/core/SkColorFilter.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "include/core/SkData.h"
Kevin Lubick6b921b72019-09-18 16:18:17 -040016#include "include/core/SkDrawable.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "include/core/SkEncodedImageFormat.h"
18#include "include/core/SkFilterQuality.h"
19#include "include/core/SkFont.h"
20#include "include/core/SkFontMgr.h"
21#include "include/core/SkFontTypes.h"
22#include "include/core/SkImage.h"
Kevin Lubick15b40232019-10-29 09:55:39 -040023#include "include/core/SkImageFilter.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/core/SkImageInfo.h"
25#include "include/core/SkMaskFilter.h"
26#include "include/core/SkPaint.h"
27#include "include/core/SkPath.h"
28#include "include/core/SkPathEffect.h"
29#include "include/core/SkPathMeasure.h"
30#include "include/core/SkPicture.h"
31#include "include/core/SkPictureRecorder.h"
Kevin Lubick2e5fe352019-09-03 12:59:06 -040032#include "include/core/SkRRect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050033#include "include/core/SkScalar.h"
34#include "include/core/SkShader.h"
35#include "include/core/SkString.h"
36#include "include/core/SkStrokeRec.h"
37#include "include/core/SkSurface.h"
38#include "include/core/SkSurfaceProps.h"
39#include "include/core/SkTextBlob.h"
40#include "include/core/SkTypeface.h"
41#include "include/core/SkTypes.h"
42#include "include/core/SkVertices.h"
43#include "include/effects/SkCornerPathEffect.h"
44#include "include/effects/SkDashPathEffect.h"
45#include "include/effects/SkDiscretePathEffect.h"
46#include "include/effects/SkGradientShader.h"
Kevin Lubick15b40232019-10-29 09:55:39 -040047#include "include/effects/SkImageFilters.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050048#include "include/effects/SkTrimPathEffect.h"
49#include "include/pathops/SkPathOps.h"
50#include "include/utils/SkParsePath.h"
51#include "include/utils/SkShadowUtils.h"
52#include "modules/skshaper/include/SkShaper.h"
53#include "src/core/SkFontMgrPriv.h"
54#include "src/core/SkMakeUnique.h"
Kevin Lubickb5ae3b52018-11-03 07:51:19 -040055
Kevin Lubick217056c2018-09-20 17:39:31 -040056#include <iostream>
57#include <string>
Kevin Lubick217056c2018-09-20 17:39:31 -040058
Mike Kleinc0bd9f92019-04-23 12:05:21 -050059#include "modules/canvaskit/WasmAliases.h"
Kevin Lubick217056c2018-09-20 17:39:31 -040060#include <emscripten.h>
61#include <emscripten/bind.h>
Kevin Lubick46839422019-01-03 14:27:27 -050062
Kevin Lubick53965c92018-10-11 08:51:55 -040063#if SK_SUPPORT_GPU
Mike Kleinc0bd9f92019-04-23 12:05:21 -050064#include "include/gpu/GrBackendSurface.h"
65#include "include/gpu/GrContext.h"
66#include "include/gpu/gl/GrGLInterface.h"
67#include "include/gpu/gl/GrGLTypes.h"
Kevin Lubick3f67f412019-03-11 16:11:58 -040068
Kevin Lubick53965c92018-10-11 08:51:55 -040069#include <GL/gl.h>
Kevin Lubick217056c2018-09-20 17:39:31 -040070#include <emscripten/html5.h>
Kevin Lubick53965c92018-10-11 08:51:55 -040071#endif
Kevin Lubick217056c2018-09-20 17:39:31 -040072
Kevin Lubick369f6a52019-10-03 11:22:08 -040073#ifdef SK_INCLUDE_PARAGRAPH
74#include "modules/skparagraph/include/Paragraph.h"
75#endif
Kevin Lubickb5ae3b52018-11-03 07:51:19 -040076// Aliases for less typing
77using BoneIndices = SkVertices::BoneIndices;
78using BoneWeights = SkVertices::BoneWeights;
79using Bone = SkVertices::Bone;
Kevin Lubick217056c2018-09-20 17:39:31 -040080
Kevin Lubick61887c72019-09-26 13:20:50 -040081#ifndef SK_NO_FONTS
82sk_sp<SkFontMgr> SkFontMgr_New_Custom_Data(const uint8_t** datas, const size_t* sizes, int n);
83#endif
84
Kevin Lubickb5ae3b52018-11-03 07:51:19 -040085struct SimpleMatrix {
86 SkScalar scaleX, skewX, transX;
87 SkScalar skewY, scaleY, transY;
88 SkScalar pers0, pers1, pers2;
89};
90
91SkMatrix toSkMatrix(const SimpleMatrix& sm) {
92 return SkMatrix::MakeAll(sm.scaleX, sm.skewX , sm.transX,
93 sm.skewY , sm.scaleY, sm.transY,
94 sm.pers0 , sm.pers1 , sm.pers2);
Kevin Lubick217056c2018-09-20 17:39:31 -040095}
96
Kevin Lubick5d5723c2018-12-07 10:09:11 -050097SimpleMatrix toSimpleSkMatrix(const SkMatrix& sm) {
98 SimpleMatrix m {sm[0], sm[1], sm[2],
99 sm[3], sm[4], sm[5],
100 sm[6], sm[7], sm[8]};
101 return m;
102}
103
Kevin Lubickea905ec2018-11-30 14:05:58 -0500104struct SimpleImageInfo {
105 int width;
106 int height;
107 SkColorType colorType;
108 SkAlphaType alphaType;
109 // TODO color spaces?
110};
111
112SkImageInfo toSkImageInfo(const SimpleImageInfo& sii) {
113 return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType);
114}
115
Kevin Lubick543f3522019-03-08 10:04:28 -0500116#if SK_SUPPORT_GPU
117sk_sp<GrContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)
118{
119 EMSCRIPTEN_RESULT r = emscripten_webgl_make_context_current(context);
120 if (r < 0) {
121 printf("failed to make webgl context current %d\n", r);
122 return nullptr;
123 }
124 // setup GrContext
125 auto interface = GrGLMakeNativeInterface();
126 // setup contexts
127 sk_sp<GrContext> grContext(GrContext::MakeGL(interface));
128 return grContext;
129}
130
131sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrContext> grContext, int width, int height) {
132 glClearColor(0, 0, 0, 0);
133 glClearStencil(0);
134 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
135
136
137 // Wrap the frame buffer object attached to the screen in a Skia render
138 // target so Skia can render to it
139 GrGLint buffer;
140 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
141 GrGLFramebufferInfo info;
142 info.fFBOID = (GrGLuint) buffer;
143 SkColorType colorType;
144
145 info.fFormat = GL_RGBA8;
146 colorType = kRGBA_8888_SkColorType;
147
148 GrBackendRenderTarget target(width, height, 0, 8, info);
149
150 sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget(grContext.get(), target,
151 kBottomLeft_GrSurfaceOrigin,
152 colorType, nullptr, nullptr));
153 return surface;
154}
155
156sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrContext> grContext, int width, int height) {
157 SkImageInfo info = SkImageInfo::MakeN32(width, height, SkAlphaType::kPremul_SkAlphaType);
158
159 sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(grContext.get(),
160 SkBudgeted::kYes,
161 info, 0,
162 kBottomLeft_GrSurfaceOrigin,
163 nullptr, true));
164 return surface;
165}
166
167sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrContext> grContext, SimpleImageInfo sii) {
168 sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(grContext.get(),
169 SkBudgeted::kYes,
170 toSkImageInfo(sii), 0,
171 kBottomLeft_GrSurfaceOrigin,
172 nullptr, true));
173 return surface;
174}
175#endif
176
177
Kevin Lubick217056c2018-09-20 17:39:31 -0400178//========================================================================================
179// Path things
180//========================================================================================
181
182// All these Apply* methods are simple wrappers to avoid returning an object.
183// The default WASM bindings produce code that will leak if a return value
184// isn't assigned to a JS variable and has delete() called on it.
185// These Apply methods, combined with the smarter binding code allow for chainable
186// commands that don't leak if the return value is ignored (i.e. when used intuitively).
187
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500188void ApplyAddArc(SkPath& orig, const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle) {
189 orig.addArc(oval, startAngle, sweepAngle);
190}
191
Kevin Lubicke384df42019-08-26 15:48:09 -0400192void ApplyAddOval(SkPath& orig, const SkRect& oval, bool ccw, unsigned start) {
193 orig.addOval(oval, ccw ? SkPath::Direction::kCCW_Direction :
194 SkPath::Direction::kCW_Direction, start);
195}
196
Kevin Lubick217056c2018-09-20 17:39:31 -0400197void ApplyAddPath(SkPath& orig, const SkPath& newPath,
198 SkScalar scaleX, SkScalar skewX, SkScalar transX,
199 SkScalar skewY, SkScalar scaleY, SkScalar transY,
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500200 SkScalar pers0, SkScalar pers1, SkScalar pers2,
201 bool extendPath) {
Kevin Lubick217056c2018-09-20 17:39:31 -0400202 SkMatrix m = SkMatrix::MakeAll(scaleX, skewX , transX,
203 skewY , scaleY, transY,
204 pers0 , pers1 , pers2);
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500205 orig.addPath(newPath, m, extendPath ? SkPath::kExtend_AddPathMode :
206 SkPath::kAppend_AddPathMode);
Kevin Lubick217056c2018-09-20 17:39:31 -0400207}
208
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500209void ApplyAddRect(SkPath& path, SkScalar left, SkScalar top,
210 SkScalar right, SkScalar bottom, bool ccw) {
211 path.addRect(left, top, right, bottom,
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500212 ccw ? SkPath::Direction::kCCW_Direction :
213 SkPath::Direction::kCW_Direction);
Alexander Khovansky3e119332018-11-15 02:01:19 +0300214}
215
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500216void ApplyAddRoundRect(SkPath& path, SkScalar left, SkScalar top,
217 SkScalar right, SkScalar bottom, uintptr_t /* SkScalar* */ rPtr,
218 bool ccw) {
219 // See comment below for uintptr_t explanation
220 const SkScalar* radii = reinterpret_cast<const SkScalar*>(rPtr);
221 path.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), radii,
222 ccw ? SkPath::Direction::kCCW_Direction : SkPath::Direction::kCW_Direction);
223}
224
225
Kevin Lubick217056c2018-09-20 17:39:31 -0400226void ApplyArcTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
227 SkScalar radius) {
228 p.arcTo(x1, y1, x2, y2, radius);
229}
230
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500231void ApplyArcToAngle(SkPath& p, SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo) {
232 p.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
233}
234
Kevin Lubick79b71342019-11-01 14:36:52 -0400235void ApplyArcToArcSize(SkPath& orig, SkScalar rx, SkScalar ry, SkScalar xAxisRotate,
236 bool useSmallArc, bool ccw, SkScalar x, SkScalar y) {
Kevin Lubicke384df42019-08-26 15:48:09 -0400237 auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize : SkPath::ArcSize::kLarge_ArcSize;
238 auto sweep = ccw ? SkPath::Direction::kCCW_Direction : SkPath::Direction::kCW_Direction;
239 orig.arcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
240}
241
Kevin Lubick79b71342019-11-01 14:36:52 -0400242void ApplyRArcToArcSize(SkPath& orig, SkScalar rx, SkScalar ry, SkScalar xAxisRotate,
243 bool useSmallArc, bool ccw, SkScalar dx, SkScalar dy) {
244 auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize : SkPath::ArcSize::kLarge_ArcSize;
245 auto sweep = ccw ? SkPath::Direction::kCCW_Direction : SkPath::Direction::kCW_Direction;
246 orig.rArcTo(rx, ry, xAxisRotate, arcSize, sweep, dx, dy);
247}
248
Kevin Lubick217056c2018-09-20 17:39:31 -0400249void ApplyClose(SkPath& p) {
250 p.close();
251}
252
253void ApplyConicTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
254 SkScalar w) {
255 p.conicTo(x1, y1, x2, y2, w);
256}
257
Kevin Lubick79b71342019-11-01 14:36:52 -0400258void ApplyRConicTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
259 SkScalar w) {
260 p.rConicTo(dx1, dy1, dx2, dy2, w);
261}
262
Kevin Lubick217056c2018-09-20 17:39:31 -0400263void ApplyCubicTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
264 SkScalar x3, SkScalar y3) {
265 p.cubicTo(x1, y1, x2, y2, x3, y3);
266}
267
Kevin Lubick79b71342019-11-01 14:36:52 -0400268void ApplyRCubicTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
269 SkScalar dx3, SkScalar dy3) {
270 p.rCubicTo(dx1, dy1, dx2, dy2, dx3, dy3);
271}
272
Kevin Lubick217056c2018-09-20 17:39:31 -0400273void ApplyLineTo(SkPath& p, SkScalar x, SkScalar y) {
274 p.lineTo(x, y);
275}
276
Kevin Lubick79b71342019-11-01 14:36:52 -0400277void ApplyRLineTo(SkPath& p, SkScalar dx, SkScalar dy) {
278 p.rLineTo(dx, dy);
279}
280
Kevin Lubick217056c2018-09-20 17:39:31 -0400281void ApplyMoveTo(SkPath& p, SkScalar x, SkScalar y) {
282 p.moveTo(x, y);
283}
284
Kevin Lubick79b71342019-11-01 14:36:52 -0400285void ApplyRMoveTo(SkPath& p, SkScalar dx, SkScalar dy) {
286 p.rMoveTo(dx, dy);
287}
288
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500289void ApplyReset(SkPath& p) {
290 p.reset();
291}
292
293void ApplyRewind(SkPath& p) {
294 p.rewind();
295}
296
Kevin Lubick217056c2018-09-20 17:39:31 -0400297void ApplyQuadTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
298 p.quadTo(x1, y1, x2, y2);
299}
300
Kevin Lubick79b71342019-11-01 14:36:52 -0400301void ApplyRQuadTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2) {
302 p.rQuadTo(dx1, dy1, dx2, dy2);
303}
304
Kevin Lubick217056c2018-09-20 17:39:31 -0400305void ApplyTransform(SkPath& orig,
306 SkScalar scaleX, SkScalar skewX, SkScalar transX,
307 SkScalar skewY, SkScalar scaleY, SkScalar transY,
308 SkScalar pers0, SkScalar pers1, SkScalar pers2) {
309 SkMatrix m = SkMatrix::MakeAll(scaleX, skewX , transX,
310 skewY , scaleY, transY,
311 pers0 , pers1 , pers2);
312 orig.transform(m);
313}
314
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400315bool EMSCRIPTEN_KEEPALIVE ApplySimplify(SkPath& path) {
316 return Simplify(path, &path);
317}
318
319bool EMSCRIPTEN_KEEPALIVE ApplyPathOp(SkPath& pathOne, const SkPath& pathTwo, SkPathOp op) {
320 return Op(pathOne, pathTwo, op, &pathOne);
321}
322
323JSString EMSCRIPTEN_KEEPALIVE ToSVGString(const SkPath& path) {
324 SkString s;
325 SkParsePath::ToSVGString(path, &s);
326 return emscripten::val(s.c_str());
327}
328
Kevin Lubicka40f8322018-12-17 16:01:36 -0500329SkPathOrNull EMSCRIPTEN_KEEPALIVE MakePathFromSVGString(std::string str) {
330 SkPath path;
331 if (SkParsePath::FromSVGString(str.c_str(), &path)) {
332 return emscripten::val(path);
333 }
334 return emscripten::val::null();
335}
336
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400337SkPathOrNull EMSCRIPTEN_KEEPALIVE MakePathFromOp(const SkPath& pathOne, const SkPath& pathTwo, SkPathOp op) {
338 SkPath out;
339 if (Op(pathOne, pathTwo, op, &out)) {
340 return emscripten::val(out);
341 }
342 return emscripten::val::null();
343}
344
Kevin Lubick217056c2018-09-20 17:39:31 -0400345SkPath EMSCRIPTEN_KEEPALIVE CopyPath(const SkPath& a) {
346 SkPath copy(a);
347 return copy;
348}
349
350bool EMSCRIPTEN_KEEPALIVE Equals(const SkPath& a, const SkPath& b) {
351 return a == b;
352}
353
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500354// =================================================================================
355// Creating/Exporting Paths with cmd arrays
356// =================================================================================
357
358static const int MOVE = 0;
359static const int LINE = 1;
360static const int QUAD = 2;
361static const int CONIC = 3;
362static const int CUBIC = 4;
363static const int CLOSE = 5;
364
365template <typename VisitFunc>
366void VisitPath(const SkPath& p, VisitFunc&& f) {
367 SkPath::RawIter iter(p);
368 SkPoint pts[4];
369 SkPath::Verb verb;
370 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
371 f(verb, pts, iter);
372 }
373}
374
375JSArray EMSCRIPTEN_KEEPALIVE ToCmds(const SkPath& path) {
376 JSArray cmds = emscripten::val::array();
377
378 VisitPath(path, [&cmds](SkPath::Verb verb, const SkPoint pts[4], SkPath::RawIter iter) {
379 JSArray cmd = emscripten::val::array();
380 switch (verb) {
381 case SkPath::kMove_Verb:
382 cmd.call<void>("push", MOVE, pts[0].x(), pts[0].y());
383 break;
384 case SkPath::kLine_Verb:
385 cmd.call<void>("push", LINE, pts[1].x(), pts[1].y());
386 break;
387 case SkPath::kQuad_Verb:
388 cmd.call<void>("push", QUAD, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
389 break;
390 case SkPath::kConic_Verb:
391 cmd.call<void>("push", CONIC,
392 pts[1].x(), pts[1].y(),
393 pts[2].x(), pts[2].y(), iter.conicWeight());
394 break;
395 case SkPath::kCubic_Verb:
396 cmd.call<void>("push", CUBIC,
397 pts[1].x(), pts[1].y(),
398 pts[2].x(), pts[2].y(),
399 pts[3].x(), pts[3].y());
400 break;
401 case SkPath::kClose_Verb:
402 cmd.call<void>("push", CLOSE);
403 break;
404 case SkPath::kDone_Verb:
405 SkASSERT(false);
406 break;
407 }
408 cmds.call<void>("push", cmd);
409 });
410 return cmds;
411}
412
413// This type signature is a mess, but it's necessary. See, we can't use "bind" (EMSCRIPTEN_BINDINGS)
414// and pointers to primitive types (Only bound types like SkPoint). We could if we used
415// cwrap (see https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97)
416// but that requires us to stick to C code and, AFAIK, doesn't allow us to return nice things like
417// SkPath or SkOpBuilder.
418//
Kevin Lubick61887c72019-09-26 13:20:50 -0400419// So, basically, if we are using C++ and EMSCRIPTEN_BINDINGS, we can't have primitive pointers
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500420// in our function type signatures. (this gives an error message like "Cannot call foo due to unbound
421// types Pi, Pf"). But, we can just pretend they are numbers and cast them to be pointers and
422// the compiler is happy.
423SkPathOrNull EMSCRIPTEN_KEEPALIVE MakePathFromCmds(uintptr_t /* float* */ cptr, int numCmds) {
424 const auto* cmds = reinterpret_cast<const float*>(cptr);
425 SkPath path;
426 float x1, y1, x2, y2, x3, y3;
427
428 // if there are not enough arguments, bail with the path we've constructed so far.
429 #define CHECK_NUM_ARGS(n) \
430 if ((i + n) > numCmds) { \
431 SkDebugf("Not enough args to match the verbs. Saw %d commands\n", numCmds); \
432 return emscripten::val::null(); \
433 }
434
435 for(int i = 0; i < numCmds;){
436 switch (sk_float_floor2int(cmds[i++])) {
437 case MOVE:
438 CHECK_NUM_ARGS(2);
439 x1 = cmds[i++], y1 = cmds[i++];
440 path.moveTo(x1, y1);
441 break;
442 case LINE:
443 CHECK_NUM_ARGS(2);
444 x1 = cmds[i++], y1 = cmds[i++];
445 path.lineTo(x1, y1);
446 break;
447 case QUAD:
448 CHECK_NUM_ARGS(4);
449 x1 = cmds[i++], y1 = cmds[i++];
450 x2 = cmds[i++], y2 = cmds[i++];
451 path.quadTo(x1, y1, x2, y2);
452 break;
453 case CONIC:
454 CHECK_NUM_ARGS(5);
455 x1 = cmds[i++], y1 = cmds[i++];
456 x2 = cmds[i++], y2 = cmds[i++];
457 x3 = cmds[i++]; // weight
458 path.conicTo(x1, y1, x2, y2, x3);
459 break;
460 case CUBIC:
461 CHECK_NUM_ARGS(6);
462 x1 = cmds[i++], y1 = cmds[i++];
463 x2 = cmds[i++], y2 = cmds[i++];
464 x3 = cmds[i++], y3 = cmds[i++];
465 path.cubicTo(x1, y1, x2, y2, x3, y3);
466 break;
467 case CLOSE:
468 path.close();
469 break;
470 default:
471 SkDebugf(" path: UNKNOWN command %f, aborting dump...\n", cmds[i-1]);
472 return emscripten::val::null();
473 }
474 }
475
476 #undef CHECK_NUM_ARGS
477
478 return emscripten::val(path);
479}
480
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400481//========================================================================================
482// Path Effects
483//========================================================================================
484
485bool ApplyDash(SkPath& path, SkScalar on, SkScalar off, SkScalar phase) {
486 SkScalar intervals[] = { on, off };
487 auto pe = SkDashPathEffect::Make(intervals, 2, phase);
488 if (!pe) {
489 SkDebugf("Invalid args to dash()\n");
490 return false;
491 }
492 SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
493 if (pe->filterPath(&path, path, &rec, nullptr)) {
494 return true;
495 }
496 SkDebugf("Could not make dashed path\n");
497 return false;
Kevin Lubick217056c2018-09-20 17:39:31 -0400498}
499
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400500bool ApplyTrim(SkPath& path, SkScalar startT, SkScalar stopT, bool isComplement) {
501 auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted : SkTrimPathEffect::Mode::kNormal;
502 auto pe = SkTrimPathEffect::Make(startT, stopT, mode);
503 if (!pe) {
504 SkDebugf("Invalid args to trim(): startT and stopT must be in [0,1]\n");
505 return false;
506 }
507 SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
508 if (pe->filterPath(&path, path, &rec, nullptr)) {
509 return true;
510 }
511 SkDebugf("Could not trim path\n");
512 return false;
513}
514
515struct StrokeOpts {
Kevin Lubickb9db3902018-11-26 11:47:54 -0500516 // Default values are set in interface.js which allows clients
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400517 // to set any number of them. Otherwise, the binding code complains if
518 // any are omitted.
519 SkScalar width;
520 SkScalar miter_limit;
521 SkPaint::Join join;
522 SkPaint::Cap cap;
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500523 float precision;
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400524};
525
526bool ApplyStroke(SkPath& path, StrokeOpts opts) {
527 SkPaint p;
528 p.setStyle(SkPaint::kStroke_Style);
529 p.setStrokeCap(opts.cap);
530 p.setStrokeJoin(opts.join);
531 p.setStrokeWidth(opts.width);
532 p.setStrokeMiter(opts.miter_limit);
533
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500534 return p.getFillPath(path, &path, nullptr, opts.precision);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400535}
536
537// to map from raw memory to a uint8array
538Uint8Array getSkDataBytes(const SkData *data) {
539 return Uint8Array(typed_memory_view(data->size(), data->bytes()));
540}
541
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500542// Text Shaping abstraction
543
544struct ShapedTextOpts {
545 SkFont font;
546 bool leftToRight;
547 std::string text;
548 SkScalar width;
549};
550
551std::unique_ptr<SkShaper> shaper;
552
553static sk_sp<SkTextBlob> do_shaping(const ShapedTextOpts& opts, SkPoint* pt) {
Ben Wagner3bdb69c2019-04-01 19:01:09 -0400554 SkTextBlobBuilderRunHandler builder(opts.text.c_str(), {0, 0});
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500555 if (!shaper) {
556 shaper = SkShaper::Make();
557 }
Ben Wagner3bdb69c2019-04-01 19:01:09 -0400558 shaper->shape(opts.text.c_str(), opts.text.length(),
559 opts.font, opts.leftToRight,
560 opts.width, &builder);
561 *pt = builder.endPoint();
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500562 return builder.makeBlob();
563}
564
565class ShapedText {
566public:
567 ShapedText(ShapedTextOpts opts) : fOpts(opts) {}
568
569 SkRect getBounds() {
570 this->init();
571 return SkRect::MakeLTRB(0, 0, fOpts.width, fPoint.y());
572 }
573
574 SkTextBlob* blob() {
575 this->init();
576 return fBlob.get();
577 }
578private:
579 const ShapedTextOpts fOpts;
580 SkPoint fPoint;
581 sk_sp<SkTextBlob> fBlob;
582
583 void init() {
584 if (!fBlob) {
585 fBlob = do_shaping(fOpts, &fPoint);
586 }
587 }
588};
589
590void drawShapedText(SkCanvas& canvas, ShapedText st, SkScalar x,
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400591 SkScalar y, SkPaint paint) {
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500592 canvas.drawTextBlob(st.blob(), x, y, paint);
593}
594
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400595int saveLayerRec(SkCanvas& canvas, const SkPaint* paint,
596 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) {
597 return canvas.saveLayer(SkCanvas::SaveLayerRec(nullptr, paint, backdrop, flags));
598}
599
600int saveLayerRecBounds(SkCanvas& canvas, const SkPaint* paint, const SkImageFilter* backdrop,
601 SkCanvas::SaveLayerFlags flags, const SkRect& bounds) {
602 return canvas.saveLayer(SkCanvas::SaveLayerRec(&bounds, paint, backdrop, flags));
603}
604
Kevin Lubickd3cfbca2019-03-15 15:36:29 -0400605// This is simpler than dealing with an SkPoint and SkVector
606struct PosTan {
607 SkScalar px, py, tx, ty;
608};
609
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400610// SimpleRRect is simpler than passing a (complex) SkRRect over the wire to JS.
611struct SimpleRRect {
612 SkRect rect;
Kevin Lubick7d644e12019-09-11 14:22:22 -0400613
614 SkScalar rx1;
615 SkScalar ry1;
616 SkScalar rx2;
617 SkScalar ry2;
618 SkScalar rx3;
619 SkScalar ry3;
620 SkScalar rx4;
621 SkScalar ry4;
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400622};
623
624SkRRect toRRect(const SimpleRRect& r) {
Kevin Lubick7d644e12019-09-11 14:22:22 -0400625 SkVector fRadii[4] = {{r.rx1, r.ry1}, {r.rx2, r.ry2},
626 {r.rx3, r.ry3}, {r.rx4, r.ry4}};
627 SkRRect rr;
628 rr.setRectRadii(r.rect, fRadii);
629 return rr;
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400630}
631
Kevin Lubick50f377e2019-09-11 15:23:00 -0400632struct TonalColors {
633 SkColor ambientColor;
634 SkColor spotColor;
635};
636
637TonalColors computeTonalColors(const TonalColors& in) {
638 TonalColors out;
639 SkShadowUtils::ComputeTonalColors(in.ambientColor, in.spotColor,
640 &out.ambientColor, &out.spotColor);
641 return out;
642}
643
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400644// These objects have private destructors / delete methods - I don't think
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400645// we need to do anything other than tell emscripten to do nothing.
Kevin Lubick217056c2018-09-20 17:39:31 -0400646namespace emscripten {
647 namespace internal {
648 template<typename ClassType>
649 void raw_destructor(ClassType *);
650
651 template<>
652 void raw_destructor<SkData>(SkData *ptr) {
653 }
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400654
655 template<>
656 void raw_destructor<SkVertices>(SkVertices *ptr) {
657 }
Kevin Lubickec4903d2019-01-14 08:36:08 -0500658
Kevin Lubick61887c72019-09-26 13:20:50 -0400659#ifndef SK_NO_FONTS
Kevin Lubickec4903d2019-01-14 08:36:08 -0500660 template<>
661 void raw_destructor<SkTextBlob>(SkTextBlob *ptr) {
662 }
Kevin Lubick61887c72019-09-26 13:20:50 -0400663
664 template<>
665 void raw_destructor<SkTypeface>(SkTypeface *ptr) {
666 }
667#endif
Kevin Lubick217056c2018-09-20 17:39:31 -0400668 }
669}
670
Kevin Lubick61887c72019-09-26 13:20:50 -0400671// Some signatures below have uintptr_t instead of a pointer to a primitive
Kevin Lubick217056c2018-09-20 17:39:31 -0400672// type (e.g. SkScalar). This is necessary because we can't use "bind" (EMSCRIPTEN_BINDINGS)
673// and pointers to primitive types (Only bound types like SkPoint). We could if we used
674// cwrap (see https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97)
675// but that requires us to stick to C code and, AFAIK, doesn't allow us to return nice things like
676// SkPath or SkCanvas.
677//
Kevin Lubick61887c72019-09-26 13:20:50 -0400678// So, basically, if we are using C++ and EMSCRIPTEN_BINDINGS, we can't have primitive pointers
Kevin Lubick217056c2018-09-20 17:39:31 -0400679// in our function type signatures. (this gives an error message like "Cannot call foo due to unbound
680// types Pi, Pf"). But, we can just pretend they are numbers and cast them to be pointers and
681// the compiler is happy.
682EMSCRIPTEN_BINDINGS(Skia) {
Kevin Lubick53965c92018-10-11 08:51:55 -0400683#if SK_SUPPORT_GPU
Kevin Lubick53965c92018-10-11 08:51:55 -0400684 function("currentContext", &emscripten_webgl_get_current_context);
685 function("setCurrentContext", &emscripten_webgl_make_context_current);
Kevin Lubick543f3522019-03-08 10:04:28 -0500686 function("MakeGrContext", &MakeGrContext);
687 function("MakeOnScreenGLSurface", &MakeOnScreenGLSurface);
688 function("MakeRenderTarget", select_overload<sk_sp<SkSurface>(sk_sp<GrContext>, int, int)>(&MakeRenderTarget));
689 function("MakeRenderTarget", select_overload<sk_sp<SkSurface>(sk_sp<GrContext>, SimpleImageInfo)>(&MakeRenderTarget));
690
Kevin Lubick3d99b1e2018-10-16 10:15:01 -0400691 constant("gpu", true);
Kevin Lubickb07204a2018-11-20 14:07:42 -0500692#endif
Kevin Lubick50f377e2019-09-11 15:23:00 -0400693 function("computeTonalColors", &computeTonalColors);
Kevin Lubick6b921b72019-09-18 16:18:17 -0400694 function("_decodeAnimatedImage", optional_override([](uintptr_t /* uint8_t* */ iptr,
695 size_t length)->sk_sp<SkAnimatedImage> {
696 uint8_t* imgData = reinterpret_cast<uint8_t*>(iptr);
697 sk_sp<SkData> bytes = SkData::MakeFromMalloc(imgData, length);
698 auto codec = SkAndroidCodec::MakeFromData(bytes);
699 if (nullptr == codec) {
700 return nullptr;
701 }
702 return SkAnimatedImage::Make(std::move(codec));
703 }), allow_raw_pointers());
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500704 function("_decodeImage", optional_override([](uintptr_t /* uint8_t* */ iptr,
705 size_t length)->sk_sp<SkImage> {
706 uint8_t* imgData = reinterpret_cast<uint8_t*>(iptr);
Kevin Lubick88aff5f2019-02-28 16:05:09 -0500707 sk_sp<SkData> bytes = SkData::MakeFromMalloc(imgData, length);
708 return SkImage::MakeFromEncoded(std::move(bytes));
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500709 }), allow_raw_pointers());
Kevin Lubickea905ec2018-11-30 14:05:58 -0500710 function("_getRasterDirectSurface", optional_override([](const SimpleImageInfo ii,
Kevin Lubick52b9f372018-12-04 13:57:36 -0500711 uintptr_t /* uint8_t* */ pPtr,
Kevin Lubickea905ec2018-11-30 14:05:58 -0500712 size_t rowBytes)->sk_sp<SkSurface> {
Kevin Lubick52b9f372018-12-04 13:57:36 -0500713 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
Kevin Lubickea905ec2018-11-30 14:05:58 -0500714 SkImageInfo imageInfo = toSkImageInfo(ii);
715 return SkSurface::MakeRasterDirect(imageInfo, pixels, rowBytes, nullptr);
716 }), allow_raw_pointers());
Kevin Lubick53965c92018-10-11 08:51:55 -0400717 function("_getRasterN32PremulSurface", optional_override([](int width, int height)->sk_sp<SkSurface> {
718 return SkSurface::MakeRasterN32Premul(width, height, nullptr);
719 }), allow_raw_pointers());
Kevin Lubickb07204a2018-11-20 14:07:42 -0500720
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400721 function("getSkDataBytes", &getSkDataBytes, allow_raw_pointers());
Kevin Lubick217056c2018-09-20 17:39:31 -0400722 function("MakeSkCornerPathEffect", &SkCornerPathEffect::Make, allow_raw_pointers());
723 function("MakeSkDiscretePathEffect", &SkDiscretePathEffect::Make, allow_raw_pointers());
Kevin Lubick15b40232019-10-29 09:55:39 -0400724 // Deprecated: use Canvaskit.SkMaskFilter.MakeBlur
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500725 function("MakeBlurMaskFilter", optional_override([](SkBlurStyle style, SkScalar sigma, bool respectCTM)->sk_sp<SkMaskFilter> {
726 // Adds a little helper because emscripten doesn't expose default params.
727 return SkMaskFilter::MakeBlur(style, sigma, respectCTM);
728 }), allow_raw_pointers());
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500729 function("_MakePathFromCmds", &MakePathFromCmds);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400730 function("MakePathFromOp", &MakePathFromOp);
Kevin Lubicka40f8322018-12-17 16:01:36 -0500731 function("MakePathFromSVGString", &MakePathFromSVGString);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400732
733 // These won't be called directly, there's a JS helper to deal with typed arrays.
Kevin Lubick217056c2018-09-20 17:39:31 -0400734 function("_MakeSkDashPathEffect", optional_override([](uintptr_t /* float* */ cptr, int count, SkScalar phase)->sk_sp<SkPathEffect> {
735 // See comment above for uintptr_t explanation
736 const float* intervals = reinterpret_cast<const float*>(cptr);
737 return SkDashPathEffect::Make(intervals, count, phase);
738 }), allow_raw_pointers());
Kevin Lubick52b9f372018-12-04 13:57:36 -0500739 function("_MakeImage", optional_override([](SimpleImageInfo ii,
740 uintptr_t /* uint8_t* */ pPtr, int plen,
741 size_t rowBytes)->sk_sp<SkImage> {
742 // See comment above for uintptr_t explanation
743 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
744 SkImageInfo info = toSkImageInfo(ii);
745 sk_sp<SkData> pixelData = SkData::MakeFromMalloc(pixels, plen);
746
747 return SkImage::MakeRasterData(info, pixelData, rowBytes);
748 }), allow_raw_pointers());
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400749 function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
750 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400751 int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400752 SkPoint points[] = { start, end };
753 // See comment above for uintptr_t explanation
754 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
755 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
756
757 return SkGradientShader::MakeLinear(points, colors, positions, count,
758 mode, flags, nullptr);
759 }), allow_raw_pointers());
760 function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
761 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400762 int count, SkTileMode mode, uint32_t flags,
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400763 const SimpleMatrix& lm)->sk_sp<SkShader> {
764 SkPoint points[] = { start, end };
765 // See comment above for uintptr_t explanation
766 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
767 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
768
769 SkMatrix localMatrix = toSkMatrix(lm);
770
771 return SkGradientShader::MakeLinear(points, colors, positions, count,
772 mode, flags, &localMatrix);
773 }), allow_raw_pointers());
774 function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
775 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400776 int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400777 // See comment above for uintptr_t explanation
778 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
779 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
780
781 return SkGradientShader::MakeRadial(center, radius, colors, positions, count,
782 mode, flags, nullptr);
783 }), allow_raw_pointers());
784 function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
785 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400786 int count, SkTileMode mode, uint32_t flags,
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400787 const SimpleMatrix& lm)->sk_sp<SkShader> {
788 // See comment above for uintptr_t explanation
789 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
790 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
791
792 SkMatrix localMatrix = toSkMatrix(lm);
793 return SkGradientShader::MakeRadial(center, radius, colors, positions, count,
794 mode, flags, &localMatrix);
795 }), allow_raw_pointers());
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500796 function("_MakeTwoPointConicalGradientShader", optional_override([](
797 SkPoint start, SkScalar startRadius,
798 SkPoint end, SkScalar endRadius,
799 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400800 int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500801 // See comment above for uintptr_t explanation
802 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
803 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
804
805 return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
806 colors, positions, count, mode,
807 flags, nullptr);
808 }), allow_raw_pointers());
809 function("_MakeTwoPointConicalGradientShader", optional_override([](
810 SkPoint start, SkScalar startRadius,
811 SkPoint end, SkScalar endRadius,
812 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400813 int count, SkTileMode mode, uint32_t flags,
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500814 const SimpleMatrix& lm)->sk_sp<SkShader> {
815 // See comment above for uintptr_t explanation
816 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
817 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
818
819 SkMatrix localMatrix = toSkMatrix(lm);
820 return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
821 colors, positions, count, mode,
822 flags, &localMatrix);
823 }), allow_raw_pointers());
824
Kevin Lubick543f3522019-03-08 10:04:28 -0500825#if SK_SUPPORT_GPU
826 class_<GrContext>("GrContext")
Kevin Lubickcd544662019-03-22 15:41:36 -0400827 .smart_ptr<sk_sp<GrContext>>("sk_sp<GrContext>")
828 .function("getResourceCacheLimitBytes", optional_override([](GrContext& self)->size_t {
829 int maxResources = 0;// ignored
830 size_t currMax = 0;
831 self.getResourceCacheLimits(&maxResources, &currMax);
832 return currMax;
833 }))
834 .function("getResourceCacheUsageBytes", optional_override([](GrContext& self)->size_t {
835 int usedResources = 0;// ignored
836 size_t currUsage = 0;
837 self.getResourceCacheUsage(&usedResources, &currUsage);
838 return currUsage;
839 }))
840 .function("setResourceCacheLimitBytes", optional_override([](GrContext& self, size_t maxResourceBytes)->void {
841 int maxResources = 0;
842 size_t currMax = 0; // ignored
843 self.getResourceCacheLimits(&maxResources, &currMax);
844 self.setResourceCacheLimits(maxResources, maxResourceBytes);
845 }));
Kevin Lubick543f3522019-03-08 10:04:28 -0500846#endif
847
Kevin Lubick6b921b72019-09-18 16:18:17 -0400848 class_<SkAnimatedImage>("SkAnimatedImage")
849 .smart_ptr<sk_sp<SkAnimatedImage>>("sk_sp<SkAnimatedImage>")
Kevin Lubick47bd9f12019-11-08 06:55:15 -0800850 .function("decodeNextFrame", &SkAnimatedImage::decodeNextFrame)
851 .function("getFrameCount", &SkAnimatedImage::getFrameCount)
Kevin Lubick6b921b72019-09-18 16:18:17 -0400852 .function("getRepetitionCount", &SkAnimatedImage::getRepetitionCount)
Kevin Lubick47bd9f12019-11-08 06:55:15 -0800853 .function("height", optional_override([](SkAnimatedImage& self)->int32_t {
854 return self.dimensions().height();
855 }))
856 .function("reset", &SkAnimatedImage::reset)
857 .function("width", optional_override([](SkAnimatedImage& self)->int32_t {
858 return self.dimensions().width();
859 }));
Kevin Lubick6b921b72019-09-18 16:18:17 -0400860
Kevin Lubick217056c2018-09-20 17:39:31 -0400861 class_<SkCanvas>("SkCanvas")
862 .constructor<>()
Kevin Lubickee91c072019-03-29 10:39:52 -0400863 .function("clear", &SkCanvas::clear)
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500864 .function("clipPath", select_overload<void (const SkPath&, SkClipOp, bool)>(&SkCanvas::clipPath))
Kevin Lubick47bd9f12019-11-08 06:55:15 -0800865 .function("clipRRect", optional_override([](SkCanvas& self, const SimpleRRect& r, SkClipOp op, bool doAntiAlias) {
Kevin Lubick6dbc4ed2019-10-22 09:43:34 -0400866 self.clipRRect(toRRect(r), op, doAntiAlias);
867 }))
Kevin Lubick52b9f372018-12-04 13:57:36 -0500868 .function("clipRect", select_overload<void (const SkRect&, SkClipOp, bool)>(&SkCanvas::clipRect))
869 .function("concat", optional_override([](SkCanvas& self, const SimpleMatrix& m) {
870 self.concat(toSkMatrix(m));
871 }))
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500872 .function("drawArc", &SkCanvas::drawArc)
Kevin Lubickee91c072019-03-29 10:39:52 -0400873 .function("_drawAtlas", optional_override([](SkCanvas& self,
874 const sk_sp<SkImage>& atlas, uintptr_t /* SkRSXform* */ xptr,
875 uintptr_t /* SkRect* */ rptr, uintptr_t /* SkColor* */ cptr, int count,
876 SkBlendMode mode, const SkPaint* paint)->void {
877 // See comment above for uintptr_t explanation
878 const SkRSXform* dstXforms = reinterpret_cast<const SkRSXform*>(xptr);
879 const SkRect* srcRects = reinterpret_cast<const SkRect*>(rptr);
880 const SkColor* colors = nullptr;
881 if (cptr) {
882 colors = reinterpret_cast<const SkColor*>(cptr);
883 }
884 self.drawAtlas(atlas, dstXforms, srcRects, colors, count, mode, nullptr, paint);
885 }), allow_raw_pointers())
Kevin Lubicke384df42019-08-26 15:48:09 -0400886 .function("drawCircle", select_overload<void (SkScalar, SkScalar, SkScalar, const SkPaint& paint)>(&SkCanvas::drawCircle))
Kevin Lubick6dbc4ed2019-10-22 09:43:34 -0400887 .function("drawColor", &SkCanvas::drawColor)
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400888 .function("drawDRRect",optional_override([](SkCanvas& self, const SimpleRRect& o, const SimpleRRect& i, const SkPaint& paint) {
889 self.drawDRRect(toRRect(o), toRRect(i), paint);
890 }))
Kevin Lubick6b921b72019-09-18 16:18:17 -0400891 .function("drawAnimatedImage", optional_override([](SkCanvas& self, sk_sp<SkAnimatedImage>& aImg,
892 SkScalar x, SkScalar y)->void {
893 self.drawDrawable(aImg.get(), x, y);
894 }), allow_raw_pointers())
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500895 .function("drawImage", select_overload<void (const sk_sp<SkImage>&, SkScalar, SkScalar, const SkPaint*)>(&SkCanvas::drawImage), allow_raw_pointers())
896 .function("drawImageRect", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
897 SkRect src, SkRect dst,
898 const SkPaint* paint, bool fastSample)->void {
899 self.drawImageRect(image, src, dst, paint,
900 fastSample ? SkCanvas::kFast_SrcRectConstraint :
901 SkCanvas::kStrict_SrcRectConstraint);
902 }), allow_raw_pointers())
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500903 .function("drawLine", select_overload<void (SkScalar, SkScalar, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawLine))
904 .function("drawOval", &SkCanvas::drawOval)
Kevin Lubick217056c2018-09-20 17:39:31 -0400905 .function("drawPaint", &SkCanvas::drawPaint)
Kevin Lubick369f6a52019-10-03 11:22:08 -0400906#ifdef SK_INCLUDE_PARAGRAPH
907 .function("drawParagraph", optional_override([](SkCanvas& self, skia::textlayout::Paragraph* p,
908 SkScalar x, SkScalar y) {
909 p->paint(&self, x, y);
910 }), allow_raw_pointers())
911#endif
Kevin Lubick217056c2018-09-20 17:39:31 -0400912 .function("drawPath", &SkCanvas::drawPath)
Kevin Lubickcc13fd32019-04-05 13:00:01 -0400913 // Of note, picture is *not* what is colloquially thought of as a "picture", what we call
914 // a bitmap. An SkPicture is a series of draw commands.
915 .function("drawPicture", select_overload<void (const sk_sp<SkPicture>&)>(&SkCanvas::drawPicture))
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400916 .function("drawRRect",optional_override([](SkCanvas& self, const SimpleRRect& r, const SkPaint& paint) {
917 self.drawRRect(toRRect(r), paint);
918 }))
Kevin Lubick217056c2018-09-20 17:39:31 -0400919 .function("drawRect", &SkCanvas::drawRect)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500920 .function("drawRoundRect", &SkCanvas::drawRoundRect)
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500921 .function("drawShadow", optional_override([](SkCanvas& self, const SkPath& path,
922 const SkPoint3& zPlaneParams,
923 const SkPoint3& lightPos, SkScalar lightRadius,
Kevin Lubickee91c072019-03-29 10:39:52 -0400924 SkColor ambientColor, SkColor spotColor,
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500925 uint32_t flags) {
926 SkShadowUtils::DrawShadow(&self, path, zPlaneParams, lightPos, lightRadius,
Kevin Lubickee91c072019-03-29 10:39:52 -0400927 ambientColor, spotColor, flags);
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500928 }))
Kevin Lubick61887c72019-09-26 13:20:50 -0400929#ifndef SK_NO_FONTS
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500930 .function("_drawShapedText", &drawShapedText)
Kevin Lubickec4903d2019-01-14 08:36:08 -0500931 .function("_drawSimpleText", optional_override([](SkCanvas& self, uintptr_t /* char* */ sptr,
932 size_t len, SkScalar x, SkScalar y, const SkFont& font,
933 const SkPaint& paint) {
934 // See comment above for uintptr_t explanation
935 const char* str = reinterpret_cast<const char*>(sptr);
936
937 self.drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
Kevin Lubick217056c2018-09-20 17:39:31 -0400938 }))
Kevin Lubickec4903d2019-01-14 08:36:08 -0500939 .function("drawTextBlob", select_overload<void (const sk_sp<SkTextBlob>&, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawTextBlob))
Kevin Lubick61887c72019-09-26 13:20:50 -0400940#endif
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400941 .function("drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices))
Kevin Lubick217056c2018-09-20 17:39:31 -0400942 .function("flush", &SkCanvas::flush)
Kevin Lubicke384df42019-08-26 15:48:09 -0400943 .function("getSaveCount", &SkCanvas::getSaveCount)
Kevin Lubick5d5723c2018-12-07 10:09:11 -0500944 .function("getTotalMatrix", optional_override([](const SkCanvas& self)->SimpleMatrix {
945 SkMatrix m = self.getTotalMatrix();
946 return toSimpleSkMatrix(m);
947 }))
Kevin Lubick543f3522019-03-08 10:04:28 -0500948 .function("makeSurface", optional_override([](SkCanvas& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
949 return self.makeSurface(toSkImageInfo(sii), nullptr);
950 }), allow_raw_pointers())
Kevin Lubick52b9f372018-12-04 13:57:36 -0500951 .function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
952 uintptr_t /* uint8_t* */ pPtr,
953 size_t dstRowBytes, int srcX, int srcY) {
954 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
955 SkImageInfo dstInfo = toSkImageInfo(di);
956
957 return self.readPixels(dstInfo, pixels, dstRowBytes, srcX, srcY);
958 }))
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500959 .function("restore", &SkCanvas::restore)
Kevin Lubickb3574c92019-03-06 08:25:36 -0500960 .function("restoreToCount", &SkCanvas::restoreToCount)
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400961 .function("rotate", select_overload<void (SkScalar, SkScalar, SkScalar)>(&SkCanvas::rotate))
Kevin Lubick217056c2018-09-20 17:39:31 -0400962 .function("save", &SkCanvas::save)
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400963 // 2 params
Kevin Lubickb3574c92019-03-06 08:25:36 -0500964 .function("saveLayer", select_overload<int (const SkRect&, const SkPaint*)>(&SkCanvas::saveLayer),
965 allow_raw_pointers())
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400966 // 3 params (effectively with SaveLayerRec, but no bounds)
967 .function("saveLayer", saveLayerRec, allow_raw_pointers())
968 // 4 params (effectively with SaveLayerRec)
969 .function("saveLayer", saveLayerRecBounds, allow_raw_pointers())
970
Kevin Lubick006a6f32018-10-19 14:34:34 -0400971 .function("scale", &SkCanvas::scale)
Kevin Lubick006a6f32018-10-19 14:34:34 -0400972 .function("skew", &SkCanvas::skew)
Kevin Lubick52b9f372018-12-04 13:57:36 -0500973 .function("translate", &SkCanvas::translate)
974 .function("_writePixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
975 uintptr_t /* uint8_t* */ pPtr,
976 size_t srcRowBytes, int dstX, int dstY) {
977 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
978 SkImageInfo dstInfo = toSkImageInfo(di);
979
980 return self.writePixels(dstInfo, pixels, srcRowBytes, dstX, dstY);
Kevin Lubick369f6a52019-10-03 11:22:08 -0400981 }));
Kevin Lubick217056c2018-09-20 17:39:31 -0400982
Kevin Lubickd3729342019-09-12 11:11:25 -0400983 class_<SkColorFilter>("SkColorFilter")
984 .smart_ptr<sk_sp<SkColorFilter>>("sk_sp<SkColorFilter>>")
985 .class_function("MakeBlend", &SkColorFilters::Blend)
986 .class_function("MakeCompose", &SkColorFilters::Compose)
987 .class_function("MakeLerp", &SkColorFilters::Lerp)
988 .class_function("MakeLinearToSRGBGamma", &SkColorFilters::LinearToSRGBGamma)
989 .class_function("_makeMatrix", optional_override([](uintptr_t /* float* */ fPtr) {
990 float* twentyFloats = reinterpret_cast<float*>(fPtr);
991 return SkColorFilters::Matrix(twentyFloats);
992 }))
993 .class_function("MakeSRGBToLinearGamma", &SkColorFilters::SRGBToLinearGamma);
994
Kevin Lubick217056c2018-09-20 17:39:31 -0400995 class_<SkData>("SkData")
996 .smart_ptr<sk_sp<SkData>>("sk_sp<SkData>>")
997 .function("size", &SkData::size);
998
Kevin Lubick6b921b72019-09-18 16:18:17 -0400999 class_<SkDrawable>("SkDrawable")
1000 .smart_ptr<sk_sp<SkDrawable>>("sk_sp<SkDrawable>>");
1001
Kevin Lubick61887c72019-09-26 13:20:50 -04001002#ifndef SK_NO_FONTS
Kevin Lubick35ac0382019-01-02 15:13:57 -05001003 class_<SkFont>("SkFont")
1004 .constructor<>()
1005 .constructor<sk_sp<SkTypeface>>()
1006 .constructor<sk_sp<SkTypeface>, SkScalar>()
1007 .constructor<sk_sp<SkTypeface>, SkScalar, SkScalar, SkScalar>()
1008 .function("getScaleX", &SkFont::getScaleX)
1009 .function("getSize", &SkFont::getSize)
1010 .function("getSkewX", &SkFont::getSkewX)
1011 .function("getTypeface", &SkFont::getTypeface, allow_raw_pointers())
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001012 .function("_getWidths", optional_override([](SkFont& self, uintptr_t /* char* */ sptr,
1013 size_t strLen, size_t expectedCodePoints,
1014 uintptr_t /* SkScalar* */ wptr) -> bool {
1015 char* str = reinterpret_cast<char*>(sptr);
1016 SkScalar* widths = reinterpret_cast<SkScalar*>(wptr);
1017
1018 SkGlyphID* glyphStorage = new SkGlyphID[expectedCodePoints];
1019 int actualCodePoints = self.textToGlyphs(str, strLen, SkTextEncoding::kUTF8,
1020 glyphStorage, expectedCodePoints);
1021 if (actualCodePoints != expectedCodePoints) {
1022 SkDebugf("Actually %d glyphs, expected only %d\n",
1023 actualCodePoints, expectedCodePoints);
1024 return false;
1025 }
1026
1027 self.getWidths(glyphStorage, actualCodePoints, widths);
1028 delete[] glyphStorage;
1029 return true;
1030 }))
Kevin Lubick35ac0382019-01-02 15:13:57 -05001031 .function("measureText", optional_override([](SkFont& self, std::string text) {
1032 // TODO(kjlubick): This does not work well for non-ascii
1033 // Need to maybe add a helper in interface.js that supports UTF-8
1034 // Otherwise, go with std::wstring and set UTF-32 encoding.
1035 return self.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
1036 }))
1037 .function("setScaleX", &SkFont::setScaleX)
1038 .function("setSize", &SkFont::setSize)
1039 .function("setSkewX", &SkFont::setSkewX)
1040 .function("setTypeface", &SkFont::setTypeface, allow_raw_pointers());
1041
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -05001042 class_<ShapedText>("ShapedText")
1043 .constructor<ShapedTextOpts>()
1044 .function("getBounds", &ShapedText::getBounds);
1045
Kevin Lubickddd0a332018-12-12 10:35:13 -05001046 class_<SkFontMgr>("SkFontMgr")
1047 .smart_ptr<sk_sp<SkFontMgr>>("sk_sp<SkFontMgr>")
Kevin Lubick61887c72019-09-26 13:20:50 -04001048 .class_function("_fromData", optional_override([](uintptr_t /* uint8_t** */ dPtr,
1049 uintptr_t /* size_t* */ sPtr,
1050 int numFonts)->sk_sp<SkFontMgr> {
1051 // See comment above for uintptr_t explanation
1052 auto datas = reinterpret_cast<const uint8_t**>(dPtr);
1053 auto sizes = reinterpret_cast<const size_t*>(sPtr);
1054
1055 return SkFontMgr_New_Custom_Data(datas, sizes, numFonts);
1056 }), allow_raw_pointers())
Kevin Lubickddd0a332018-12-12 10:35:13 -05001057 .class_function("RefDefault", &SkFontMgr::RefDefault)
1058#ifdef SK_DEBUG
1059 .function("dumpFamilies", optional_override([](SkFontMgr& self) {
1060 int numFam = self.countFamilies();
Kevin Lubick61887c72019-09-26 13:20:50 -04001061 SkDebugf("There are %d font families\n", numFam);
Kevin Lubickddd0a332018-12-12 10:35:13 -05001062 for (int i = 0 ; i< numFam; i++) {
1063 SkString s;
1064 self.getFamilyName(i, &s);
Kevin Lubick61887c72019-09-26 13:20:50 -04001065 SkDebugf("\t%s\n", s.c_str());
Kevin Lubickddd0a332018-12-12 10:35:13 -05001066 }
1067 }))
1068#endif
1069 .function("countFamilies", &SkFontMgr::countFamilies)
1070 .function("_makeTypefaceFromData", optional_override([](SkFontMgr& self,
1071 uintptr_t /* uint8_t* */ fPtr,
1072 int flen)->sk_sp<SkTypeface> {
1073 // See comment above for uintptr_t explanation
1074 uint8_t* font = reinterpret_cast<uint8_t*>(fPtr);
1075 sk_sp<SkData> fontData = SkData::MakeFromMalloc(font, flen);
1076
1077 return self.makeFromData(fontData);
1078 }), allow_raw_pointers());
Kevin Lubick61887c72019-09-26 13:20:50 -04001079#endif
Kevin Lubickddd0a332018-12-12 10:35:13 -05001080
Kevin Lubick217056c2018-09-20 17:39:31 -04001081 class_<SkImage>("SkImage")
1082 .smart_ptr<sk_sp<SkImage>>("sk_sp<SkImage>")
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001083 .function("height", &SkImage::height)
1084 .function("width", &SkImage::width)
Alexander Khovansky3e119332018-11-15 02:01:19 +03001085 .function("_encodeToData", select_overload<sk_sp<SkData>()const>(&SkImage::encodeToData))
Kevin Lubicka064c282019-04-04 09:28:53 -04001086 .function("_encodeToDataWithFormat", select_overload<sk_sp<SkData>(SkEncodedImageFormat encodedImageFormat, int quality)const>(&SkImage::encodeToData))
1087 // Allow localMatrix to be optional, so we have 2 declarations of these shaders
1088 .function("_makeShader", optional_override([](sk_sp<SkImage> self,
1089 SkTileMode tx, SkTileMode ty)->sk_sp<SkShader> {
1090 return self->makeShader(tx, ty, nullptr);
1091 }), allow_raw_pointers())
1092 .function("_makeShader", optional_override([](sk_sp<SkImage> self,
1093 SkTileMode tx, SkTileMode ty,
1094 const SimpleMatrix& lm)->sk_sp<SkShader> {
1095 SkMatrix localMatrix = toSkMatrix(lm);
1096
1097 return self->makeShader(tx, ty, &localMatrix);
Kevin Lubickd6b32ed2019-05-06 13:04:03 -04001098 }), allow_raw_pointers())
1099 .function("_readPixels", optional_override([](sk_sp<SkImage> self,
1100 SimpleImageInfo sii, uintptr_t /* uint8_t* */ pPtr,
1101 size_t dstRowBytes, int srcX, int srcY)->bool {
1102 // See comment above for uintptr_t explanation
1103 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1104 SkImageInfo ii = toSkImageInfo(sii);
1105
1106 return self->readPixels(ii, pixels, dstRowBytes, srcX, srcY);
Kevin Lubicka064c282019-04-04 09:28:53 -04001107 }), allow_raw_pointers());
Kevin Lubick217056c2018-09-20 17:39:31 -04001108
Kevin Lubick15b40232019-10-29 09:55:39 -04001109 class_<SkImageFilter>("SkImageFilter")
1110 .smart_ptr<sk_sp<SkImageFilter>>("sk_sp<SkImageFilter>")
1111 .class_function("MakeBlur", optional_override([](SkScalar sigmaX, SkScalar sigmaY,
1112 SkTileMode tileMode, sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1113 // Emscripten does not like default args nor SkIRect* much
1114 return SkImageFilters::Blur(sigmaX, sigmaY, tileMode, input);
1115 }))
1116 .class_function("MakeColorFilter", optional_override([](sk_sp<SkColorFilter> cf,
1117 sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1118 // Emscripten does not like default args nor SkIRect* much
1119 return SkImageFilters::ColorFilter(cf, input);
1120 }))
1121 .class_function("MakeCompose", &SkImageFilters::Compose);
1122
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001123 class_<SkMaskFilter>("SkMaskFilter")
Kevin Lubick15b40232019-10-29 09:55:39 -04001124 .smart_ptr<sk_sp<SkMaskFilter>>("sk_sp<SkMaskFilter>")
1125 .class_function("MakeBlur", optional_override([](SkBlurStyle style, SkScalar sigma, bool respectCTM)->sk_sp<SkMaskFilter> {
1126 // Adds a little helper because emscripten doesn't expose default params.
1127 return SkMaskFilter::MakeBlur(style, sigma, respectCTM);
1128 }), allow_raw_pointers());
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001129
Kevin Lubick217056c2018-09-20 17:39:31 -04001130 class_<SkPaint>("SkPaint")
1131 .constructor<>()
1132 .function("copy", optional_override([](const SkPaint& self)->SkPaint {
1133 SkPaint p(self);
1134 return p;
1135 }))
Kevin Lubick12c0e502018-11-28 12:51:56 -05001136 .function("getBlendMode", &SkPaint::getBlendMode)
Kevin Lubickee91c072019-03-29 10:39:52 -04001137 .function("getColor", &SkPaint::getColor)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001138 .function("getFilterQuality", &SkPaint::getFilterQuality)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001139 .function("getStrokeCap", &SkPaint::getStrokeCap)
1140 .function("getStrokeJoin", &SkPaint::getStrokeJoin)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001141 .function("getStrokeMiter", &SkPaint::getStrokeMiter)
1142 .function("getStrokeWidth", &SkPaint::getStrokeWidth)
Kevin Lubick217056c2018-09-20 17:39:31 -04001143 .function("setAntiAlias", &SkPaint::setAntiAlias)
Kevin Lubick12c0e502018-11-28 12:51:56 -05001144 .function("setBlendMode", &SkPaint::setBlendMode)
Mike Reeddc2b98f2019-05-20 11:47:49 -04001145 .function("setColor", optional_override([](SkPaint& self, SkColor c) {
1146 self.setColor(c);
1147 }))
1148 .function("setColorf", optional_override([](SkPaint& self,
1149 float r, float g, float b, float a) {
1150 self.setColor({r, g, b, a});
1151 }))
Kevin Lubickd3729342019-09-12 11:11:25 -04001152 .function("setColorFilter", &SkPaint::setColorFilter)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001153 .function("setFilterQuality", &SkPaint::setFilterQuality)
Kevin Lubick15b40232019-10-29 09:55:39 -04001154 .function("setImageFilter", &SkPaint::setImageFilter)
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001155 .function("setMaskFilter", &SkPaint::setMaskFilter)
Kevin Lubick217056c2018-09-20 17:39:31 -04001156 .function("setPathEffect", &SkPaint::setPathEffect)
1157 .function("setShader", &SkPaint::setShader)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001158 .function("setStrokeCap", &SkPaint::setStrokeCap)
1159 .function("setStrokeJoin", &SkPaint::setStrokeJoin)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001160 .function("setStrokeMiter", &SkPaint::setStrokeMiter)
1161 .function("setStrokeWidth", &SkPaint::setStrokeWidth)
Kevin Lubickec4903d2019-01-14 08:36:08 -05001162 .function("setStyle", &SkPaint::setStyle);
Kevin Lubick217056c2018-09-20 17:39:31 -04001163
1164 class_<SkPathEffect>("SkPathEffect")
1165 .smart_ptr<sk_sp<SkPathEffect>>("sk_sp<SkPathEffect>");
1166
Kevin Lubick217056c2018-09-20 17:39:31 -04001167 class_<SkPath>("SkPath")
1168 .constructor<>()
1169 .constructor<const SkPath&>()
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001170 .function("_addArc", &ApplyAddArc)
Kevin Lubick217056c2018-09-20 17:39:31 -04001171 // interface.js has 3 overloads of addPath
Kevin Lubicke384df42019-08-26 15:48:09 -04001172 .function("_addOval", &ApplyAddOval)
Kevin Lubick217056c2018-09-20 17:39:31 -04001173 .function("_addPath", &ApplyAddPath)
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001174 // interface.js has 4 overloads of addRect
1175 .function("_addRect", &ApplyAddRect)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001176 // interface.js has 4 overloads of addRoundRect
1177 .function("_addRoundRect", &ApplyAddRoundRect)
Kevin Lubick217056c2018-09-20 17:39:31 -04001178 .function("_arcTo", &ApplyArcTo)
Kevin Lubick1646e7d2018-12-07 13:03:08 -05001179 .function("_arcTo", &ApplyArcToAngle)
Kevin Lubick79b71342019-11-01 14:36:52 -04001180 .function("_arcTo", &ApplyArcToArcSize)
Kevin Lubick217056c2018-09-20 17:39:31 -04001181 .function("_close", &ApplyClose)
1182 .function("_conicTo", &ApplyConicTo)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001183 .function("countPoints", &SkPath::countPoints)
Kevin Lubick1646e7d2018-12-07 13:03:08 -05001184 .function("contains", &SkPath::contains)
Kevin Lubick217056c2018-09-20 17:39:31 -04001185 .function("_cubicTo", &ApplyCubicTo)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001186 .function("getPoint", &SkPath::getPoint)
Kevin Lubick1646e7d2018-12-07 13:03:08 -05001187 .function("isEmpty", &SkPath::isEmpty)
Kevin Lubick2b79d1c2018-12-14 16:10:38 -05001188 .function("isVolatile", &SkPath::isVolatile)
Kevin Lubick217056c2018-09-20 17:39:31 -04001189 .function("_lineTo", &ApplyLineTo)
1190 .function("_moveTo", &ApplyMoveTo)
Kevin Lubick79b71342019-11-01 14:36:52 -04001191 .function("_quadTo", &ApplyQuadTo)
1192 .function("_rArcTo", &ApplyRArcToArcSize)
1193 .function("_rConicTo", &ApplyRConicTo)
1194 .function("_rCubicTo", &ApplyRCubicTo)
1195 .function("_rLineTo", &ApplyRLineTo)
1196 .function("_rMoveTo", &ApplyRMoveTo)
1197 .function("_rQuadTo", &ApplyRQuadTo)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001198 .function("reset", &ApplyReset)
1199 .function("rewind", &ApplyRewind)
Kevin Lubick2b79d1c2018-12-14 16:10:38 -05001200 .function("setIsVolatile", &SkPath::setIsVolatile)
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001201 .function("_transform", select_overload<void(SkPath&, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar)>(&ApplyTransform))
Kevin Lubick217056c2018-09-20 17:39:31 -04001202
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001203 // PathEffects
1204 .function("_dash", &ApplyDash)
1205 .function("_trim", &ApplyTrim)
1206 .function("_stroke", &ApplyStroke)
1207
1208 // PathOps
1209 .function("_simplify", &ApplySimplify)
1210 .function("_op", &ApplyPathOp)
1211
1212 // Exporting
1213 .function("toSVGString", &ToSVGString)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001214 .function("toCmds", &ToCmds)
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001215
Kevin Lubick217056c2018-09-20 17:39:31 -04001216 .function("setFillType", &SkPath::setFillType)
1217 .function("getFillType", &SkPath::getFillType)
1218 .function("getBounds", &SkPath::getBounds)
1219 .function("computeTightBounds", &SkPath::computeTightBounds)
1220 .function("equals", &Equals)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001221 .function("copy", &CopyPath)
1222#ifdef SK_DEBUG
1223 .function("dump", select_overload<void() const>(&SkPath::dump))
1224 .function("dumpHex", select_overload<void() const>(&SkPath::dumpHex))
1225#endif
1226 ;
Kevin Lubick217056c2018-09-20 17:39:31 -04001227
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001228 class_<SkPathMeasure>("SkPathMeasure")
1229 .constructor<const SkPath&, bool, SkScalar>()
1230 .function("getLength", &SkPathMeasure::getLength)
1231 .function("getPosTan", optional_override([](SkPathMeasure& self,
1232 SkScalar distance) -> PosTan {
1233 SkPoint p{0, 0};
1234 SkVector v{0, 0};
1235 if (!self.getPosTan(distance, &p, &v)) {
1236 SkDebugf("zero-length path in getPosTan\n");
1237 }
1238 return PosTan{p.x(), p.y(), v.x(), v.y()};
1239 }))
1240 .function("isClosed", &SkPathMeasure::isClosed)
1241 .function("nextContour", &SkPathMeasure::nextContour);
1242
Kevin Lubickcc13fd32019-04-05 13:00:01 -04001243 class_<SkPictureRecorder>("SkPictureRecorder")
1244 .constructor<>()
1245 .function("beginRecording", optional_override([](SkPictureRecorder& self,
1246 const SkRect& bounds) -> SkCanvas* {
1247 return self.beginRecording(bounds, nullptr, 0);
1248 }), allow_raw_pointers())
1249 .function("finishRecordingAsPicture", optional_override([](SkPictureRecorder& self)
1250 -> sk_sp<SkPicture> {
1251 return self.finishRecordingAsPicture(0);
1252 }), allow_raw_pointers());
1253
1254 class_<SkPicture>("SkPicture")
1255 .smart_ptr<sk_sp<SkPicture>>("sk_sp<SkPicture>")
1256 // The serialized format of an SkPicture (informally called an "skp"), is not something
1257 // that clients should ever rely on. It is useful when filing bug reports, but that's
1258 // about it. The format may change at anytime and no promises are made for backwards
1259 // or forward compatibility.
1260 .function("DEBUGONLY_serialize", optional_override([](SkPicture& self) -> sk_sp<SkData> {
1261 // Emscripten doesn't play well with optional arguments, which we don't
1262 // want to expose anyway.
1263 return self.serialize();
1264 }), allow_raw_pointers());
1265
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001266 class_<SkShader>("SkShader")
1267 .smart_ptr<sk_sp<SkShader>>("sk_sp<SkShader>");
1268
Kevin Lubick217056c2018-09-20 17:39:31 -04001269 class_<SkSurface>("SkSurface")
1270 .smart_ptr<sk_sp<SkSurface>>("sk_sp<SkSurface>")
Greg Danielbae71212019-03-01 15:24:35 -05001271 .function("_flush", select_overload<void()>(&SkSurface::flush))
Kevin Lubick543f3522019-03-08 10:04:28 -05001272 .function("getCanvas", &SkSurface::getCanvas, allow_raw_pointers())
1273 .function("height", &SkSurface::height)
Mike Reed114bde82018-11-21 09:12:09 -05001274 .function("makeImageSnapshot", select_overload<sk_sp<SkImage>()>(&SkSurface::makeImageSnapshot))
1275 .function("makeImageSnapshot", select_overload<sk_sp<SkImage>(const SkIRect& bounds)>(&SkSurface::makeImageSnapshot))
Kevin Lubick543f3522019-03-08 10:04:28 -05001276 .function("makeSurface", optional_override([](SkSurface& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
1277 return self.makeSurface(toSkImageInfo(sii));
1278 }), allow_raw_pointers())
1279 .function("width", &SkSurface::width);
Kevin Lubick217056c2018-09-20 17:39:31 -04001280
Kevin Lubick61887c72019-09-26 13:20:50 -04001281#ifndef SK_NO_FONTS
Kevin Lubickec4903d2019-01-14 08:36:08 -05001282 class_<SkTextBlob>("SkTextBlob")
1283 .smart_ptr<sk_sp<SkTextBlob>>("sk_sp<SkTextBlob>>")
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001284 .class_function("_MakeFromRSXform", optional_override([](uintptr_t /* char* */ sptr,
1285 size_t strBtyes,
1286 uintptr_t /* SkRSXform* */ xptr,
1287 const SkFont& font,
1288 SkTextEncoding encoding)->sk_sp<SkTextBlob> {
1289 // See comment above for uintptr_t explanation
1290 const char* str = reinterpret_cast<const char*>(sptr);
1291 const SkRSXform* xforms = reinterpret_cast<const SkRSXform*>(xptr);
1292
1293 return SkTextBlob::MakeFromRSXform(str, strBtyes, xforms, font, encoding);
1294 }), allow_raw_pointers())
Kevin Lubick543f3522019-03-08 10:04:28 -05001295 .class_function("_MakeFromText", optional_override([](uintptr_t /* char* */ sptr,
1296 size_t len, const SkFont& font,
1297 SkTextEncoding encoding)->sk_sp<SkTextBlob> {
Kevin Lubickec4903d2019-01-14 08:36:08 -05001298 // See comment above for uintptr_t explanation
1299 const char* str = reinterpret_cast<const char*>(sptr);
1300 return SkTextBlob::MakeFromText(str, len, font, encoding);
1301 }), allow_raw_pointers());
1302
Kevin Lubickddd0a332018-12-12 10:35:13 -05001303 class_<SkTypeface>("SkTypeface")
1304 .smart_ptr<sk_sp<SkTypeface>>("sk_sp<SkTypeface>");
Kevin Lubick61887c72019-09-26 13:20:50 -04001305#endif
Kevin Lubickddd0a332018-12-12 10:35:13 -05001306
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001307 class_<SkVertices>("SkVertices")
1308 .smart_ptr<sk_sp<SkVertices>>("sk_sp<SkVertices>")
1309 .function("_applyBones", optional_override([](SkVertices& self, uintptr_t /* Bone* */ bptr, int boneCount)->sk_sp<SkVertices> {
1310 // See comment above for uintptr_t explanation
1311 const Bone* bones = reinterpret_cast<const Bone*>(bptr);
1312 return self.applyBones(bones, boneCount);
1313 }))
1314 .function("bounds", &SkVertices::bounds)
1315 .function("mode", &SkVertices::mode)
1316 .function("uniqueID", &SkVertices::uniqueID)
Kevin Lubick12c0e502018-11-28 12:51:56 -05001317#ifdef SK_DEBUG
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001318 .function("dumpPositions", optional_override([](SkVertices& self)->void {
1319 auto pos = self.positions();
1320 for(int i = 0; i< self.vertexCount(); i++) {
1321 SkDebugf("position[%d] = (%f, %f)\n", i, pos[i].x(), pos[i].y());
1322 }
1323 }))
Kevin Lubick12c0e502018-11-28 12:51:56 -05001324#endif
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001325 .function("vertexCount", &SkVertices::vertexCount);
1326
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001327 // Not intended to be called directly by clients
1328 class_<SkVertices::Builder>("_SkVerticesBuilder")
1329 .constructor<SkVertices::VertexMode, int, int, uint32_t>()
1330 .function("boneIndices", optional_override([](SkVertices::Builder& self)->uintptr_t /* BoneIndices* */{
1331 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1332 return reinterpret_cast<uintptr_t>(self.boneIndices());
1333 }))
1334 .function("boneWeights", optional_override([](SkVertices::Builder& self)->uintptr_t /* BoneWeights* */{
1335 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1336 return reinterpret_cast<uintptr_t>(self.boneWeights());
1337 }))
1338 .function("colors", optional_override([](SkVertices::Builder& self)->uintptr_t /* SkColor* */{
1339 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1340 return reinterpret_cast<uintptr_t>(self.colors());
1341 }))
1342 .function("detach", &SkVertices::Builder::detach)
1343 .function("indices", optional_override([](SkVertices::Builder& self)->uintptr_t /* uint16_t* */{
1344 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1345 return reinterpret_cast<uintptr_t>(self.indices());
1346 }))
1347 .function("positions", optional_override([](SkVertices::Builder& self)->uintptr_t /* SkPoint* */{
1348 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1349 return reinterpret_cast<uintptr_t>(self.positions());
1350 }))
1351 .function("texCoords", optional_override([](SkVertices::Builder& self)->uintptr_t /* SkPoint* */{
1352 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1353 return reinterpret_cast<uintptr_t>(self.texCoords());
1354 }));
1355
Kevin Lubickea905ec2018-11-30 14:05:58 -05001356 enum_<SkAlphaType>("AlphaType")
1357 .value("Opaque", SkAlphaType::kOpaque_SkAlphaType)
1358 .value("Premul", SkAlphaType::kPremul_SkAlphaType)
1359 .value("Unpremul", SkAlphaType::kUnpremul_SkAlphaType);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001360
1361 enum_<SkBlendMode>("BlendMode")
1362 .value("Clear", SkBlendMode::kClear)
1363 .value("Src", SkBlendMode::kSrc)
1364 .value("Dst", SkBlendMode::kDst)
1365 .value("SrcOver", SkBlendMode::kSrcOver)
1366 .value("DstOver", SkBlendMode::kDstOver)
1367 .value("SrcIn", SkBlendMode::kSrcIn)
1368 .value("DstIn", SkBlendMode::kDstIn)
1369 .value("SrcOut", SkBlendMode::kSrcOut)
1370 .value("DstOut", SkBlendMode::kDstOut)
1371 .value("SrcATop", SkBlendMode::kSrcATop)
1372 .value("DstATop", SkBlendMode::kDstATop)
1373 .value("Xor", SkBlendMode::kXor)
1374 .value("Plus", SkBlendMode::kPlus)
1375 .value("Modulate", SkBlendMode::kModulate)
1376 .value("Screen", SkBlendMode::kScreen)
1377 .value("Overlay", SkBlendMode::kOverlay)
1378 .value("Darken", SkBlendMode::kDarken)
1379 .value("Lighten", SkBlendMode::kLighten)
1380 .value("ColorDodge", SkBlendMode::kColorDodge)
1381 .value("ColorBurn", SkBlendMode::kColorBurn)
1382 .value("HardLight", SkBlendMode::kHardLight)
1383 .value("SoftLight", SkBlendMode::kSoftLight)
1384 .value("Difference", SkBlendMode::kDifference)
1385 .value("Exclusion", SkBlendMode::kExclusion)
1386 .value("Multiply", SkBlendMode::kMultiply)
1387 .value("Hue", SkBlendMode::kHue)
1388 .value("Saturation", SkBlendMode::kSaturation)
1389 .value("Color", SkBlendMode::kColor)
1390 .value("Luminosity", SkBlendMode::kLuminosity);
Kevin Lubick217056c2018-09-20 17:39:31 -04001391
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001392 enum_<SkBlurStyle>("BlurStyle")
1393 .value("Normal", SkBlurStyle::kNormal_SkBlurStyle)
1394 .value("Solid", SkBlurStyle::kSolid_SkBlurStyle)
1395 .value("Outer", SkBlurStyle::kOuter_SkBlurStyle)
1396 .value("Inner", SkBlurStyle::kInner_SkBlurStyle);
Kevin Lubick217056c2018-09-20 17:39:31 -04001397
Kevin Lubickeb2f6b02018-11-29 15:07:02 -05001398 enum_<SkClipOp>("ClipOp")
1399 .value("Difference", SkClipOp::kDifference)
1400 .value("Intersect", SkClipOp::kIntersect);
1401
Kevin Lubickea905ec2018-11-30 14:05:58 -05001402 enum_<SkColorType>("ColorType")
1403 .value("Alpha_8", SkColorType::kAlpha_8_SkColorType)
1404 .value("RGB_565", SkColorType::kRGB_565_SkColorType)
1405 .value("ARGB_4444", SkColorType::kARGB_4444_SkColorType)
1406 .value("RGBA_8888", SkColorType::kRGBA_8888_SkColorType)
1407 .value("RGB_888x", SkColorType::kRGB_888x_SkColorType)
1408 .value("BGRA_8888", SkColorType::kBGRA_8888_SkColorType)
1409 .value("RGBA_1010102", SkColorType::kRGBA_1010102_SkColorType)
1410 .value("RGB_101010x", SkColorType::kRGB_101010x_SkColorType)
1411 .value("Gray_8", SkColorType::kGray_8_SkColorType)
1412 .value("RGBA_F16", SkColorType::kRGBA_F16_SkColorType)
Robert Phillipsd470e1b2019-09-04 15:05:35 -04001413 .value("RGBA_F32", SkColorType::kRGBA_F32_SkColorType)
Robert Phillipsea1b30b2019-09-19 16:05:48 -04001414 .value("R8G8_unorm", SkColorType::kR8G8_unorm_SkColorType)
1415 .value("A16_unorm", SkColorType::kA16_unorm_SkColorType)
1416 .value("R16G16_unorm", SkColorType::kR16G16_unorm_SkColorType)
1417 .value("A16_float", SkColorType::kA16_float_SkColorType)
1418 .value("R16G16_float", SkColorType::kR16G16_float_SkColorType)
1419 .value("R16G16B16A16_unorm", SkColorType::kR16G16B16A16_unorm_SkColorType);
Kevin Lubickea905ec2018-11-30 14:05:58 -05001420
Kevin Lubick217056c2018-09-20 17:39:31 -04001421 enum_<SkPath::FillType>("FillType")
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001422 .value("Winding", SkPath::FillType::kWinding_FillType)
1423 .value("EvenOdd", SkPath::FillType::kEvenOdd_FillType)
1424 .value("InverseWinding", SkPath::FillType::kInverseWinding_FillType)
1425 .value("InverseEvenOdd", SkPath::FillType::kInverseEvenOdd_FillType);
1426
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001427 enum_<SkFilterQuality>("FilterQuality")
1428 .value("None", SkFilterQuality::kNone_SkFilterQuality)
1429 .value("Low", SkFilterQuality::kLow_SkFilterQuality)
1430 .value("Medium", SkFilterQuality::kMedium_SkFilterQuality)
1431 .value("High", SkFilterQuality::kHigh_SkFilterQuality);
1432
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001433 enum_<SkEncodedImageFormat>("ImageFormat")
1434 .value("PNG", SkEncodedImageFormat::kPNG)
1435 .value("JPEG", SkEncodedImageFormat::kJPEG);
1436
1437 enum_<SkPaint::Style>("PaintStyle")
1438 .value("Fill", SkPaint::Style::kFill_Style)
1439 .value("Stroke", SkPaint::Style::kStroke_Style)
1440 .value("StrokeAndFill", SkPaint::Style::kStrokeAndFill_Style);
1441
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001442 enum_<SkPathOp>("PathOp")
1443 .value("Difference", SkPathOp::kDifference_SkPathOp)
1444 .value("Intersect", SkPathOp::kIntersect_SkPathOp)
1445 .value("Union", SkPathOp::kUnion_SkPathOp)
1446 .value("XOR", SkPathOp::kXOR_SkPathOp)
1447 .value("ReverseDifference", SkPathOp::kReverseDifference_SkPathOp);
1448
Kevin Lubickb9db3902018-11-26 11:47:54 -05001449 enum_<SkPaint::Cap>("StrokeCap")
1450 .value("Butt", SkPaint::Cap::kButt_Cap)
1451 .value("Round", SkPaint::Cap::kRound_Cap)
1452 .value("Square", SkPaint::Cap::kSquare_Cap);
1453
1454 enum_<SkPaint::Join>("StrokeJoin")
1455 .value("Miter", SkPaint::Join::kMiter_Join)
1456 .value("Round", SkPaint::Join::kRound_Join)
1457 .value("Bevel", SkPaint::Join::kBevel_Join);
1458
Kevin Lubickec4903d2019-01-14 08:36:08 -05001459 enum_<SkTextEncoding>("TextEncoding")
1460 .value("UTF8", SkTextEncoding::kUTF8)
1461 .value("UTF16", SkTextEncoding::kUTF16)
1462 .value("UTF32", SkTextEncoding::kUTF32)
1463 .value("GlyphID", SkTextEncoding::kGlyphID);
Kevin Lubickb9db3902018-11-26 11:47:54 -05001464
Mike Reed5c5de212019-04-03 16:51:47 -04001465 enum_<SkTileMode>("TileMode")
1466 .value("Clamp", SkTileMode::kClamp)
1467 .value("Repeat", SkTileMode::kRepeat)
1468 .value("Mirror", SkTileMode::kMirror)
Mike Reed5c5de212019-04-03 16:51:47 -04001469 .value("Decal", SkTileMode::kDecal);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001470
1471 enum_<SkVertices::VertexMode>("VertexMode")
1472 .value("Triangles", SkVertices::VertexMode::kTriangles_VertexMode)
1473 .value("TrianglesStrip", SkVertices::VertexMode::kTriangleStrip_VertexMode)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001474 .value("TriangleFan", SkVertices::VertexMode::kTriangleFan_VertexMode);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001475
Kevin Lubick217056c2018-09-20 17:39:31 -04001476
1477 // A value object is much simpler than a class - it is returned as a JS
1478 // object and does not require delete().
1479 // https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#value-types
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -05001480 value_object<ShapedTextOpts>("ShapedTextOpts")
1481 .field("font", &ShapedTextOpts::font)
1482 .field("leftToRight", &ShapedTextOpts::leftToRight)
1483 .field("text", &ShapedTextOpts::text)
1484 .field("width", &ShapedTextOpts::width);
1485
Kevin Lubick217056c2018-09-20 17:39:31 -04001486 value_object<SkRect>("SkRect")
1487 .field("fLeft", &SkRect::fLeft)
1488 .field("fTop", &SkRect::fTop)
1489 .field("fRight", &SkRect::fRight)
1490 .field("fBottom", &SkRect::fBottom);
1491
Kevin Lubick2e5fe352019-09-03 12:59:06 -04001492 value_object<SimpleRRect>("SkRRect")
1493 .field("rect", &SimpleRRect::rect)
Kevin Lubick7d644e12019-09-11 14:22:22 -04001494 .field("rx1", &SimpleRRect::rx1)
1495 .field("ry1", &SimpleRRect::ry1)
1496 .field("rx2", &SimpleRRect::rx2)
1497 .field("ry2", &SimpleRRect::ry2)
1498 .field("rx3", &SimpleRRect::rx3)
1499 .field("ry3", &SimpleRRect::ry3)
1500 .field("rx4", &SimpleRRect::rx4)
1501 .field("ry4", &SimpleRRect::ry4);
Kevin Lubick2e5fe352019-09-03 12:59:06 -04001502
Mike Reed114bde82018-11-21 09:12:09 -05001503 value_object<SkIRect>("SkIRect")
1504 .field("fLeft", &SkIRect::fLeft)
1505 .field("fTop", &SkIRect::fTop)
1506 .field("fRight", &SkIRect::fRight)
1507 .field("fBottom", &SkIRect::fBottom);
1508
Kevin Lubick50f377e2019-09-11 15:23:00 -04001509 value_object<TonalColors>("TonalColors")
1510 .field("ambient", &TonalColors::ambientColor)
1511 .field("spot", &TonalColors::spotColor);
1512
Kevin Lubickea905ec2018-11-30 14:05:58 -05001513 value_object<SimpleImageInfo>("SkImageInfo")
1514 .field("width", &SimpleImageInfo::width)
1515 .field("height", &SimpleImageInfo::height)
1516 .field("colorType", &SimpleImageInfo::colorType)
1517 .field("alphaType", &SimpleImageInfo::alphaType);
1518
Kevin Lubick217056c2018-09-20 17:39:31 -04001519 // SkPoints can be represented by [x, y]
1520 value_array<SkPoint>("SkPoint")
1521 .element(&SkPoint::fX)
1522 .element(&SkPoint::fY);
1523
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001524 // SkPoint3s can be represented by [x, y, z]
1525 value_array<SkPoint3>("SkPoint3")
1526 .element(&SkPoint3::fX)
1527 .element(&SkPoint3::fY)
1528 .element(&SkPoint3::fZ);
1529
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001530 // PosTan can be represented by [px, py, tx, ty]
1531 value_array<PosTan>("PosTan")
1532 .element(&PosTan::px)
1533 .element(&PosTan::py)
1534 .element(&PosTan::tx)
1535 .element(&PosTan::ty);
1536
Kevin Lubick217056c2018-09-20 17:39:31 -04001537 // {"w": Number, "h", Number}
1538 value_object<SkSize>("SkSize")
1539 .field("w", &SkSize::fWidth)
1540 .field("h", &SkSize::fHeight);
1541
1542 value_object<SkISize>("SkISize")
1543 .field("w", &SkISize::fWidth)
1544 .field("h", &SkISize::fHeight);
1545
Kevin Lubickec4903d2019-01-14 08:36:08 -05001546 value_object<StrokeOpts>("StrokeOpts")
1547 .field("width", &StrokeOpts::width)
1548 .field("miter_limit", &StrokeOpts::miter_limit)
1549 .field("join", &StrokeOpts::join)
1550 .field("cap", &StrokeOpts::cap)
1551 .field("precision", &StrokeOpts::precision);
1552
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001553 // Allows clients to supply a 1D array of 9 elements and the bindings
1554 // will automatically turn it into a 3x3 2D matrix.
1555 // e.g. path.transform([0,1,2,3,4,5,6,7,8])
1556 // This is likely simpler for the client than exposing SkMatrix
1557 // directly and requiring them to do a lot of .delete().
1558 value_array<SimpleMatrix>("SkMatrix")
1559 .element(&SimpleMatrix::scaleX)
1560 .element(&SimpleMatrix::skewX)
1561 .element(&SimpleMatrix::transX)
1562
1563 .element(&SimpleMatrix::skewY)
1564 .element(&SimpleMatrix::scaleY)
1565 .element(&SimpleMatrix::transY)
1566
1567 .element(&SimpleMatrix::pers0)
1568 .element(&SimpleMatrix::pers1)
1569 .element(&SimpleMatrix::pers2);
1570
Kevin Lubickee91c072019-03-29 10:39:52 -04001571 constant("TRANSPARENT", SK_ColorTRANSPARENT);
1572 constant("RED", SK_ColorRED);
1573 constant("BLUE", SK_ColorBLUE);
1574 constant("YELLOW", SK_ColorYELLOW);
1575 constant("CYAN", SK_ColorCYAN);
1576 constant("BLACK", SK_ColorBLACK);
1577 constant("WHITE", SK_ColorWHITE);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001578 // TODO(?)
1579
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001580 constant("MOVE_VERB", MOVE);
1581 constant("LINE_VERB", LINE);
1582 constant("QUAD_VERB", QUAD);
1583 constant("CONIC_VERB", CONIC);
1584 constant("CUBIC_VERB", CUBIC);
1585 constant("CLOSE_VERB", CLOSE);
Kevin Lubick77d9b5c2019-10-29 10:48:26 -04001586
1587 constant("SaveLayerInitWithPrevious", SkCanvas::SaveLayerFlagsSet::kInitWithPrevious_SaveLayerFlag);
1588 constant("SaveLayerF16ColorType", SkCanvas::SaveLayerFlagsSet::kF16ColorType);
1589
Kevin Lubick217056c2018-09-20 17:39:31 -04001590}