blob: 2f42b6fa25c47c3f0f40c479626667f418537900 [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"
Florin Malita0d603d82019-11-25 13:45:28 -050055#include "src/core/SkResourceCache.h"
Kevin Lubickb5ae3b52018-11-03 07:51:19 -040056
Kevin Lubick217056c2018-09-20 17:39:31 -040057#include <iostream>
58#include <string>
Kevin Lubick217056c2018-09-20 17:39:31 -040059
Mike Kleinc0bd9f92019-04-23 12:05:21 -050060#include "modules/canvaskit/WasmAliases.h"
Kevin Lubick217056c2018-09-20 17:39:31 -040061#include <emscripten.h>
62#include <emscripten/bind.h>
Kevin Lubick46839422019-01-03 14:27:27 -050063
Kevin Lubick53965c92018-10-11 08:51:55 -040064#if SK_SUPPORT_GPU
Mike Kleinc0bd9f92019-04-23 12:05:21 -050065#include "include/gpu/GrBackendSurface.h"
66#include "include/gpu/GrContext.h"
67#include "include/gpu/gl/GrGLInterface.h"
68#include "include/gpu/gl/GrGLTypes.h"
Kevin Lubick3f67f412019-03-11 16:11:58 -040069
Kevin Lubick53965c92018-10-11 08:51:55 -040070#include <GL/gl.h>
Kevin Lubick217056c2018-09-20 17:39:31 -040071#include <emscripten/html5.h>
Kevin Lubick53965c92018-10-11 08:51:55 -040072#endif
Kevin Lubick217056c2018-09-20 17:39:31 -040073
Kevin Lubick369f6a52019-10-03 11:22:08 -040074#ifdef SK_INCLUDE_PARAGRAPH
75#include "modules/skparagraph/include/Paragraph.h"
76#endif
Kevin Lubickb5ae3b52018-11-03 07:51:19 -040077// Aliases for less typing
78using BoneIndices = SkVertices::BoneIndices;
79using BoneWeights = SkVertices::BoneWeights;
80using Bone = SkVertices::Bone;
Kevin Lubick217056c2018-09-20 17:39:31 -040081
Kevin Lubick61887c72019-09-26 13:20:50 -040082#ifndef SK_NO_FONTS
83sk_sp<SkFontMgr> SkFontMgr_New_Custom_Data(const uint8_t** datas, const size_t* sizes, int n);
84#endif
85
Kevin Lubickb5ae3b52018-11-03 07:51:19 -040086struct SimpleMatrix {
87 SkScalar scaleX, skewX, transX;
88 SkScalar skewY, scaleY, transY;
89 SkScalar pers0, pers1, pers2;
90};
91
92SkMatrix toSkMatrix(const SimpleMatrix& sm) {
93 return SkMatrix::MakeAll(sm.scaleX, sm.skewX , sm.transX,
94 sm.skewY , sm.scaleY, sm.transY,
95 sm.pers0 , sm.pers1 , sm.pers2);
Kevin Lubick217056c2018-09-20 17:39:31 -040096}
97
Kevin Lubick5d5723c2018-12-07 10:09:11 -050098SimpleMatrix toSimpleSkMatrix(const SkMatrix& sm) {
99 SimpleMatrix m {sm[0], sm[1], sm[2],
100 sm[3], sm[4], sm[5],
101 sm[6], sm[7], sm[8]};
102 return m;
103}
104
Kevin Lubickea905ec2018-11-30 14:05:58 -0500105struct SimpleImageInfo {
106 int width;
107 int height;
108 SkColorType colorType;
109 SkAlphaType alphaType;
110 // TODO color spaces?
111};
112
113SkImageInfo toSkImageInfo(const SimpleImageInfo& sii) {
114 return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType);
115}
116
Kevin Lubick543f3522019-03-08 10:04:28 -0500117#if SK_SUPPORT_GPU
118sk_sp<GrContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)
119{
120 EMSCRIPTEN_RESULT r = emscripten_webgl_make_context_current(context);
121 if (r < 0) {
122 printf("failed to make webgl context current %d\n", r);
123 return nullptr;
124 }
125 // setup GrContext
126 auto interface = GrGLMakeNativeInterface();
127 // setup contexts
128 sk_sp<GrContext> grContext(GrContext::MakeGL(interface));
129 return grContext;
130}
131
132sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrContext> grContext, int width, int height) {
133 glClearColor(0, 0, 0, 0);
134 glClearStencil(0);
135 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
136
137
138 // Wrap the frame buffer object attached to the screen in a Skia render
139 // target so Skia can render to it
140 GrGLint buffer;
141 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
142 GrGLFramebufferInfo info;
143 info.fFBOID = (GrGLuint) buffer;
144 SkColorType colorType;
145
Kevin Lubick14967582019-11-15 11:02:15 -0500146 GrGLint stencil;
147 glGetIntegerv(GL_STENCIL_BITS, &stencil);
148
Kevin Lubick543f3522019-03-08 10:04:28 -0500149 info.fFormat = GL_RGBA8;
150 colorType = kRGBA_8888_SkColorType;
151
Kevin Lubick14967582019-11-15 11:02:15 -0500152 GrBackendRenderTarget target(width, height, 0, stencil, info);
Kevin Lubick543f3522019-03-08 10:04:28 -0500153
154 sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget(grContext.get(), target,
155 kBottomLeft_GrSurfaceOrigin,
156 colorType, nullptr, nullptr));
157 return surface;
158}
159
160sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrContext> grContext, int width, int height) {
161 SkImageInfo info = SkImageInfo::MakeN32(width, height, SkAlphaType::kPremul_SkAlphaType);
162
163 sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(grContext.get(),
164 SkBudgeted::kYes,
165 info, 0,
166 kBottomLeft_GrSurfaceOrigin,
167 nullptr, true));
168 return surface;
169}
170
171sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrContext> grContext, SimpleImageInfo sii) {
172 sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(grContext.get(),
173 SkBudgeted::kYes,
174 toSkImageInfo(sii), 0,
175 kBottomLeft_GrSurfaceOrigin,
176 nullptr, true));
177 return surface;
178}
179#endif
180
181
Kevin Lubick217056c2018-09-20 17:39:31 -0400182//========================================================================================
183// Path things
184//========================================================================================
185
186// All these Apply* methods are simple wrappers to avoid returning an object.
187// The default WASM bindings produce code that will leak if a return value
188// isn't assigned to a JS variable and has delete() called on it.
189// These Apply methods, combined with the smarter binding code allow for chainable
190// commands that don't leak if the return value is ignored (i.e. when used intuitively).
191
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500192void ApplyAddArc(SkPath& orig, const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle) {
193 orig.addArc(oval, startAngle, sweepAngle);
194}
195
Kevin Lubicke384df42019-08-26 15:48:09 -0400196void ApplyAddOval(SkPath& orig, const SkRect& oval, bool ccw, unsigned start) {
Mike Reed30bc5272019-11-22 18:34:02 +0000197 orig.addOval(oval, ccw ? SkPathDirection::kCCW : SkPathDirection::kCW, start);
Kevin Lubicke384df42019-08-26 15:48:09 -0400198}
199
Kevin Lubick217056c2018-09-20 17:39:31 -0400200void ApplyAddPath(SkPath& orig, const SkPath& newPath,
201 SkScalar scaleX, SkScalar skewX, SkScalar transX,
202 SkScalar skewY, SkScalar scaleY, SkScalar transY,
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500203 SkScalar pers0, SkScalar pers1, SkScalar pers2,
204 bool extendPath) {
Kevin Lubick217056c2018-09-20 17:39:31 -0400205 SkMatrix m = SkMatrix::MakeAll(scaleX, skewX , transX,
206 skewY , scaleY, transY,
207 pers0 , pers1 , pers2);
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500208 orig.addPath(newPath, m, extendPath ? SkPath::kExtend_AddPathMode :
209 SkPath::kAppend_AddPathMode);
Kevin Lubick217056c2018-09-20 17:39:31 -0400210}
211
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500212void ApplyAddRect(SkPath& path, SkScalar left, SkScalar top,
213 SkScalar right, SkScalar bottom, bool ccw) {
Mike Reed30bc5272019-11-22 18:34:02 +0000214 path.addRect(left, top, right, bottom, ccw ? SkPathDirection::kCCW : SkPathDirection::kCW);
Alexander Khovansky3e119332018-11-15 02:01:19 +0300215}
216
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500217void ApplyAddRoundRect(SkPath& path, SkScalar left, SkScalar top,
218 SkScalar right, SkScalar bottom, uintptr_t /* SkScalar* */ rPtr,
219 bool ccw) {
220 // See comment below for uintptr_t explanation
221 const SkScalar* radii = reinterpret_cast<const SkScalar*>(rPtr);
222 path.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), radii,
Mike Reed30bc5272019-11-22 18:34:02 +0000223 ccw ? SkPathDirection::kCCW : SkPathDirection::kCW);
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500224}
225
226
Kevin Lubick217056c2018-09-20 17:39:31 -0400227void ApplyArcTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
228 SkScalar radius) {
229 p.arcTo(x1, y1, x2, y2, radius);
230}
231
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500232void ApplyArcToAngle(SkPath& p, SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo) {
233 p.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
234}
235
Kevin Lubick79b71342019-11-01 14:36:52 -0400236void ApplyArcToArcSize(SkPath& orig, SkScalar rx, SkScalar ry, SkScalar xAxisRotate,
237 bool useSmallArc, bool ccw, SkScalar x, SkScalar y) {
Kevin Lubicke384df42019-08-26 15:48:09 -0400238 auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize : SkPath::ArcSize::kLarge_ArcSize;
Mike Reed30bc5272019-11-22 18:34:02 +0000239 auto sweep = ccw ? SkPathDirection::kCCW : SkPathDirection::kCW;
Kevin Lubicke384df42019-08-26 15:48:09 -0400240 orig.arcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
241}
242
Kevin Lubick79b71342019-11-01 14:36:52 -0400243void ApplyRArcToArcSize(SkPath& orig, SkScalar rx, SkScalar ry, SkScalar xAxisRotate,
244 bool useSmallArc, bool ccw, SkScalar dx, SkScalar dy) {
245 auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize : SkPath::ArcSize::kLarge_ArcSize;
Mike Reed30bc5272019-11-22 18:34:02 +0000246 auto sweep = ccw ? SkPathDirection::kCCW : SkPathDirection::kCW;
Kevin Lubick79b71342019-11-01 14:36:52 -0400247 orig.rArcTo(rx, ry, xAxisRotate, arcSize, sweep, dx, dy);
248}
249
Kevin Lubick217056c2018-09-20 17:39:31 -0400250void ApplyClose(SkPath& p) {
251 p.close();
252}
253
254void ApplyConicTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
255 SkScalar w) {
256 p.conicTo(x1, y1, x2, y2, w);
257}
258
Kevin Lubick79b71342019-11-01 14:36:52 -0400259void ApplyRConicTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
260 SkScalar w) {
261 p.rConicTo(dx1, dy1, dx2, dy2, w);
262}
263
Kevin Lubick217056c2018-09-20 17:39:31 -0400264void ApplyCubicTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
265 SkScalar x3, SkScalar y3) {
266 p.cubicTo(x1, y1, x2, y2, x3, y3);
267}
268
Kevin Lubick79b71342019-11-01 14:36:52 -0400269void ApplyRCubicTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
270 SkScalar dx3, SkScalar dy3) {
271 p.rCubicTo(dx1, dy1, dx2, dy2, dx3, dy3);
272}
273
Kevin Lubick217056c2018-09-20 17:39:31 -0400274void ApplyLineTo(SkPath& p, SkScalar x, SkScalar y) {
275 p.lineTo(x, y);
276}
277
Kevin Lubick79b71342019-11-01 14:36:52 -0400278void ApplyRLineTo(SkPath& p, SkScalar dx, SkScalar dy) {
279 p.rLineTo(dx, dy);
280}
281
Kevin Lubick217056c2018-09-20 17:39:31 -0400282void ApplyMoveTo(SkPath& p, SkScalar x, SkScalar y) {
283 p.moveTo(x, y);
284}
285
Kevin Lubick79b71342019-11-01 14:36:52 -0400286void ApplyRMoveTo(SkPath& p, SkScalar dx, SkScalar dy) {
287 p.rMoveTo(dx, dy);
288}
289
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500290void ApplyReset(SkPath& p) {
291 p.reset();
292}
293
294void ApplyRewind(SkPath& p) {
295 p.rewind();
296}
297
Kevin Lubick217056c2018-09-20 17:39:31 -0400298void ApplyQuadTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
299 p.quadTo(x1, y1, x2, y2);
300}
301
Kevin Lubick79b71342019-11-01 14:36:52 -0400302void ApplyRQuadTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2) {
303 p.rQuadTo(dx1, dy1, dx2, dy2);
304}
305
Kevin Lubick217056c2018-09-20 17:39:31 -0400306void ApplyTransform(SkPath& orig,
307 SkScalar scaleX, SkScalar skewX, SkScalar transX,
308 SkScalar skewY, SkScalar scaleY, SkScalar transY,
309 SkScalar pers0, SkScalar pers1, SkScalar pers2) {
310 SkMatrix m = SkMatrix::MakeAll(scaleX, skewX , transX,
311 skewY , scaleY, transY,
312 pers0 , pers1 , pers2);
313 orig.transform(m);
314}
315
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400316bool EMSCRIPTEN_KEEPALIVE ApplySimplify(SkPath& path) {
317 return Simplify(path, &path);
318}
319
320bool EMSCRIPTEN_KEEPALIVE ApplyPathOp(SkPath& pathOne, const SkPath& pathTwo, SkPathOp op) {
321 return Op(pathOne, pathTwo, op, &pathOne);
322}
323
324JSString EMSCRIPTEN_KEEPALIVE ToSVGString(const SkPath& path) {
325 SkString s;
326 SkParsePath::ToSVGString(path, &s);
327 return emscripten::val(s.c_str());
328}
329
Kevin Lubicka40f8322018-12-17 16:01:36 -0500330SkPathOrNull EMSCRIPTEN_KEEPALIVE MakePathFromSVGString(std::string str) {
331 SkPath path;
332 if (SkParsePath::FromSVGString(str.c_str(), &path)) {
333 return emscripten::val(path);
334 }
335 return emscripten::val::null();
336}
337
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400338SkPathOrNull EMSCRIPTEN_KEEPALIVE MakePathFromOp(const SkPath& pathOne, const SkPath& pathTwo, SkPathOp op) {
339 SkPath out;
340 if (Op(pathOne, pathTwo, op, &out)) {
341 return emscripten::val(out);
342 }
343 return emscripten::val::null();
344}
345
Kevin Lubick217056c2018-09-20 17:39:31 -0400346SkPath EMSCRIPTEN_KEEPALIVE CopyPath(const SkPath& a) {
347 SkPath copy(a);
348 return copy;
349}
350
351bool EMSCRIPTEN_KEEPALIVE Equals(const SkPath& a, const SkPath& b) {
352 return a == b;
353}
354
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500355// =================================================================================
356// Creating/Exporting Paths with cmd arrays
357// =================================================================================
358
359static const int MOVE = 0;
360static const int LINE = 1;
361static const int QUAD = 2;
362static const int CONIC = 3;
363static const int CUBIC = 4;
364static const int CLOSE = 5;
365
366template <typename VisitFunc>
367void VisitPath(const SkPath& p, VisitFunc&& f) {
368 SkPath::RawIter iter(p);
369 SkPoint pts[4];
370 SkPath::Verb verb;
371 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
372 f(verb, pts, iter);
373 }
374}
375
376JSArray EMSCRIPTEN_KEEPALIVE ToCmds(const SkPath& path) {
377 JSArray cmds = emscripten::val::array();
378
379 VisitPath(path, [&cmds](SkPath::Verb verb, const SkPoint pts[4], SkPath::RawIter iter) {
380 JSArray cmd = emscripten::val::array();
381 switch (verb) {
382 case SkPath::kMove_Verb:
383 cmd.call<void>("push", MOVE, pts[0].x(), pts[0].y());
384 break;
385 case SkPath::kLine_Verb:
386 cmd.call<void>("push", LINE, pts[1].x(), pts[1].y());
387 break;
388 case SkPath::kQuad_Verb:
389 cmd.call<void>("push", QUAD, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
390 break;
391 case SkPath::kConic_Verb:
392 cmd.call<void>("push", CONIC,
393 pts[1].x(), pts[1].y(),
394 pts[2].x(), pts[2].y(), iter.conicWeight());
395 break;
396 case SkPath::kCubic_Verb:
397 cmd.call<void>("push", CUBIC,
398 pts[1].x(), pts[1].y(),
399 pts[2].x(), pts[2].y(),
400 pts[3].x(), pts[3].y());
401 break;
402 case SkPath::kClose_Verb:
403 cmd.call<void>("push", CLOSE);
404 break;
405 case SkPath::kDone_Verb:
406 SkASSERT(false);
407 break;
408 }
409 cmds.call<void>("push", cmd);
410 });
411 return cmds;
412}
413
414// This type signature is a mess, but it's necessary. See, we can't use "bind" (EMSCRIPTEN_BINDINGS)
415// and pointers to primitive types (Only bound types like SkPoint). We could if we used
416// cwrap (see https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97)
417// but that requires us to stick to C code and, AFAIK, doesn't allow us to return nice things like
418// SkPath or SkOpBuilder.
419//
Kevin Lubick61887c72019-09-26 13:20:50 -0400420// So, basically, if we are using C++ and EMSCRIPTEN_BINDINGS, we can't have primitive pointers
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500421// in our function type signatures. (this gives an error message like "Cannot call foo due to unbound
422// types Pi, Pf"). But, we can just pretend they are numbers and cast them to be pointers and
423// the compiler is happy.
424SkPathOrNull EMSCRIPTEN_KEEPALIVE MakePathFromCmds(uintptr_t /* float* */ cptr, int numCmds) {
425 const auto* cmds = reinterpret_cast<const float*>(cptr);
426 SkPath path;
427 float x1, y1, x2, y2, x3, y3;
428
429 // if there are not enough arguments, bail with the path we've constructed so far.
430 #define CHECK_NUM_ARGS(n) \
431 if ((i + n) > numCmds) { \
432 SkDebugf("Not enough args to match the verbs. Saw %d commands\n", numCmds); \
433 return emscripten::val::null(); \
434 }
435
436 for(int i = 0; i < numCmds;){
437 switch (sk_float_floor2int(cmds[i++])) {
438 case MOVE:
439 CHECK_NUM_ARGS(2);
440 x1 = cmds[i++], y1 = cmds[i++];
441 path.moveTo(x1, y1);
442 break;
443 case LINE:
444 CHECK_NUM_ARGS(2);
445 x1 = cmds[i++], y1 = cmds[i++];
446 path.lineTo(x1, y1);
447 break;
448 case QUAD:
449 CHECK_NUM_ARGS(4);
450 x1 = cmds[i++], y1 = cmds[i++];
451 x2 = cmds[i++], y2 = cmds[i++];
452 path.quadTo(x1, y1, x2, y2);
453 break;
454 case CONIC:
455 CHECK_NUM_ARGS(5);
456 x1 = cmds[i++], y1 = cmds[i++];
457 x2 = cmds[i++], y2 = cmds[i++];
458 x3 = cmds[i++]; // weight
459 path.conicTo(x1, y1, x2, y2, x3);
460 break;
461 case CUBIC:
462 CHECK_NUM_ARGS(6);
463 x1 = cmds[i++], y1 = cmds[i++];
464 x2 = cmds[i++], y2 = cmds[i++];
465 x3 = cmds[i++], y3 = cmds[i++];
466 path.cubicTo(x1, y1, x2, y2, x3, y3);
467 break;
468 case CLOSE:
469 path.close();
470 break;
471 default:
472 SkDebugf(" path: UNKNOWN command %f, aborting dump...\n", cmds[i-1]);
473 return emscripten::val::null();
474 }
475 }
476
477 #undef CHECK_NUM_ARGS
478
479 return emscripten::val(path);
480}
481
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400482//========================================================================================
483// Path Effects
484//========================================================================================
485
486bool ApplyDash(SkPath& path, SkScalar on, SkScalar off, SkScalar phase) {
487 SkScalar intervals[] = { on, off };
488 auto pe = SkDashPathEffect::Make(intervals, 2, phase);
489 if (!pe) {
490 SkDebugf("Invalid args to dash()\n");
491 return false;
492 }
493 SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
494 if (pe->filterPath(&path, path, &rec, nullptr)) {
495 return true;
496 }
497 SkDebugf("Could not make dashed path\n");
498 return false;
Kevin Lubick217056c2018-09-20 17:39:31 -0400499}
500
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400501bool ApplyTrim(SkPath& path, SkScalar startT, SkScalar stopT, bool isComplement) {
502 auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted : SkTrimPathEffect::Mode::kNormal;
503 auto pe = SkTrimPathEffect::Make(startT, stopT, mode);
504 if (!pe) {
505 SkDebugf("Invalid args to trim(): startT and stopT must be in [0,1]\n");
506 return false;
507 }
508 SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
509 if (pe->filterPath(&path, path, &rec, nullptr)) {
510 return true;
511 }
512 SkDebugf("Could not trim path\n");
513 return false;
514}
515
516struct StrokeOpts {
Kevin Lubickb9db3902018-11-26 11:47:54 -0500517 // Default values are set in interface.js which allows clients
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400518 // to set any number of them. Otherwise, the binding code complains if
519 // any are omitted.
520 SkScalar width;
521 SkScalar miter_limit;
522 SkPaint::Join join;
523 SkPaint::Cap cap;
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500524 float precision;
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400525};
526
527bool ApplyStroke(SkPath& path, StrokeOpts opts) {
528 SkPaint p;
529 p.setStyle(SkPaint::kStroke_Style);
530 p.setStrokeCap(opts.cap);
531 p.setStrokeJoin(opts.join);
532 p.setStrokeWidth(opts.width);
533 p.setStrokeMiter(opts.miter_limit);
534
Kevin Lubick1646e7d2018-12-07 13:03:08 -0500535 return p.getFillPath(path, &path, nullptr, opts.precision);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400536}
537
538// to map from raw memory to a uint8array
539Uint8Array getSkDataBytes(const SkData *data) {
540 return Uint8Array(typed_memory_view(data->size(), data->bytes()));
541}
542
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500543// Text Shaping abstraction
544
545struct ShapedTextOpts {
546 SkFont font;
547 bool leftToRight;
548 std::string text;
549 SkScalar width;
550};
551
552std::unique_ptr<SkShaper> shaper;
553
554static sk_sp<SkTextBlob> do_shaping(const ShapedTextOpts& opts, SkPoint* pt) {
Ben Wagner3bdb69c2019-04-01 19:01:09 -0400555 SkTextBlobBuilderRunHandler builder(opts.text.c_str(), {0, 0});
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500556 if (!shaper) {
557 shaper = SkShaper::Make();
558 }
Ben Wagner3bdb69c2019-04-01 19:01:09 -0400559 shaper->shape(opts.text.c_str(), opts.text.length(),
560 opts.font, opts.leftToRight,
561 opts.width, &builder);
562 *pt = builder.endPoint();
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500563 return builder.makeBlob();
564}
565
566class ShapedText {
567public:
568 ShapedText(ShapedTextOpts opts) : fOpts(opts) {}
569
570 SkRect getBounds() {
571 this->init();
572 return SkRect::MakeLTRB(0, 0, fOpts.width, fPoint.y());
573 }
574
575 SkTextBlob* blob() {
576 this->init();
577 return fBlob.get();
578 }
579private:
580 const ShapedTextOpts fOpts;
581 SkPoint fPoint;
582 sk_sp<SkTextBlob> fBlob;
583
584 void init() {
585 if (!fBlob) {
586 fBlob = do_shaping(fOpts, &fPoint);
587 }
588 }
589};
590
591void drawShapedText(SkCanvas& canvas, ShapedText st, SkScalar x,
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400592 SkScalar y, SkPaint paint) {
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500593 canvas.drawTextBlob(st.blob(), x, y, paint);
594}
595
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400596int saveLayerRec(SkCanvas& canvas, const SkPaint* paint,
597 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) {
598 return canvas.saveLayer(SkCanvas::SaveLayerRec(nullptr, paint, backdrop, flags));
599}
600
601int saveLayerRecBounds(SkCanvas& canvas, const SkPaint* paint, const SkImageFilter* backdrop,
602 SkCanvas::SaveLayerFlags flags, const SkRect& bounds) {
603 return canvas.saveLayer(SkCanvas::SaveLayerRec(&bounds, paint, backdrop, flags));
604}
605
Kevin Lubickd3cfbca2019-03-15 15:36:29 -0400606// This is simpler than dealing with an SkPoint and SkVector
607struct PosTan {
608 SkScalar px, py, tx, ty;
609};
610
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400611// SimpleRRect is simpler than passing a (complex) SkRRect over the wire to JS.
612struct SimpleRRect {
613 SkRect rect;
Kevin Lubick7d644e12019-09-11 14:22:22 -0400614
615 SkScalar rx1;
616 SkScalar ry1;
617 SkScalar rx2;
618 SkScalar ry2;
619 SkScalar rx3;
620 SkScalar ry3;
621 SkScalar rx4;
622 SkScalar ry4;
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400623};
624
625SkRRect toRRect(const SimpleRRect& r) {
Kevin Lubick7d644e12019-09-11 14:22:22 -0400626 SkVector fRadii[4] = {{r.rx1, r.ry1}, {r.rx2, r.ry2},
627 {r.rx3, r.ry3}, {r.rx4, r.ry4}};
628 SkRRect rr;
629 rr.setRectRadii(r.rect, fRadii);
630 return rr;
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400631}
632
Kevin Lubick50f377e2019-09-11 15:23:00 -0400633struct TonalColors {
634 SkColor ambientColor;
635 SkColor spotColor;
636};
637
638TonalColors computeTonalColors(const TonalColors& in) {
639 TonalColors out;
640 SkShadowUtils::ComputeTonalColors(in.ambientColor, in.spotColor,
641 &out.ambientColor, &out.spotColor);
642 return out;
643}
644
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400645// These objects have private destructors / delete methods - I don't think
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400646// we need to do anything other than tell emscripten to do nothing.
Kevin Lubick217056c2018-09-20 17:39:31 -0400647namespace emscripten {
648 namespace internal {
649 template<typename ClassType>
650 void raw_destructor(ClassType *);
651
652 template<>
Kevin Lubicke59c1672019-11-20 14:17:53 -0500653 void raw_destructor<SkContourMeasure>(SkContourMeasure *ptr) {
654 }
655
656 template<>
Kevin Lubick217056c2018-09-20 17:39:31 -0400657 void raw_destructor<SkData>(SkData *ptr) {
658 }
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400659
660 template<>
661 void raw_destructor<SkVertices>(SkVertices *ptr) {
662 }
Kevin Lubickec4903d2019-01-14 08:36:08 -0500663
Kevin Lubick61887c72019-09-26 13:20:50 -0400664#ifndef SK_NO_FONTS
Kevin Lubickec4903d2019-01-14 08:36:08 -0500665 template<>
666 void raw_destructor<SkTextBlob>(SkTextBlob *ptr) {
667 }
Kevin Lubick61887c72019-09-26 13:20:50 -0400668
669 template<>
670 void raw_destructor<SkTypeface>(SkTypeface *ptr) {
671 }
672#endif
Kevin Lubick217056c2018-09-20 17:39:31 -0400673 }
674}
675
Kevin Lubick61887c72019-09-26 13:20:50 -0400676// Some signatures below have uintptr_t instead of a pointer to a primitive
Kevin Lubick217056c2018-09-20 17:39:31 -0400677// type (e.g. SkScalar). This is necessary because we can't use "bind" (EMSCRIPTEN_BINDINGS)
678// and pointers to primitive types (Only bound types like SkPoint). We could if we used
679// cwrap (see https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97)
680// but that requires us to stick to C code and, AFAIK, doesn't allow us to return nice things like
681// SkPath or SkCanvas.
682//
Kevin Lubick61887c72019-09-26 13:20:50 -0400683// So, basically, if we are using C++ and EMSCRIPTEN_BINDINGS, we can't have primitive pointers
Kevin Lubick217056c2018-09-20 17:39:31 -0400684// in our function type signatures. (this gives an error message like "Cannot call foo due to unbound
685// types Pi, Pf"). But, we can just pretend they are numbers and cast them to be pointers and
686// the compiler is happy.
687EMSCRIPTEN_BINDINGS(Skia) {
Kevin Lubick53965c92018-10-11 08:51:55 -0400688#if SK_SUPPORT_GPU
Kevin Lubick53965c92018-10-11 08:51:55 -0400689 function("currentContext", &emscripten_webgl_get_current_context);
690 function("setCurrentContext", &emscripten_webgl_make_context_current);
Kevin Lubick543f3522019-03-08 10:04:28 -0500691 function("MakeGrContext", &MakeGrContext);
692 function("MakeOnScreenGLSurface", &MakeOnScreenGLSurface);
693 function("MakeRenderTarget", select_overload<sk_sp<SkSurface>(sk_sp<GrContext>, int, int)>(&MakeRenderTarget));
694 function("MakeRenderTarget", select_overload<sk_sp<SkSurface>(sk_sp<GrContext>, SimpleImageInfo)>(&MakeRenderTarget));
695
Kevin Lubick3d99b1e2018-10-16 10:15:01 -0400696 constant("gpu", true);
Kevin Lubickb07204a2018-11-20 14:07:42 -0500697#endif
Florin Malita0d603d82019-11-25 13:45:28 -0500698 function("getDecodeCacheLimitBytes", &SkResourceCache::GetTotalByteLimit);
699 function("setDecodeCacheLimitBytes", &SkResourceCache::SetTotalByteLimit);
700 function("getDecodeCacheUsedBytes" , &SkResourceCache::GetTotalBytesUsed);
701
Kevin Lubick50f377e2019-09-11 15:23:00 -0400702 function("computeTonalColors", &computeTonalColors);
Kevin Lubick6b921b72019-09-18 16:18:17 -0400703 function("_decodeAnimatedImage", optional_override([](uintptr_t /* uint8_t* */ iptr,
704 size_t length)->sk_sp<SkAnimatedImage> {
705 uint8_t* imgData = reinterpret_cast<uint8_t*>(iptr);
706 sk_sp<SkData> bytes = SkData::MakeFromMalloc(imgData, length);
707 auto codec = SkAndroidCodec::MakeFromData(bytes);
708 if (nullptr == codec) {
709 return nullptr;
710 }
711 return SkAnimatedImage::Make(std::move(codec));
712 }), allow_raw_pointers());
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500713 function("_decodeImage", optional_override([](uintptr_t /* uint8_t* */ iptr,
714 size_t length)->sk_sp<SkImage> {
715 uint8_t* imgData = reinterpret_cast<uint8_t*>(iptr);
Kevin Lubick88aff5f2019-02-28 16:05:09 -0500716 sk_sp<SkData> bytes = SkData::MakeFromMalloc(imgData, length);
717 return SkImage::MakeFromEncoded(std::move(bytes));
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500718 }), allow_raw_pointers());
Kevin Lubickea905ec2018-11-30 14:05:58 -0500719 function("_getRasterDirectSurface", optional_override([](const SimpleImageInfo ii,
Kevin Lubick52b9f372018-12-04 13:57:36 -0500720 uintptr_t /* uint8_t* */ pPtr,
Kevin Lubickea905ec2018-11-30 14:05:58 -0500721 size_t rowBytes)->sk_sp<SkSurface> {
Kevin Lubick52b9f372018-12-04 13:57:36 -0500722 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
Kevin Lubickea905ec2018-11-30 14:05:58 -0500723 SkImageInfo imageInfo = toSkImageInfo(ii);
724 return SkSurface::MakeRasterDirect(imageInfo, pixels, rowBytes, nullptr);
725 }), allow_raw_pointers());
Kevin Lubick53965c92018-10-11 08:51:55 -0400726 function("_getRasterN32PremulSurface", optional_override([](int width, int height)->sk_sp<SkSurface> {
727 return SkSurface::MakeRasterN32Premul(width, height, nullptr);
728 }), allow_raw_pointers());
Kevin Lubickb07204a2018-11-20 14:07:42 -0500729
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400730 function("getSkDataBytes", &getSkDataBytes, allow_raw_pointers());
Kevin Lubick217056c2018-09-20 17:39:31 -0400731 function("MakeSkCornerPathEffect", &SkCornerPathEffect::Make, allow_raw_pointers());
732 function("MakeSkDiscretePathEffect", &SkDiscretePathEffect::Make, allow_raw_pointers());
Kevin Lubick15b40232019-10-29 09:55:39 -0400733 // Deprecated: use Canvaskit.SkMaskFilter.MakeBlur
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500734 function("MakeBlurMaskFilter", optional_override([](SkBlurStyle style, SkScalar sigma, bool respectCTM)->sk_sp<SkMaskFilter> {
735 // Adds a little helper because emscripten doesn't expose default params.
736 return SkMaskFilter::MakeBlur(style, sigma, respectCTM);
737 }), allow_raw_pointers());
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500738 function("_MakePathFromCmds", &MakePathFromCmds);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400739 function("MakePathFromOp", &MakePathFromOp);
Kevin Lubicka40f8322018-12-17 16:01:36 -0500740 function("MakePathFromSVGString", &MakePathFromSVGString);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400741
742 // These won't be called directly, there's a JS helper to deal with typed arrays.
Kevin Lubick217056c2018-09-20 17:39:31 -0400743 function("_MakeSkDashPathEffect", optional_override([](uintptr_t /* float* */ cptr, int count, SkScalar phase)->sk_sp<SkPathEffect> {
744 // See comment above for uintptr_t explanation
745 const float* intervals = reinterpret_cast<const float*>(cptr);
746 return SkDashPathEffect::Make(intervals, count, phase);
747 }), allow_raw_pointers());
Kevin Lubick52b9f372018-12-04 13:57:36 -0500748 function("_MakeImage", optional_override([](SimpleImageInfo ii,
749 uintptr_t /* uint8_t* */ pPtr, int plen,
750 size_t rowBytes)->sk_sp<SkImage> {
751 // See comment above for uintptr_t explanation
752 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
753 SkImageInfo info = toSkImageInfo(ii);
754 sk_sp<SkData> pixelData = SkData::MakeFromMalloc(pixels, plen);
755
756 return SkImage::MakeRasterData(info, pixelData, rowBytes);
757 }), allow_raw_pointers());
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400758 function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
759 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400760 int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400761 SkPoint points[] = { start, end };
762 // See comment above for uintptr_t explanation
763 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
764 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
765
766 return SkGradientShader::MakeLinear(points, colors, positions, count,
767 mode, flags, nullptr);
768 }), allow_raw_pointers());
769 function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
770 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400771 int count, SkTileMode mode, uint32_t flags,
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400772 const SimpleMatrix& lm)->sk_sp<SkShader> {
773 SkPoint points[] = { start, end };
774 // See comment above for uintptr_t explanation
775 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
776 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
777
778 SkMatrix localMatrix = toSkMatrix(lm);
779
780 return SkGradientShader::MakeLinear(points, colors, positions, count,
781 mode, flags, &localMatrix);
782 }), allow_raw_pointers());
783 function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
784 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400785 int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400786 // See comment above for uintptr_t explanation
787 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
788 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
789
790 return SkGradientShader::MakeRadial(center, radius, colors, positions, count,
791 mode, flags, nullptr);
792 }), allow_raw_pointers());
793 function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
794 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400795 int count, SkTileMode mode, uint32_t flags,
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400796 const SimpleMatrix& lm)->sk_sp<SkShader> {
797 // See comment above for uintptr_t explanation
798 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
799 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
800
801 SkMatrix localMatrix = toSkMatrix(lm);
802 return SkGradientShader::MakeRadial(center, radius, colors, positions, count,
803 mode, flags, &localMatrix);
804 }), allow_raw_pointers());
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500805 function("_MakeTwoPointConicalGradientShader", optional_override([](
806 SkPoint start, SkScalar startRadius,
807 SkPoint end, SkScalar endRadius,
808 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400809 int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500810 // See comment above for uintptr_t explanation
811 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
812 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
813
814 return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
815 colors, positions, count, mode,
816 flags, nullptr);
817 }), allow_raw_pointers());
818 function("_MakeTwoPointConicalGradientShader", optional_override([](
819 SkPoint start, SkScalar startRadius,
820 SkPoint end, SkScalar endRadius,
821 uintptr_t /* SkColor* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
Mike Reed5c5de212019-04-03 16:51:47 -0400822 int count, SkTileMode mode, uint32_t flags,
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500823 const SimpleMatrix& lm)->sk_sp<SkShader> {
824 // See comment above for uintptr_t explanation
825 const SkColor* colors = reinterpret_cast<const SkColor*> (cPtr);
826 const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
827
828 SkMatrix localMatrix = toSkMatrix(lm);
829 return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
830 colors, positions, count, mode,
831 flags, &localMatrix);
832 }), allow_raw_pointers());
833
Kevin Lubick543f3522019-03-08 10:04:28 -0500834#if SK_SUPPORT_GPU
835 class_<GrContext>("GrContext")
Kevin Lubickcd544662019-03-22 15:41:36 -0400836 .smart_ptr<sk_sp<GrContext>>("sk_sp<GrContext>")
837 .function("getResourceCacheLimitBytes", optional_override([](GrContext& self)->size_t {
838 int maxResources = 0;// ignored
839 size_t currMax = 0;
840 self.getResourceCacheLimits(&maxResources, &currMax);
841 return currMax;
842 }))
843 .function("getResourceCacheUsageBytes", optional_override([](GrContext& self)->size_t {
844 int usedResources = 0;// ignored
845 size_t currUsage = 0;
846 self.getResourceCacheUsage(&usedResources, &currUsage);
847 return currUsage;
848 }))
849 .function("setResourceCacheLimitBytes", optional_override([](GrContext& self, size_t maxResourceBytes)->void {
850 int maxResources = 0;
851 size_t currMax = 0; // ignored
852 self.getResourceCacheLimits(&maxResources, &currMax);
853 self.setResourceCacheLimits(maxResources, maxResourceBytes);
854 }));
Kevin Lubick543f3522019-03-08 10:04:28 -0500855#endif
856
Kevin Lubick6b921b72019-09-18 16:18:17 -0400857 class_<SkAnimatedImage>("SkAnimatedImage")
858 .smart_ptr<sk_sp<SkAnimatedImage>>("sk_sp<SkAnimatedImage>")
Kevin Lubick47bd9f12019-11-08 06:55:15 -0800859 .function("decodeNextFrame", &SkAnimatedImage::decodeNextFrame)
860 .function("getFrameCount", &SkAnimatedImage::getFrameCount)
Kevin Lubick6b921b72019-09-18 16:18:17 -0400861 .function("getRepetitionCount", &SkAnimatedImage::getRepetitionCount)
Kevin Lubick47bd9f12019-11-08 06:55:15 -0800862 .function("height", optional_override([](SkAnimatedImage& self)->int32_t {
863 return self.dimensions().height();
864 }))
865 .function("reset", &SkAnimatedImage::reset)
866 .function("width", optional_override([](SkAnimatedImage& self)->int32_t {
867 return self.dimensions().width();
868 }));
Kevin Lubick6b921b72019-09-18 16:18:17 -0400869
Kevin Lubick217056c2018-09-20 17:39:31 -0400870 class_<SkCanvas>("SkCanvas")
871 .constructor<>()
Kevin Lubickee91c072019-03-29 10:39:52 -0400872 .function("clear", &SkCanvas::clear)
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500873 .function("clipPath", select_overload<void (const SkPath&, SkClipOp, bool)>(&SkCanvas::clipPath))
Kevin Lubick47bd9f12019-11-08 06:55:15 -0800874 .function("clipRRect", optional_override([](SkCanvas& self, const SimpleRRect& r, SkClipOp op, bool doAntiAlias) {
Kevin Lubick6dbc4ed2019-10-22 09:43:34 -0400875 self.clipRRect(toRRect(r), op, doAntiAlias);
876 }))
Kevin Lubick52b9f372018-12-04 13:57:36 -0500877 .function("clipRect", select_overload<void (const SkRect&, SkClipOp, bool)>(&SkCanvas::clipRect))
878 .function("concat", optional_override([](SkCanvas& self, const SimpleMatrix& m) {
879 self.concat(toSkMatrix(m));
880 }))
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500881 .function("drawArc", &SkCanvas::drawArc)
Kevin Lubickee91c072019-03-29 10:39:52 -0400882 .function("_drawAtlas", optional_override([](SkCanvas& self,
883 const sk_sp<SkImage>& atlas, uintptr_t /* SkRSXform* */ xptr,
884 uintptr_t /* SkRect* */ rptr, uintptr_t /* SkColor* */ cptr, int count,
885 SkBlendMode mode, const SkPaint* paint)->void {
886 // See comment above for uintptr_t explanation
887 const SkRSXform* dstXforms = reinterpret_cast<const SkRSXform*>(xptr);
888 const SkRect* srcRects = reinterpret_cast<const SkRect*>(rptr);
889 const SkColor* colors = nullptr;
890 if (cptr) {
891 colors = reinterpret_cast<const SkColor*>(cptr);
892 }
893 self.drawAtlas(atlas, dstXforms, srcRects, colors, count, mode, nullptr, paint);
894 }), allow_raw_pointers())
Kevin Lubicke384df42019-08-26 15:48:09 -0400895 .function("drawCircle", select_overload<void (SkScalar, SkScalar, SkScalar, const SkPaint& paint)>(&SkCanvas::drawCircle))
Kevin Lubick6dbc4ed2019-10-22 09:43:34 -0400896 .function("drawColor", &SkCanvas::drawColor)
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400897 .function("drawDRRect",optional_override([](SkCanvas& self, const SimpleRRect& o, const SimpleRRect& i, const SkPaint& paint) {
898 self.drawDRRect(toRRect(o), toRRect(i), paint);
899 }))
Kevin Lubick6b921b72019-09-18 16:18:17 -0400900 .function("drawAnimatedImage", optional_override([](SkCanvas& self, sk_sp<SkAnimatedImage>& aImg,
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500901 SkScalar x, SkScalar y)->void {
Kevin Lubick6b921b72019-09-18 16:18:17 -0400902 self.drawDrawable(aImg.get(), x, y);
903 }), allow_raw_pointers())
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500904 .function("drawImage", select_overload<void (const sk_sp<SkImage>&, SkScalar, SkScalar, const SkPaint*)>(&SkCanvas::drawImage), allow_raw_pointers())
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500905 .function("drawImageNine", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
906 SkIRect center, SkRect dst,
907 const SkPaint* paint)->void {
908 self.drawImageNine(image, center, dst, paint);
909 }), allow_raw_pointers())
Kevin Lubick0a1293c2018-12-03 12:31:04 -0500910 .function("drawImageRect", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
911 SkRect src, SkRect dst,
912 const SkPaint* paint, bool fastSample)->void {
913 self.drawImageRect(image, src, dst, paint,
914 fastSample ? SkCanvas::kFast_SrcRectConstraint :
915 SkCanvas::kStrict_SrcRectConstraint);
916 }), allow_raw_pointers())
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500917 .function("drawLine", select_overload<void (SkScalar, SkScalar, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawLine))
918 .function("drawOval", &SkCanvas::drawOval)
Kevin Lubick217056c2018-09-20 17:39:31 -0400919 .function("drawPaint", &SkCanvas::drawPaint)
Kevin Lubick369f6a52019-10-03 11:22:08 -0400920#ifdef SK_INCLUDE_PARAGRAPH
921 .function("drawParagraph", optional_override([](SkCanvas& self, skia::textlayout::Paragraph* p,
922 SkScalar x, SkScalar y) {
923 p->paint(&self, x, y);
924 }), allow_raw_pointers())
925#endif
Kevin Lubick217056c2018-09-20 17:39:31 -0400926 .function("drawPath", &SkCanvas::drawPath)
Kevin Lubickcc13fd32019-04-05 13:00:01 -0400927 // Of note, picture is *not* what is colloquially thought of as a "picture", what we call
928 // a bitmap. An SkPicture is a series of draw commands.
929 .function("drawPicture", select_overload<void (const sk_sp<SkPicture>&)>(&SkCanvas::drawPicture))
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500930 .function("_drawPoints", optional_override([](SkCanvas& self, SkCanvas::PointMode mode,
931 uintptr_t /* SkPoint* */ pptr,
932 int count, SkPaint paint)->void {
933 // See comment above for uintptr_t explanation
934 const SkPoint* pts = reinterpret_cast<const SkPoint*>(pptr);
935 self.drawPoints(mode, count, pts, paint);
936 }))
Kevin Lubick2e5fe352019-09-03 12:59:06 -0400937 .function("drawRRect",optional_override([](SkCanvas& self, const SimpleRRect& r, const SkPaint& paint) {
938 self.drawRRect(toRRect(r), paint);
939 }))
Kevin Lubick217056c2018-09-20 17:39:31 -0400940 .function("drawRect", &SkCanvas::drawRect)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500941 .function("drawRoundRect", &SkCanvas::drawRoundRect)
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500942 .function("drawShadow", optional_override([](SkCanvas& self, const SkPath& path,
943 const SkPoint3& zPlaneParams,
944 const SkPoint3& lightPos, SkScalar lightRadius,
Kevin Lubickee91c072019-03-29 10:39:52 -0400945 SkColor ambientColor, SkColor spotColor,
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500946 uint32_t flags) {
947 SkShadowUtils::DrawShadow(&self, path, zPlaneParams, lightPos, lightRadius,
Kevin Lubickee91c072019-03-29 10:39:52 -0400948 ambientColor, spotColor, flags);
Kevin Lubick61ef7b22018-11-27 13:26:59 -0500949 }))
Kevin Lubick61887c72019-09-26 13:20:50 -0400950#ifndef SK_NO_FONTS
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500951 .function("_drawShapedText", &drawShapedText)
Kevin Lubickec4903d2019-01-14 08:36:08 -0500952 .function("_drawSimpleText", optional_override([](SkCanvas& self, uintptr_t /* char* */ sptr,
953 size_t len, SkScalar x, SkScalar y, const SkFont& font,
954 const SkPaint& paint) {
955 // See comment above for uintptr_t explanation
956 const char* str = reinterpret_cast<const char*>(sptr);
957
958 self.drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
Kevin Lubick217056c2018-09-20 17:39:31 -0400959 }))
Kevin Lubickec4903d2019-01-14 08:36:08 -0500960 .function("drawTextBlob", select_overload<void (const sk_sp<SkTextBlob>&, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawTextBlob))
Kevin Lubick61887c72019-09-26 13:20:50 -0400961#endif
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400962 .function("drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices))
Kevin Lubick217056c2018-09-20 17:39:31 -0400963 .function("flush", &SkCanvas::flush)
Kevin Lubicke384df42019-08-26 15:48:09 -0400964 .function("getSaveCount", &SkCanvas::getSaveCount)
Kevin Lubick5d5723c2018-12-07 10:09:11 -0500965 .function("getTotalMatrix", optional_override([](const SkCanvas& self)->SimpleMatrix {
966 SkMatrix m = self.getTotalMatrix();
967 return toSimpleSkMatrix(m);
968 }))
Kevin Lubick543f3522019-03-08 10:04:28 -0500969 .function("makeSurface", optional_override([](SkCanvas& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
970 return self.makeSurface(toSkImageInfo(sii), nullptr);
971 }), allow_raw_pointers())
Kevin Lubick52b9f372018-12-04 13:57:36 -0500972 .function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
973 uintptr_t /* uint8_t* */ pPtr,
974 size_t dstRowBytes, int srcX, int srcY) {
975 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
976 SkImageInfo dstInfo = toSkImageInfo(di);
977
978 return self.readPixels(dstInfo, pixels, dstRowBytes, srcX, srcY);
979 }))
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500980 .function("restore", &SkCanvas::restore)
Kevin Lubickb3574c92019-03-06 08:25:36 -0500981 .function("restoreToCount", &SkCanvas::restoreToCount)
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400982 .function("rotate", select_overload<void (SkScalar, SkScalar, SkScalar)>(&SkCanvas::rotate))
Kevin Lubick217056c2018-09-20 17:39:31 -0400983 .function("save", &SkCanvas::save)
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400984 // 2 params
Kevin Lubickb3574c92019-03-06 08:25:36 -0500985 .function("saveLayer", select_overload<int (const SkRect&, const SkPaint*)>(&SkCanvas::saveLayer),
986 allow_raw_pointers())
Kevin Lubick77d9b5c2019-10-29 10:48:26 -0400987 // 3 params (effectively with SaveLayerRec, but no bounds)
988 .function("saveLayer", saveLayerRec, allow_raw_pointers())
989 // 4 params (effectively with SaveLayerRec)
990 .function("saveLayer", saveLayerRecBounds, allow_raw_pointers())
991
Kevin Lubick006a6f32018-10-19 14:34:34 -0400992 .function("scale", &SkCanvas::scale)
Kevin Lubick006a6f32018-10-19 14:34:34 -0400993 .function("skew", &SkCanvas::skew)
Kevin Lubick52b9f372018-12-04 13:57:36 -0500994 .function("translate", &SkCanvas::translate)
995 .function("_writePixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
996 uintptr_t /* uint8_t* */ pPtr,
997 size_t srcRowBytes, int dstX, int dstY) {
998 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
999 SkImageInfo dstInfo = toSkImageInfo(di);
1000
1001 return self.writePixels(dstInfo, pixels, srcRowBytes, dstX, dstY);
Kevin Lubick369f6a52019-10-03 11:22:08 -04001002 }));
Kevin Lubick217056c2018-09-20 17:39:31 -04001003
Kevin Lubickd3729342019-09-12 11:11:25 -04001004 class_<SkColorFilter>("SkColorFilter")
1005 .smart_ptr<sk_sp<SkColorFilter>>("sk_sp<SkColorFilter>>")
1006 .class_function("MakeBlend", &SkColorFilters::Blend)
1007 .class_function("MakeCompose", &SkColorFilters::Compose)
1008 .class_function("MakeLerp", &SkColorFilters::Lerp)
1009 .class_function("MakeLinearToSRGBGamma", &SkColorFilters::LinearToSRGBGamma)
1010 .class_function("_makeMatrix", optional_override([](uintptr_t /* float* */ fPtr) {
1011 float* twentyFloats = reinterpret_cast<float*>(fPtr);
1012 return SkColorFilters::Matrix(twentyFloats);
1013 }))
1014 .class_function("MakeSRGBToLinearGamma", &SkColorFilters::SRGBToLinearGamma);
1015
Kevin Lubicke59c1672019-11-20 14:17:53 -05001016 class_<SkContourMeasureIter>("SkContourMeasureIter")
1017 .constructor<const SkPath&, bool, SkScalar>()
1018 .function("next", &SkContourMeasureIter::next);
1019
1020 class_<SkContourMeasure>("SkContourMeasure")
1021 .smart_ptr<sk_sp<SkContourMeasure>>("sk_sp<SkContourMeasure>>")
1022 .function("getPosTan", optional_override([](SkContourMeasure& self,
1023 SkScalar distance) -> PosTan {
1024 SkPoint p{0, 0};
1025 SkVector v{0, 0};
1026 if (!self.getPosTan(distance, &p, &v)) {
1027 SkDebugf("zero-length path in getPosTan\n");
1028 }
1029 return PosTan{p.x(), p.y(), v.x(), v.y()};
1030 }))
1031 .function("getSegment", optional_override([](SkContourMeasure& self, SkScalar startD,
1032 SkScalar stopD, bool startWithMoveTo) -> SkPath {
1033 SkPath p;
1034 bool ok = self.getSegment(startD, stopD, &p, startWithMoveTo);
1035 if (ok) {
1036 return p;
1037 }
1038 return SkPath();
1039 }))
1040 .function("isClosed", &SkContourMeasure::isClosed)
1041 .function("length", &SkContourMeasure::length);
1042
Kevin Lubick217056c2018-09-20 17:39:31 -04001043 class_<SkData>("SkData")
1044 .smart_ptr<sk_sp<SkData>>("sk_sp<SkData>>")
1045 .function("size", &SkData::size);
1046
Kevin Lubick6b921b72019-09-18 16:18:17 -04001047 class_<SkDrawable>("SkDrawable")
1048 .smart_ptr<sk_sp<SkDrawable>>("sk_sp<SkDrawable>>");
1049
Kevin Lubick61887c72019-09-26 13:20:50 -04001050#ifndef SK_NO_FONTS
Kevin Lubick35ac0382019-01-02 15:13:57 -05001051 class_<SkFont>("SkFont")
1052 .constructor<>()
1053 .constructor<sk_sp<SkTypeface>>()
1054 .constructor<sk_sp<SkTypeface>, SkScalar>()
1055 .constructor<sk_sp<SkTypeface>, SkScalar, SkScalar, SkScalar>()
1056 .function("getScaleX", &SkFont::getScaleX)
1057 .function("getSize", &SkFont::getSize)
1058 .function("getSkewX", &SkFont::getSkewX)
1059 .function("getTypeface", &SkFont::getTypeface, allow_raw_pointers())
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001060 .function("_getWidths", optional_override([](SkFont& self, uintptr_t /* char* */ sptr,
1061 size_t strLen, size_t expectedCodePoints,
1062 uintptr_t /* SkScalar* */ wptr) -> bool {
1063 char* str = reinterpret_cast<char*>(sptr);
1064 SkScalar* widths = reinterpret_cast<SkScalar*>(wptr);
1065
1066 SkGlyphID* glyphStorage = new SkGlyphID[expectedCodePoints];
1067 int actualCodePoints = self.textToGlyphs(str, strLen, SkTextEncoding::kUTF8,
1068 glyphStorage, expectedCodePoints);
1069 if (actualCodePoints != expectedCodePoints) {
1070 SkDebugf("Actually %d glyphs, expected only %d\n",
1071 actualCodePoints, expectedCodePoints);
1072 return false;
1073 }
1074
1075 self.getWidths(glyphStorage, actualCodePoints, widths);
1076 delete[] glyphStorage;
1077 return true;
1078 }))
Kevin Lubick35ac0382019-01-02 15:13:57 -05001079 .function("measureText", optional_override([](SkFont& self, std::string text) {
1080 // TODO(kjlubick): This does not work well for non-ascii
1081 // Need to maybe add a helper in interface.js that supports UTF-8
1082 // Otherwise, go with std::wstring and set UTF-32 encoding.
1083 return self.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
1084 }))
1085 .function("setScaleX", &SkFont::setScaleX)
1086 .function("setSize", &SkFont::setSize)
1087 .function("setSkewX", &SkFont::setSkewX)
1088 .function("setTypeface", &SkFont::setTypeface, allow_raw_pointers());
1089
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -05001090 class_<ShapedText>("ShapedText")
1091 .constructor<ShapedTextOpts>()
1092 .function("getBounds", &ShapedText::getBounds);
1093
Kevin Lubickddd0a332018-12-12 10:35:13 -05001094 class_<SkFontMgr>("SkFontMgr")
1095 .smart_ptr<sk_sp<SkFontMgr>>("sk_sp<SkFontMgr>")
Kevin Lubick61887c72019-09-26 13:20:50 -04001096 .class_function("_fromData", optional_override([](uintptr_t /* uint8_t** */ dPtr,
1097 uintptr_t /* size_t* */ sPtr,
1098 int numFonts)->sk_sp<SkFontMgr> {
1099 // See comment above for uintptr_t explanation
1100 auto datas = reinterpret_cast<const uint8_t**>(dPtr);
1101 auto sizes = reinterpret_cast<const size_t*>(sPtr);
1102
1103 return SkFontMgr_New_Custom_Data(datas, sizes, numFonts);
1104 }), allow_raw_pointers())
Kevin Lubickddd0a332018-12-12 10:35:13 -05001105 .class_function("RefDefault", &SkFontMgr::RefDefault)
1106#ifdef SK_DEBUG
1107 .function("dumpFamilies", optional_override([](SkFontMgr& self) {
1108 int numFam = self.countFamilies();
Kevin Lubick61887c72019-09-26 13:20:50 -04001109 SkDebugf("There are %d font families\n", numFam);
Kevin Lubickddd0a332018-12-12 10:35:13 -05001110 for (int i = 0 ; i< numFam; i++) {
1111 SkString s;
1112 self.getFamilyName(i, &s);
Kevin Lubick61887c72019-09-26 13:20:50 -04001113 SkDebugf("\t%s\n", s.c_str());
Kevin Lubickddd0a332018-12-12 10:35:13 -05001114 }
1115 }))
1116#endif
1117 .function("countFamilies", &SkFontMgr::countFamilies)
1118 .function("_makeTypefaceFromData", optional_override([](SkFontMgr& self,
1119 uintptr_t /* uint8_t* */ fPtr,
1120 int flen)->sk_sp<SkTypeface> {
1121 // See comment above for uintptr_t explanation
1122 uint8_t* font = reinterpret_cast<uint8_t*>(fPtr);
1123 sk_sp<SkData> fontData = SkData::MakeFromMalloc(font, flen);
1124
1125 return self.makeFromData(fontData);
1126 }), allow_raw_pointers());
Kevin Lubick61887c72019-09-26 13:20:50 -04001127#endif
Kevin Lubickddd0a332018-12-12 10:35:13 -05001128
Kevin Lubick217056c2018-09-20 17:39:31 -04001129 class_<SkImage>("SkImage")
1130 .smart_ptr<sk_sp<SkImage>>("sk_sp<SkImage>")
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001131 .function("height", &SkImage::height)
1132 .function("width", &SkImage::width)
Alexander Khovansky3e119332018-11-15 02:01:19 +03001133 .function("_encodeToData", select_overload<sk_sp<SkData>()const>(&SkImage::encodeToData))
Kevin Lubicka064c282019-04-04 09:28:53 -04001134 .function("_encodeToDataWithFormat", select_overload<sk_sp<SkData>(SkEncodedImageFormat encodedImageFormat, int quality)const>(&SkImage::encodeToData))
1135 // Allow localMatrix to be optional, so we have 2 declarations of these shaders
1136 .function("_makeShader", optional_override([](sk_sp<SkImage> self,
1137 SkTileMode tx, SkTileMode ty)->sk_sp<SkShader> {
1138 return self->makeShader(tx, ty, nullptr);
1139 }), allow_raw_pointers())
1140 .function("_makeShader", optional_override([](sk_sp<SkImage> self,
1141 SkTileMode tx, SkTileMode ty,
1142 const SimpleMatrix& lm)->sk_sp<SkShader> {
1143 SkMatrix localMatrix = toSkMatrix(lm);
1144
1145 return self->makeShader(tx, ty, &localMatrix);
Kevin Lubickd6b32ed2019-05-06 13:04:03 -04001146 }), allow_raw_pointers())
1147 .function("_readPixels", optional_override([](sk_sp<SkImage> self,
1148 SimpleImageInfo sii, uintptr_t /* uint8_t* */ pPtr,
1149 size_t dstRowBytes, int srcX, int srcY)->bool {
1150 // See comment above for uintptr_t explanation
1151 uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1152 SkImageInfo ii = toSkImageInfo(sii);
1153
1154 return self->readPixels(ii, pixels, dstRowBytes, srcX, srcY);
Kevin Lubicka064c282019-04-04 09:28:53 -04001155 }), allow_raw_pointers());
Kevin Lubick217056c2018-09-20 17:39:31 -04001156
Kevin Lubick15b40232019-10-29 09:55:39 -04001157 class_<SkImageFilter>("SkImageFilter")
1158 .smart_ptr<sk_sp<SkImageFilter>>("sk_sp<SkImageFilter>")
1159 .class_function("MakeBlur", optional_override([](SkScalar sigmaX, SkScalar sigmaY,
1160 SkTileMode tileMode, sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1161 // Emscripten does not like default args nor SkIRect* much
1162 return SkImageFilters::Blur(sigmaX, sigmaY, tileMode, input);
1163 }))
1164 .class_function("MakeColorFilter", optional_override([](sk_sp<SkColorFilter> cf,
1165 sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1166 // Emscripten does not like default args nor SkIRect* much
1167 return SkImageFilters::ColorFilter(cf, input);
1168 }))
Kevin Lubickd2677192019-11-15 14:13:20 -05001169 .class_function("MakeCompose", &SkImageFilters::Compose)
1170 .class_function("MakeMatrixTransform", optional_override([](SimpleMatrix sm, SkFilterQuality fq,
1171 sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1172 return SkImageFilters::MatrixTransform(toSkMatrix(sm), fq, input);
1173 }));
Kevin Lubick15b40232019-10-29 09:55:39 -04001174
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001175 class_<SkMaskFilter>("SkMaskFilter")
Kevin Lubick15b40232019-10-29 09:55:39 -04001176 .smart_ptr<sk_sp<SkMaskFilter>>("sk_sp<SkMaskFilter>")
1177 .class_function("MakeBlur", optional_override([](SkBlurStyle style, SkScalar sigma, bool respectCTM)->sk_sp<SkMaskFilter> {
1178 // Adds a little helper because emscripten doesn't expose default params.
1179 return SkMaskFilter::MakeBlur(style, sigma, respectCTM);
1180 }), allow_raw_pointers());
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001181
Kevin Lubick217056c2018-09-20 17:39:31 -04001182 class_<SkPaint>("SkPaint")
1183 .constructor<>()
1184 .function("copy", optional_override([](const SkPaint& self)->SkPaint {
1185 SkPaint p(self);
1186 return p;
1187 }))
Kevin Lubick12c0e502018-11-28 12:51:56 -05001188 .function("getBlendMode", &SkPaint::getBlendMode)
Kevin Lubickee91c072019-03-29 10:39:52 -04001189 .function("getColor", &SkPaint::getColor)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001190 .function("getFilterQuality", &SkPaint::getFilterQuality)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001191 .function("getStrokeCap", &SkPaint::getStrokeCap)
1192 .function("getStrokeJoin", &SkPaint::getStrokeJoin)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001193 .function("getStrokeMiter", &SkPaint::getStrokeMiter)
1194 .function("getStrokeWidth", &SkPaint::getStrokeWidth)
Kevin Lubick217056c2018-09-20 17:39:31 -04001195 .function("setAntiAlias", &SkPaint::setAntiAlias)
Kevin Lubick12c0e502018-11-28 12:51:56 -05001196 .function("setBlendMode", &SkPaint::setBlendMode)
Mike Reeddc2b98f2019-05-20 11:47:49 -04001197 .function("setColor", optional_override([](SkPaint& self, SkColor c) {
1198 self.setColor(c);
1199 }))
1200 .function("setColorf", optional_override([](SkPaint& self,
1201 float r, float g, float b, float a) {
1202 self.setColor({r, g, b, a});
1203 }))
Kevin Lubickd3729342019-09-12 11:11:25 -04001204 .function("setColorFilter", &SkPaint::setColorFilter)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001205 .function("setFilterQuality", &SkPaint::setFilterQuality)
Kevin Lubick15b40232019-10-29 09:55:39 -04001206 .function("setImageFilter", &SkPaint::setImageFilter)
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001207 .function("setMaskFilter", &SkPaint::setMaskFilter)
Kevin Lubick217056c2018-09-20 17:39:31 -04001208 .function("setPathEffect", &SkPaint::setPathEffect)
1209 .function("setShader", &SkPaint::setShader)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001210 .function("setStrokeCap", &SkPaint::setStrokeCap)
1211 .function("setStrokeJoin", &SkPaint::setStrokeJoin)
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001212 .function("setStrokeMiter", &SkPaint::setStrokeMiter)
1213 .function("setStrokeWidth", &SkPaint::setStrokeWidth)
Kevin Lubickec4903d2019-01-14 08:36:08 -05001214 .function("setStyle", &SkPaint::setStyle);
Kevin Lubick217056c2018-09-20 17:39:31 -04001215
1216 class_<SkPathEffect>("SkPathEffect")
1217 .smart_ptr<sk_sp<SkPathEffect>>("sk_sp<SkPathEffect>");
1218
Kevin Lubick217056c2018-09-20 17:39:31 -04001219 class_<SkPath>("SkPath")
1220 .constructor<>()
1221 .constructor<const SkPath&>()
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001222 .function("_addArc", &ApplyAddArc)
Kevin Lubick217056c2018-09-20 17:39:31 -04001223 // interface.js has 3 overloads of addPath
Kevin Lubicke384df42019-08-26 15:48:09 -04001224 .function("_addOval", &ApplyAddOval)
Kevin Lubick217056c2018-09-20 17:39:31 -04001225 .function("_addPath", &ApplyAddPath)
Kevin Lubick37ab53e2019-11-11 10:06:08 -05001226 .function("_addPoly", optional_override([](SkPath& self,
1227 uintptr_t /* SkPoint* */ pptr,
1228 int count, bool close)->void {
1229 // See comment above for uintptr_t explanation
1230 const SkPoint* pts = reinterpret_cast<const SkPoint*>(pptr);
1231 self.addPoly(pts, count, close);
1232 }))
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001233 // interface.js has 4 overloads of addRect
1234 .function("_addRect", &ApplyAddRect)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001235 // interface.js has 4 overloads of addRoundRect
1236 .function("_addRoundRect", &ApplyAddRoundRect)
Kevin Lubick217056c2018-09-20 17:39:31 -04001237 .function("_arcTo", &ApplyArcTo)
Kevin Lubick1646e7d2018-12-07 13:03:08 -05001238 .function("_arcTo", &ApplyArcToAngle)
Kevin Lubick79b71342019-11-01 14:36:52 -04001239 .function("_arcTo", &ApplyArcToArcSize)
Kevin Lubick217056c2018-09-20 17:39:31 -04001240 .function("_close", &ApplyClose)
1241 .function("_conicTo", &ApplyConicTo)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001242 .function("countPoints", &SkPath::countPoints)
Kevin Lubick1646e7d2018-12-07 13:03:08 -05001243 .function("contains", &SkPath::contains)
Kevin Lubick217056c2018-09-20 17:39:31 -04001244 .function("_cubicTo", &ApplyCubicTo)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001245 .function("getPoint", &SkPath::getPoint)
Kevin Lubick1646e7d2018-12-07 13:03:08 -05001246 .function("isEmpty", &SkPath::isEmpty)
Kevin Lubick2b79d1c2018-12-14 16:10:38 -05001247 .function("isVolatile", &SkPath::isVolatile)
Kevin Lubick217056c2018-09-20 17:39:31 -04001248 .function("_lineTo", &ApplyLineTo)
1249 .function("_moveTo", &ApplyMoveTo)
Kevin Lubick79b71342019-11-01 14:36:52 -04001250 .function("_quadTo", &ApplyQuadTo)
1251 .function("_rArcTo", &ApplyRArcToArcSize)
1252 .function("_rConicTo", &ApplyRConicTo)
1253 .function("_rCubicTo", &ApplyRCubicTo)
1254 .function("_rLineTo", &ApplyRLineTo)
1255 .function("_rMoveTo", &ApplyRMoveTo)
1256 .function("_rQuadTo", &ApplyRQuadTo)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001257 .function("reset", &ApplyReset)
1258 .function("rewind", &ApplyRewind)
Kevin Lubick2b79d1c2018-12-14 16:10:38 -05001259 .function("setIsVolatile", &SkPath::setIsVolatile)
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001260 .function("_transform", select_overload<void(SkPath&, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar)>(&ApplyTransform))
Kevin Lubick217056c2018-09-20 17:39:31 -04001261
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001262 // PathEffects
1263 .function("_dash", &ApplyDash)
1264 .function("_trim", &ApplyTrim)
1265 .function("_stroke", &ApplyStroke)
1266
1267 // PathOps
1268 .function("_simplify", &ApplySimplify)
1269 .function("_op", &ApplyPathOp)
1270
1271 // Exporting
1272 .function("toSVGString", &ToSVGString)
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001273 .function("toCmds", &ToCmds)
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001274
Mike Reed7d34dc72019-11-26 12:17:17 -05001275 .function("setFillType", select_overload<void(SkPathFillType)>(&SkPath::setFillType))
Kevin Lubick217056c2018-09-20 17:39:31 -04001276 .function("getFillType", &SkPath::getFillType)
1277 .function("getBounds", &SkPath::getBounds)
1278 .function("computeTightBounds", &SkPath::computeTightBounds)
1279 .function("equals", &Equals)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001280 .function("copy", &CopyPath)
1281#ifdef SK_DEBUG
1282 .function("dump", select_overload<void() const>(&SkPath::dump))
1283 .function("dumpHex", select_overload<void() const>(&SkPath::dumpHex))
1284#endif
1285 ;
Kevin Lubick217056c2018-09-20 17:39:31 -04001286
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001287 class_<SkPathMeasure>("SkPathMeasure")
1288 .constructor<const SkPath&, bool, SkScalar>()
1289 .function("getLength", &SkPathMeasure::getLength)
1290 .function("getPosTan", optional_override([](SkPathMeasure& self,
1291 SkScalar distance) -> PosTan {
1292 SkPoint p{0, 0};
1293 SkVector v{0, 0};
1294 if (!self.getPosTan(distance, &p, &v)) {
1295 SkDebugf("zero-length path in getPosTan\n");
1296 }
1297 return PosTan{p.x(), p.y(), v.x(), v.y()};
1298 }))
Kevin Lubick37ab53e2019-11-11 10:06:08 -05001299 .function("getSegment", optional_override([](SkPathMeasure& self, SkScalar startD,
1300 SkScalar stopD, bool startWithMoveTo) -> SkPath {
1301 SkPath p;
1302 bool ok = self.getSegment(startD, stopD, &p, startWithMoveTo);
1303 if (ok) {
1304 return p;
1305 }
1306 return SkPath();
1307 }))
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001308 .function("isClosed", &SkPathMeasure::isClosed)
1309 .function("nextContour", &SkPathMeasure::nextContour);
1310
Kevin Lubickcc13fd32019-04-05 13:00:01 -04001311 class_<SkPictureRecorder>("SkPictureRecorder")
1312 .constructor<>()
1313 .function("beginRecording", optional_override([](SkPictureRecorder& self,
1314 const SkRect& bounds) -> SkCanvas* {
1315 return self.beginRecording(bounds, nullptr, 0);
1316 }), allow_raw_pointers())
1317 .function("finishRecordingAsPicture", optional_override([](SkPictureRecorder& self)
1318 -> sk_sp<SkPicture> {
1319 return self.finishRecordingAsPicture(0);
1320 }), allow_raw_pointers());
1321
1322 class_<SkPicture>("SkPicture")
1323 .smart_ptr<sk_sp<SkPicture>>("sk_sp<SkPicture>")
1324 // The serialized format of an SkPicture (informally called an "skp"), is not something
1325 // that clients should ever rely on. It is useful when filing bug reports, but that's
1326 // about it. The format may change at anytime and no promises are made for backwards
1327 // or forward compatibility.
1328 .function("DEBUGONLY_serialize", optional_override([](SkPicture& self) -> sk_sp<SkData> {
1329 // Emscripten doesn't play well with optional arguments, which we don't
1330 // want to expose anyway.
1331 return self.serialize();
1332 }), allow_raw_pointers());
1333
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001334 class_<SkShader>("SkShader")
1335 .smart_ptr<sk_sp<SkShader>>("sk_sp<SkShader>");
1336
Kevin Lubick217056c2018-09-20 17:39:31 -04001337 class_<SkSurface>("SkSurface")
1338 .smart_ptr<sk_sp<SkSurface>>("sk_sp<SkSurface>")
Greg Danielbae71212019-03-01 15:24:35 -05001339 .function("_flush", select_overload<void()>(&SkSurface::flush))
Kevin Lubick543f3522019-03-08 10:04:28 -05001340 .function("getCanvas", &SkSurface::getCanvas, allow_raw_pointers())
1341 .function("height", &SkSurface::height)
Mike Reed114bde82018-11-21 09:12:09 -05001342 .function("makeImageSnapshot", select_overload<sk_sp<SkImage>()>(&SkSurface::makeImageSnapshot))
1343 .function("makeImageSnapshot", select_overload<sk_sp<SkImage>(const SkIRect& bounds)>(&SkSurface::makeImageSnapshot))
Kevin Lubick543f3522019-03-08 10:04:28 -05001344 .function("makeSurface", optional_override([](SkSurface& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
1345 return self.makeSurface(toSkImageInfo(sii));
1346 }), allow_raw_pointers())
1347 .function("width", &SkSurface::width);
Kevin Lubick217056c2018-09-20 17:39:31 -04001348
Kevin Lubick61887c72019-09-26 13:20:50 -04001349#ifndef SK_NO_FONTS
Kevin Lubickec4903d2019-01-14 08:36:08 -05001350 class_<SkTextBlob>("SkTextBlob")
1351 .smart_ptr<sk_sp<SkTextBlob>>("sk_sp<SkTextBlob>>")
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001352 .class_function("_MakeFromRSXform", optional_override([](uintptr_t /* char* */ sptr,
1353 size_t strBtyes,
1354 uintptr_t /* SkRSXform* */ xptr,
1355 const SkFont& font,
1356 SkTextEncoding encoding)->sk_sp<SkTextBlob> {
1357 // See comment above for uintptr_t explanation
1358 const char* str = reinterpret_cast<const char*>(sptr);
1359 const SkRSXform* xforms = reinterpret_cast<const SkRSXform*>(xptr);
1360
1361 return SkTextBlob::MakeFromRSXform(str, strBtyes, xforms, font, encoding);
1362 }), allow_raw_pointers())
Kevin Lubick543f3522019-03-08 10:04:28 -05001363 .class_function("_MakeFromText", optional_override([](uintptr_t /* char* */ sptr,
1364 size_t len, const SkFont& font,
1365 SkTextEncoding encoding)->sk_sp<SkTextBlob> {
Kevin Lubickec4903d2019-01-14 08:36:08 -05001366 // See comment above for uintptr_t explanation
1367 const char* str = reinterpret_cast<const char*>(sptr);
1368 return SkTextBlob::MakeFromText(str, len, font, encoding);
1369 }), allow_raw_pointers());
1370
Kevin Lubickddd0a332018-12-12 10:35:13 -05001371 class_<SkTypeface>("SkTypeface")
1372 .smart_ptr<sk_sp<SkTypeface>>("sk_sp<SkTypeface>");
Kevin Lubick61887c72019-09-26 13:20:50 -04001373#endif
Kevin Lubickddd0a332018-12-12 10:35:13 -05001374
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001375 class_<SkVertices>("SkVertices")
1376 .smart_ptr<sk_sp<SkVertices>>("sk_sp<SkVertices>")
1377 .function("_applyBones", optional_override([](SkVertices& self, uintptr_t /* Bone* */ bptr, int boneCount)->sk_sp<SkVertices> {
1378 // See comment above for uintptr_t explanation
1379 const Bone* bones = reinterpret_cast<const Bone*>(bptr);
1380 return self.applyBones(bones, boneCount);
1381 }))
1382 .function("bounds", &SkVertices::bounds)
1383 .function("mode", &SkVertices::mode)
1384 .function("uniqueID", &SkVertices::uniqueID)
Kevin Lubick12c0e502018-11-28 12:51:56 -05001385#ifdef SK_DEBUG
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001386 .function("dumpPositions", optional_override([](SkVertices& self)->void {
1387 auto pos = self.positions();
1388 for(int i = 0; i< self.vertexCount(); i++) {
1389 SkDebugf("position[%d] = (%f, %f)\n", i, pos[i].x(), pos[i].y());
1390 }
1391 }))
Kevin Lubick12c0e502018-11-28 12:51:56 -05001392#endif
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001393 .function("vertexCount", &SkVertices::vertexCount);
1394
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001395 // Not intended to be called directly by clients
1396 class_<SkVertices::Builder>("_SkVerticesBuilder")
1397 .constructor<SkVertices::VertexMode, int, int, uint32_t>()
1398 .function("boneIndices", optional_override([](SkVertices::Builder& self)->uintptr_t /* BoneIndices* */{
1399 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1400 return reinterpret_cast<uintptr_t>(self.boneIndices());
1401 }))
1402 .function("boneWeights", optional_override([](SkVertices::Builder& self)->uintptr_t /* BoneWeights* */{
1403 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1404 return reinterpret_cast<uintptr_t>(self.boneWeights());
1405 }))
1406 .function("colors", optional_override([](SkVertices::Builder& self)->uintptr_t /* SkColor* */{
1407 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1408 return reinterpret_cast<uintptr_t>(self.colors());
1409 }))
1410 .function("detach", &SkVertices::Builder::detach)
1411 .function("indices", optional_override([](SkVertices::Builder& self)->uintptr_t /* uint16_t* */{
1412 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1413 return reinterpret_cast<uintptr_t>(self.indices());
1414 }))
1415 .function("positions", optional_override([](SkVertices::Builder& self)->uintptr_t /* SkPoint* */{
1416 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1417 return reinterpret_cast<uintptr_t>(self.positions());
1418 }))
1419 .function("texCoords", optional_override([](SkVertices::Builder& self)->uintptr_t /* SkPoint* */{
1420 // Emscripten won't let us return bare pointers, but we can return ints just fine.
1421 return reinterpret_cast<uintptr_t>(self.texCoords());
1422 }));
1423
Kevin Lubickea905ec2018-11-30 14:05:58 -05001424 enum_<SkAlphaType>("AlphaType")
1425 .value("Opaque", SkAlphaType::kOpaque_SkAlphaType)
1426 .value("Premul", SkAlphaType::kPremul_SkAlphaType)
1427 .value("Unpremul", SkAlphaType::kUnpremul_SkAlphaType);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001428
1429 enum_<SkBlendMode>("BlendMode")
1430 .value("Clear", SkBlendMode::kClear)
1431 .value("Src", SkBlendMode::kSrc)
1432 .value("Dst", SkBlendMode::kDst)
1433 .value("SrcOver", SkBlendMode::kSrcOver)
1434 .value("DstOver", SkBlendMode::kDstOver)
1435 .value("SrcIn", SkBlendMode::kSrcIn)
1436 .value("DstIn", SkBlendMode::kDstIn)
1437 .value("SrcOut", SkBlendMode::kSrcOut)
1438 .value("DstOut", SkBlendMode::kDstOut)
1439 .value("SrcATop", SkBlendMode::kSrcATop)
1440 .value("DstATop", SkBlendMode::kDstATop)
1441 .value("Xor", SkBlendMode::kXor)
1442 .value("Plus", SkBlendMode::kPlus)
1443 .value("Modulate", SkBlendMode::kModulate)
1444 .value("Screen", SkBlendMode::kScreen)
1445 .value("Overlay", SkBlendMode::kOverlay)
1446 .value("Darken", SkBlendMode::kDarken)
1447 .value("Lighten", SkBlendMode::kLighten)
1448 .value("ColorDodge", SkBlendMode::kColorDodge)
1449 .value("ColorBurn", SkBlendMode::kColorBurn)
1450 .value("HardLight", SkBlendMode::kHardLight)
1451 .value("SoftLight", SkBlendMode::kSoftLight)
1452 .value("Difference", SkBlendMode::kDifference)
1453 .value("Exclusion", SkBlendMode::kExclusion)
1454 .value("Multiply", SkBlendMode::kMultiply)
1455 .value("Hue", SkBlendMode::kHue)
1456 .value("Saturation", SkBlendMode::kSaturation)
1457 .value("Color", SkBlendMode::kColor)
1458 .value("Luminosity", SkBlendMode::kLuminosity);
Kevin Lubick217056c2018-09-20 17:39:31 -04001459
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001460 enum_<SkBlurStyle>("BlurStyle")
1461 .value("Normal", SkBlurStyle::kNormal_SkBlurStyle)
1462 .value("Solid", SkBlurStyle::kSolid_SkBlurStyle)
1463 .value("Outer", SkBlurStyle::kOuter_SkBlurStyle)
1464 .value("Inner", SkBlurStyle::kInner_SkBlurStyle);
Kevin Lubick217056c2018-09-20 17:39:31 -04001465
Kevin Lubickeb2f6b02018-11-29 15:07:02 -05001466 enum_<SkClipOp>("ClipOp")
1467 .value("Difference", SkClipOp::kDifference)
1468 .value("Intersect", SkClipOp::kIntersect);
1469
Kevin Lubickea905ec2018-11-30 14:05:58 -05001470 enum_<SkColorType>("ColorType")
1471 .value("Alpha_8", SkColorType::kAlpha_8_SkColorType)
1472 .value("RGB_565", SkColorType::kRGB_565_SkColorType)
1473 .value("ARGB_4444", SkColorType::kARGB_4444_SkColorType)
1474 .value("RGBA_8888", SkColorType::kRGBA_8888_SkColorType)
1475 .value("RGB_888x", SkColorType::kRGB_888x_SkColorType)
1476 .value("BGRA_8888", SkColorType::kBGRA_8888_SkColorType)
1477 .value("RGBA_1010102", SkColorType::kRGBA_1010102_SkColorType)
1478 .value("RGB_101010x", SkColorType::kRGB_101010x_SkColorType)
1479 .value("Gray_8", SkColorType::kGray_8_SkColorType)
1480 .value("RGBA_F16", SkColorType::kRGBA_F16_SkColorType)
Robert Phillipsd470e1b2019-09-04 15:05:35 -04001481 .value("RGBA_F32", SkColorType::kRGBA_F32_SkColorType)
Robert Phillipsea1b30b2019-09-19 16:05:48 -04001482 .value("R8G8_unorm", SkColorType::kR8G8_unorm_SkColorType)
1483 .value("A16_unorm", SkColorType::kA16_unorm_SkColorType)
1484 .value("R16G16_unorm", SkColorType::kR16G16_unorm_SkColorType)
1485 .value("A16_float", SkColorType::kA16_float_SkColorType)
1486 .value("R16G16_float", SkColorType::kR16G16_float_SkColorType)
1487 .value("R16G16B16A16_unorm", SkColorType::kR16G16B16A16_unorm_SkColorType);
Kevin Lubickea905ec2018-11-30 14:05:58 -05001488
Mike Reed7d34dc72019-11-26 12:17:17 -05001489 enum_<SkPathFillType>("FillType")
1490 .value("Winding", SkPathFillType::kWinding)
1491 .value("EvenOdd", SkPathFillType::kEvenOdd)
1492 .value("InverseWinding", SkPathFillType::kInverseWinding)
1493 .value("InverseEvenOdd", SkPathFillType::kInverseEvenOdd);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001494
Kevin Lubick0a1293c2018-12-03 12:31:04 -05001495 enum_<SkFilterQuality>("FilterQuality")
1496 .value("None", SkFilterQuality::kNone_SkFilterQuality)
1497 .value("Low", SkFilterQuality::kLow_SkFilterQuality)
1498 .value("Medium", SkFilterQuality::kMedium_SkFilterQuality)
1499 .value("High", SkFilterQuality::kHigh_SkFilterQuality);
1500
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001501 enum_<SkEncodedImageFormat>("ImageFormat")
1502 .value("PNG", SkEncodedImageFormat::kPNG)
1503 .value("JPEG", SkEncodedImageFormat::kJPEG);
1504
1505 enum_<SkPaint::Style>("PaintStyle")
1506 .value("Fill", SkPaint::Style::kFill_Style)
1507 .value("Stroke", SkPaint::Style::kStroke_Style)
1508 .value("StrokeAndFill", SkPaint::Style::kStrokeAndFill_Style);
1509
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001510 enum_<SkPathOp>("PathOp")
1511 .value("Difference", SkPathOp::kDifference_SkPathOp)
1512 .value("Intersect", SkPathOp::kIntersect_SkPathOp)
1513 .value("Union", SkPathOp::kUnion_SkPathOp)
1514 .value("XOR", SkPathOp::kXOR_SkPathOp)
1515 .value("ReverseDifference", SkPathOp::kReverseDifference_SkPathOp);
1516
Kevin Lubick37ab53e2019-11-11 10:06:08 -05001517 enum_<SkCanvas::PointMode>("PointMode")
1518 .value("Points", SkCanvas::PointMode::kPoints_PointMode)
1519 .value("Lines", SkCanvas::PointMode::kLines_PointMode)
1520 .value("Polygon", SkCanvas::PointMode::kPolygon_PointMode);
1521
Kevin Lubickb9db3902018-11-26 11:47:54 -05001522 enum_<SkPaint::Cap>("StrokeCap")
1523 .value("Butt", SkPaint::Cap::kButt_Cap)
1524 .value("Round", SkPaint::Cap::kRound_Cap)
1525 .value("Square", SkPaint::Cap::kSquare_Cap);
1526
1527 enum_<SkPaint::Join>("StrokeJoin")
1528 .value("Miter", SkPaint::Join::kMiter_Join)
1529 .value("Round", SkPaint::Join::kRound_Join)
1530 .value("Bevel", SkPaint::Join::kBevel_Join);
1531
Kevin Lubickec4903d2019-01-14 08:36:08 -05001532 enum_<SkTextEncoding>("TextEncoding")
1533 .value("UTF8", SkTextEncoding::kUTF8)
1534 .value("UTF16", SkTextEncoding::kUTF16)
1535 .value("UTF32", SkTextEncoding::kUTF32)
1536 .value("GlyphID", SkTextEncoding::kGlyphID);
Kevin Lubickb9db3902018-11-26 11:47:54 -05001537
Mike Reed5c5de212019-04-03 16:51:47 -04001538 enum_<SkTileMode>("TileMode")
1539 .value("Clamp", SkTileMode::kClamp)
1540 .value("Repeat", SkTileMode::kRepeat)
1541 .value("Mirror", SkTileMode::kMirror)
Mike Reed5c5de212019-04-03 16:51:47 -04001542 .value("Decal", SkTileMode::kDecal);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001543
1544 enum_<SkVertices::VertexMode>("VertexMode")
1545 .value("Triangles", SkVertices::VertexMode::kTriangles_VertexMode)
1546 .value("TrianglesStrip", SkVertices::VertexMode::kTriangleStrip_VertexMode)
Kevin Lubickb9db3902018-11-26 11:47:54 -05001547 .value("TriangleFan", SkVertices::VertexMode::kTriangleFan_VertexMode);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001548
Kevin Lubick217056c2018-09-20 17:39:31 -04001549
1550 // A value object is much simpler than a class - it is returned as a JS
1551 // object and does not require delete().
1552 // https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#value-types
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -05001553 value_object<ShapedTextOpts>("ShapedTextOpts")
1554 .field("font", &ShapedTextOpts::font)
1555 .field("leftToRight", &ShapedTextOpts::leftToRight)
1556 .field("text", &ShapedTextOpts::text)
1557 .field("width", &ShapedTextOpts::width);
1558
Kevin Lubick217056c2018-09-20 17:39:31 -04001559 value_object<SkRect>("SkRect")
1560 .field("fLeft", &SkRect::fLeft)
1561 .field("fTop", &SkRect::fTop)
1562 .field("fRight", &SkRect::fRight)
1563 .field("fBottom", &SkRect::fBottom);
1564
Kevin Lubick2e5fe352019-09-03 12:59:06 -04001565 value_object<SimpleRRect>("SkRRect")
1566 .field("rect", &SimpleRRect::rect)
Kevin Lubick7d644e12019-09-11 14:22:22 -04001567 .field("rx1", &SimpleRRect::rx1)
1568 .field("ry1", &SimpleRRect::ry1)
1569 .field("rx2", &SimpleRRect::rx2)
1570 .field("ry2", &SimpleRRect::ry2)
1571 .field("rx3", &SimpleRRect::rx3)
1572 .field("ry3", &SimpleRRect::ry3)
1573 .field("rx4", &SimpleRRect::rx4)
1574 .field("ry4", &SimpleRRect::ry4);
Kevin Lubick2e5fe352019-09-03 12:59:06 -04001575
Mike Reed114bde82018-11-21 09:12:09 -05001576 value_object<SkIRect>("SkIRect")
1577 .field("fLeft", &SkIRect::fLeft)
1578 .field("fTop", &SkIRect::fTop)
1579 .field("fRight", &SkIRect::fRight)
1580 .field("fBottom", &SkIRect::fBottom);
1581
Kevin Lubick50f377e2019-09-11 15:23:00 -04001582 value_object<TonalColors>("TonalColors")
1583 .field("ambient", &TonalColors::ambientColor)
1584 .field("spot", &TonalColors::spotColor);
1585
Kevin Lubickea905ec2018-11-30 14:05:58 -05001586 value_object<SimpleImageInfo>("SkImageInfo")
1587 .field("width", &SimpleImageInfo::width)
1588 .field("height", &SimpleImageInfo::height)
1589 .field("colorType", &SimpleImageInfo::colorType)
1590 .field("alphaType", &SimpleImageInfo::alphaType);
1591
Kevin Lubick217056c2018-09-20 17:39:31 -04001592 // SkPoints can be represented by [x, y]
1593 value_array<SkPoint>("SkPoint")
1594 .element(&SkPoint::fX)
1595 .element(&SkPoint::fY);
1596
Kevin Lubick61ef7b22018-11-27 13:26:59 -05001597 // SkPoint3s can be represented by [x, y, z]
1598 value_array<SkPoint3>("SkPoint3")
1599 .element(&SkPoint3::fX)
1600 .element(&SkPoint3::fY)
1601 .element(&SkPoint3::fZ);
1602
Kevin Lubickd3cfbca2019-03-15 15:36:29 -04001603 // PosTan can be represented by [px, py, tx, ty]
1604 value_array<PosTan>("PosTan")
1605 .element(&PosTan::px)
1606 .element(&PosTan::py)
1607 .element(&PosTan::tx)
1608 .element(&PosTan::ty);
1609
Kevin Lubick217056c2018-09-20 17:39:31 -04001610 // {"w": Number, "h", Number}
1611 value_object<SkSize>("SkSize")
1612 .field("w", &SkSize::fWidth)
1613 .field("h", &SkSize::fHeight);
1614
1615 value_object<SkISize>("SkISize")
1616 .field("w", &SkISize::fWidth)
1617 .field("h", &SkISize::fHeight);
1618
Kevin Lubickec4903d2019-01-14 08:36:08 -05001619 value_object<StrokeOpts>("StrokeOpts")
1620 .field("width", &StrokeOpts::width)
1621 .field("miter_limit", &StrokeOpts::miter_limit)
1622 .field("join", &StrokeOpts::join)
1623 .field("cap", &StrokeOpts::cap)
1624 .field("precision", &StrokeOpts::precision);
1625
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001626 // Allows clients to supply a 1D array of 9 elements and the bindings
1627 // will automatically turn it into a 3x3 2D matrix.
1628 // e.g. path.transform([0,1,2,3,4,5,6,7,8])
1629 // This is likely simpler for the client than exposing SkMatrix
1630 // directly and requiring them to do a lot of .delete().
1631 value_array<SimpleMatrix>("SkMatrix")
1632 .element(&SimpleMatrix::scaleX)
1633 .element(&SimpleMatrix::skewX)
1634 .element(&SimpleMatrix::transX)
1635
1636 .element(&SimpleMatrix::skewY)
1637 .element(&SimpleMatrix::scaleY)
1638 .element(&SimpleMatrix::transY)
1639
1640 .element(&SimpleMatrix::pers0)
1641 .element(&SimpleMatrix::pers1)
1642 .element(&SimpleMatrix::pers2);
1643
Kevin Lubickee91c072019-03-29 10:39:52 -04001644 constant("TRANSPARENT", SK_ColorTRANSPARENT);
1645 constant("RED", SK_ColorRED);
1646 constant("BLUE", SK_ColorBLUE);
1647 constant("YELLOW", SK_ColorYELLOW);
1648 constant("CYAN", SK_ColorCYAN);
1649 constant("BLACK", SK_ColorBLACK);
1650 constant("WHITE", SK_ColorWHITE);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -04001651 // TODO(?)
1652
Kevin Lubickda3d8ac2019-01-07 11:08:55 -05001653 constant("MOVE_VERB", MOVE);
1654 constant("LINE_VERB", LINE);
1655 constant("QUAD_VERB", QUAD);
1656 constant("CONIC_VERB", CONIC);
1657 constant("CUBIC_VERB", CUBIC);
1658 constant("CLOSE_VERB", CLOSE);
Kevin Lubick77d9b5c2019-10-29 10:48:26 -04001659
1660 constant("SaveLayerInitWithPrevious", SkCanvas::SaveLayerFlagsSet::kInitWithPrevious_SaveLayerFlag);
1661 constant("SaveLayerF16ColorType", SkCanvas::SaveLayerFlagsSet::kF16ColorType);
1662
Kevin Lubick217056c2018-09-20 17:39:31 -04001663}