1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/android/SkAnimatedImage.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkAndroidCodec.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedImageFormat.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBBHFactory.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlender.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlurTypes.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorFilter.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageFilter.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageGenerator.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkM44.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMaskFilter.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathEffect.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathMeasure.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathUtils.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPicture.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint3.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRRect.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSerialProcs.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStrokeRec.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkVertices.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/Sk1DPathEffect.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/Sk2DPathEffect.h"
50*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkCornerPathEffect.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkDashPathEffect.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkDiscretePathEffect.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkImageFilters.h"
55*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkLumaColorFilter.h"
56*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkPerlinNoiseShader.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkRuntimeEffect.h"
58*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkTrimPathEffect.h"
59*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkJpegEncoder.h"
60*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkPngEncoder.h"
61*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkWebpEncoder.h"
62*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkOnce.h"
63*c8dee2aaSAndroid Build Coastguard Worker #include "include/utils/SkParsePath.h"
64*c8dee2aaSAndroid Build Coastguard Worker #include "include/utils/SkShadowUtils.h"
65*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkFloatBits.h"
66*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkPathPriv.h"
67*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkResourceCache.h"
68*c8dee2aaSAndroid Build Coastguard Worker #include "src/image/SkImage_Base.h"
69*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLCompiler.h"
70*c8dee2aaSAndroid Build Coastguard Worker
71*c8dee2aaSAndroid Build Coastguard Worker #include "modules/canvaskit/WasmCommon.h"
72*c8dee2aaSAndroid Build Coastguard Worker #include <emscripten.h>
73*c8dee2aaSAndroid Build Coastguard Worker #include <emscripten/bind.h>
74*c8dee2aaSAndroid Build Coastguard Worker #include <emscripten/html5.h>
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker #if defined(CK_ENABLE_WEBGL) || defined(CK_ENABLE_WEBGPU)
77*c8dee2aaSAndroid Build Coastguard Worker #define ENABLE_GPU
78*c8dee2aaSAndroid Build Coastguard Worker #endif
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker #ifdef ENABLE_GPU
81*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
82*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
83*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrExternalTextureGenerator.h"
84*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
85*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
86*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
87*c8dee2aaSAndroid Build Coastguard Worker #endif // ENABLE_GPU
88*c8dee2aaSAndroid Build Coastguard Worker
89*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
90*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
91*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
92*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
93*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLDirectContext.h"
94*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLInterface.h"
95*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLMakeWebGLInterface.h"
96*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
97*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/RefCntedCallback.h"
98*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
99*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
100*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLDefines.h"
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
103*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGL
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGPU
106*c8dee2aaSAndroid Build Coastguard Worker #include <emscripten/html5_webgpu.h>
107*c8dee2aaSAndroid Build Coastguard Worker #include <webgpu/webgpu.h>
108*c8dee2aaSAndroid Build Coastguard Worker #include <webgpu/webgpu_cpp.h>
109*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGPU
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
112*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h"
113*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMetrics.h"
114*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
115*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontTypes.h"
116*c8dee2aaSAndroid Build Coastguard Worker #include "src/ports/SkTypeface_FreeType.h"
117*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PARAGRAPH
118*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/Paragraph.h"
119*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_INCLUDE_PARAGRAPH
120*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_NO_FONTS
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PATHOPS
123*c8dee2aaSAndroid Build Coastguard Worker #include "include/pathops/SkPathOps.h"
124*c8dee2aaSAndroid Build Coastguard Worker #endif
125*c8dee2aaSAndroid Build Coastguard Worker
126*c8dee2aaSAndroid Build Coastguard Worker #if defined(CK_INCLUDE_RUNTIME_EFFECT)
127*c8dee2aaSAndroid Build Coastguard Worker #include "include/sksl/SkSLDebugTrace.h"
128*c8dee2aaSAndroid Build Coastguard Worker #endif
129*c8dee2aaSAndroid Build Coastguard Worker
130*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
131*c8dee2aaSAndroid Build Coastguard Worker #include "include/ports/SkFontMgr_data.h"
132*c8dee2aaSAndroid Build Coastguard Worker #endif
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker #if defined(CK_EMBED_FONT)
135*c8dee2aaSAndroid Build Coastguard Worker struct SkEmbeddedResource { const uint8_t* data; size_t size; };
136*c8dee2aaSAndroid Build Coastguard Worker struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count; };
137*c8dee2aaSAndroid Build Coastguard Worker extern "C" const SkEmbeddedResourceHeader SK_EMBEDDED_FONTS;
138*c8dee2aaSAndroid Build Coastguard Worker #endif
139*c8dee2aaSAndroid Build Coastguard Worker
140*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
141*c8dee2aaSAndroid Build Coastguard Worker #error "This define should not be set, as it brings in test-only things and bloats codesize."
142*c8dee2aaSAndroid Build Coastguard Worker #endif
143*c8dee2aaSAndroid Build Coastguard Worker
144*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_BMP)
145*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkBmpDecoder.h"
146*c8dee2aaSAndroid Build Coastguard Worker #endif
147*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_GIF)
148*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkGifDecoder.h"
149*c8dee2aaSAndroid Build Coastguard Worker #endif
150*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_ICO)
151*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkIcoDecoder.h"
152*c8dee2aaSAndroid Build Coastguard Worker #endif
153*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_JPEG)
154*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkJpegDecoder.h"
155*c8dee2aaSAndroid Build Coastguard Worker #endif
156*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_PNG)
157*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkPngDecoder.h"
158*c8dee2aaSAndroid Build Coastguard Worker #endif
159*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_WBMP)
160*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkWbmpDecoder.h"
161*c8dee2aaSAndroid Build Coastguard Worker #endif
162*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_WEBP)
163*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkWebpDecoder.h"
164*c8dee2aaSAndroid Build Coastguard Worker #endif
165*c8dee2aaSAndroid Build Coastguard Worker
166*c8dee2aaSAndroid Build Coastguard Worker // We'd like clients to be able to compile in as many or few codecs as they want (e.g. codesize)
DecodeImageData(sk_sp<SkData> data)167*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCodec> DecodeImageData(sk_sp<SkData> data) {
168*c8dee2aaSAndroid Build Coastguard Worker if (data == nullptr) {
169*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
170*c8dee2aaSAndroid Build Coastguard Worker }
171*c8dee2aaSAndroid Build Coastguard Worker // These codecs are arbitrarily ordered in alphabetical order.
172*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_BMP)
173*c8dee2aaSAndroid Build Coastguard Worker if (SkBmpDecoder::IsBmp(data->data(), data->size())) {
174*c8dee2aaSAndroid Build Coastguard Worker return SkBmpDecoder::Decode(data, nullptr);
175*c8dee2aaSAndroid Build Coastguard Worker }
176*c8dee2aaSAndroid Build Coastguard Worker #endif
177*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_GIF)
178*c8dee2aaSAndroid Build Coastguard Worker if (SkGifDecoder::IsGif(data->data(), data->size())) {
179*c8dee2aaSAndroid Build Coastguard Worker return SkGifDecoder::Decode(data, nullptr);
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker #endif
182*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_ICO)
183*c8dee2aaSAndroid Build Coastguard Worker if (SkIcoDecoder::IsIco(data->data(), data->size())) {
184*c8dee2aaSAndroid Build Coastguard Worker return SkIcoDecoder::Decode(data, nullptr);
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker #endif
187*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_JPEG)
188*c8dee2aaSAndroid Build Coastguard Worker if (SkJpegDecoder::IsJpeg(data->data(), data->size())) {
189*c8dee2aaSAndroid Build Coastguard Worker return SkJpegDecoder::Decode(data, nullptr);
190*c8dee2aaSAndroid Build Coastguard Worker }
191*c8dee2aaSAndroid Build Coastguard Worker #endif
192*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_PNG)
193*c8dee2aaSAndroid Build Coastguard Worker if (SkPngDecoder::IsPng(data->data(), data->size())) {
194*c8dee2aaSAndroid Build Coastguard Worker return SkPngDecoder::Decode(data, nullptr);
195*c8dee2aaSAndroid Build Coastguard Worker }
196*c8dee2aaSAndroid Build Coastguard Worker #endif
197*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_WBMP)
198*c8dee2aaSAndroid Build Coastguard Worker if (SkWbmpDecoder::IsWbmp(data->data(), data->size())) {
199*c8dee2aaSAndroid Build Coastguard Worker return SkWbmpDecoder::Decode(data, nullptr);
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker #endif
202*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_CODEC_DECODES_WEBP)
203*c8dee2aaSAndroid Build Coastguard Worker if (SkWebpDecoder::IsWebp(data->data(), data->size())) {
204*c8dee2aaSAndroid Build Coastguard Worker return SkWebpDecoder::Decode(data, nullptr);
205*c8dee2aaSAndroid Build Coastguard Worker }
206*c8dee2aaSAndroid Build Coastguard Worker #endif
207*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
208*c8dee2aaSAndroid Build Coastguard Worker }
209*c8dee2aaSAndroid Build Coastguard Worker
210*c8dee2aaSAndroid Build Coastguard Worker struct OptionalMatrix : SkMatrix {
OptionalMatrixOptionalMatrix211*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix(WASMPointerF32 mPtr) {
212*c8dee2aaSAndroid Build Coastguard Worker if (mPtr) {
213*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* nineMatrixValues = reinterpret_cast<const SkScalar*>(mPtr);
214*c8dee2aaSAndroid Build Coastguard Worker this->set9(nineMatrixValues);
215*c8dee2aaSAndroid Build Coastguard Worker }
216*c8dee2aaSAndroid Build Coastguard Worker }
217*c8dee2aaSAndroid Build Coastguard Worker };
218*c8dee2aaSAndroid Build Coastguard Worker
ptrToSkColor4f(WASMPointerF32 cPtr)219*c8dee2aaSAndroid Build Coastguard Worker SkColor4f ptrToSkColor4f(WASMPointerF32 cPtr) {
220*c8dee2aaSAndroid Build Coastguard Worker float* fourFloats = reinterpret_cast<float*>(cPtr);
221*c8dee2aaSAndroid Build Coastguard Worker SkColor4f color;
222*c8dee2aaSAndroid Build Coastguard Worker memcpy(&color, fourFloats, 4 * sizeof(float));
223*c8dee2aaSAndroid Build Coastguard Worker return color;
224*c8dee2aaSAndroid Build Coastguard Worker }
225*c8dee2aaSAndroid Build Coastguard Worker
ptrToSkRRect(WASMPointerF32 fPtr)226*c8dee2aaSAndroid Build Coastguard Worker SkRRect ptrToSkRRect(WASMPointerF32 fPtr) {
227*c8dee2aaSAndroid Build Coastguard Worker // In order, these floats should be 4 floats for the rectangle
228*c8dee2aaSAndroid Build Coastguard Worker // (left, top, right, bottom) and then 8 floats for the radii
229*c8dee2aaSAndroid Build Coastguard Worker // (upper left, upper right, lower right, lower left).
230*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* twelveFloats = reinterpret_cast<const SkScalar*>(fPtr);
231*c8dee2aaSAndroid Build Coastguard Worker const SkRect rect = reinterpret_cast<const SkRect*>(twelveFloats)[0];
232*c8dee2aaSAndroid Build Coastguard Worker const SkVector* radiiValues = reinterpret_cast<const SkVector*>(twelveFloats + 4);
233*c8dee2aaSAndroid Build Coastguard Worker
234*c8dee2aaSAndroid Build Coastguard Worker SkRRect rr;
235*c8dee2aaSAndroid Build Coastguard Worker rr.setRectRadii(rect, radiiValues);
236*c8dee2aaSAndroid Build Coastguard Worker return rr;
237*c8dee2aaSAndroid Build Coastguard Worker }
238*c8dee2aaSAndroid Build Coastguard Worker
239*c8dee2aaSAndroid Build Coastguard Worker // Surface creation structs and helpers
240*c8dee2aaSAndroid Build Coastguard Worker struct SimpleImageInfo {
241*c8dee2aaSAndroid Build Coastguard Worker int width;
242*c8dee2aaSAndroid Build Coastguard Worker int height;
243*c8dee2aaSAndroid Build Coastguard Worker SkColorType colorType;
244*c8dee2aaSAndroid Build Coastguard Worker SkAlphaType alphaType;
245*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace;
246*c8dee2aaSAndroid Build Coastguard Worker };
247*c8dee2aaSAndroid Build Coastguard Worker
toSkImageInfo(const SimpleImageInfo & sii)248*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo toSkImageInfo(const SimpleImageInfo& sii) {
249*c8dee2aaSAndroid Build Coastguard Worker return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType,
250*c8dee2aaSAndroid Build Coastguard Worker sii.colorSpace ? sii.colorSpace : SkColorSpace::MakeSRGB());
251*c8dee2aaSAndroid Build Coastguard Worker }
252*c8dee2aaSAndroid Build Coastguard Worker
253*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
254*c8dee2aaSAndroid Build Coastguard Worker
255*c8dee2aaSAndroid Build Coastguard Worker // Set the pixel format based on the colortype.
256*c8dee2aaSAndroid Build Coastguard Worker // These degrees of freedom are removed from canvaskit only to keep the interface simpler.
257*c8dee2aaSAndroid Build Coastguard Worker struct ColorSettings {
ColorSettingsColorSettings258*c8dee2aaSAndroid Build Coastguard Worker ColorSettings(sk_sp<SkColorSpace> colorSpace) {
259*c8dee2aaSAndroid Build Coastguard Worker if (colorSpace == nullptr || colorSpace->isSRGB()) {
260*c8dee2aaSAndroid Build Coastguard Worker colorType = kRGBA_8888_SkColorType;
261*c8dee2aaSAndroid Build Coastguard Worker pixFormat = GR_GL_RGBA8;
262*c8dee2aaSAndroid Build Coastguard Worker } else {
263*c8dee2aaSAndroid Build Coastguard Worker colorType = kRGBA_F16_SkColorType;
264*c8dee2aaSAndroid Build Coastguard Worker pixFormat = GR_GL_RGBA16F;
265*c8dee2aaSAndroid Build Coastguard Worker }
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker SkColorType colorType;
268*c8dee2aaSAndroid Build Coastguard Worker GrGLenum pixFormat;
269*c8dee2aaSAndroid Build Coastguard Worker };
270*c8dee2aaSAndroid Build Coastguard Worker
MakeGrContext()271*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrDirectContext> MakeGrContext() {
272*c8dee2aaSAndroid Build Coastguard Worker // We assume that any calls we make to GL for the remainder of this function will go to the
273*c8dee2aaSAndroid Build Coastguard Worker // desired WebGL Context.
274*c8dee2aaSAndroid Build Coastguard Worker // setup interface.
275*c8dee2aaSAndroid Build Coastguard Worker auto interface = GrGLInterfaces::MakeWebGL();
276*c8dee2aaSAndroid Build Coastguard Worker // setup context
277*c8dee2aaSAndroid Build Coastguard Worker return GrDirectContexts::MakeGL(interface);
278*c8dee2aaSAndroid Build Coastguard Worker }
279*c8dee2aaSAndroid Build Coastguard Worker
MakeOnScreenGLSurface(sk_sp<GrDirectContext> dContext,int width,int height,sk_sp<SkColorSpace> colorSpace,int sampleCnt,int stencil)280*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrDirectContext> dContext, int width, int height,
281*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace, int sampleCnt, int stencil) {
282*c8dee2aaSAndroid Build Coastguard Worker // WebGL should already be clearing the color and stencil buffers, but do it again here to
283*c8dee2aaSAndroid Build Coastguard Worker // ensure Skia receives them in the expected state.
284*c8dee2aaSAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, 0);
285*c8dee2aaSAndroid Build Coastguard Worker glClearColor(0, 0, 0, 0);
286*c8dee2aaSAndroid Build Coastguard Worker glClearStencil(0);
287*c8dee2aaSAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
288*c8dee2aaSAndroid Build Coastguard Worker dContext->resetContext(kRenderTarget_GrGLBackendState | kMisc_GrGLBackendState);
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker // The on-screen canvas is FBO 0. Wrap it in a Skia render target so Skia can render to it.
291*c8dee2aaSAndroid Build Coastguard Worker GrGLFramebufferInfo info;
292*c8dee2aaSAndroid Build Coastguard Worker info.fFBOID = 0;
293*c8dee2aaSAndroid Build Coastguard Worker
294*c8dee2aaSAndroid Build Coastguard Worker if (!colorSpace) {
295*c8dee2aaSAndroid Build Coastguard Worker colorSpace = SkColorSpace::MakeSRGB();
296*c8dee2aaSAndroid Build Coastguard Worker }
297*c8dee2aaSAndroid Build Coastguard Worker
298*c8dee2aaSAndroid Build Coastguard Worker const auto colorSettings = ColorSettings(colorSpace);
299*c8dee2aaSAndroid Build Coastguard Worker info.fFormat = colorSettings.pixFormat;
300*c8dee2aaSAndroid Build Coastguard Worker auto target = GrBackendRenderTargets::MakeGL(width, height, sampleCnt, stencil, info);
301*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface(SkSurfaces::WrapBackendRenderTarget(dContext.get(),
302*c8dee2aaSAndroid Build Coastguard Worker target,
303*c8dee2aaSAndroid Build Coastguard Worker kBottomLeft_GrSurfaceOrigin,
304*c8dee2aaSAndroid Build Coastguard Worker colorSettings.colorType,
305*c8dee2aaSAndroid Build Coastguard Worker colorSpace,
306*c8dee2aaSAndroid Build Coastguard Worker nullptr));
307*c8dee2aaSAndroid Build Coastguard Worker return surface;
308*c8dee2aaSAndroid Build Coastguard Worker }
309*c8dee2aaSAndroid Build Coastguard Worker
MakeOnScreenGLSurface(sk_sp<GrDirectContext> dContext,int width,int height,sk_sp<SkColorSpace> colorSpace)310*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrDirectContext> dContext, int width, int height,
311*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace) {
312*c8dee2aaSAndroid Build Coastguard Worker GrGLint sampleCnt;
313*c8dee2aaSAndroid Build Coastguard Worker glGetIntegerv(GL_SAMPLES, &sampleCnt);
314*c8dee2aaSAndroid Build Coastguard Worker
315*c8dee2aaSAndroid Build Coastguard Worker GrGLint stencil;
316*c8dee2aaSAndroid Build Coastguard Worker glGetIntegerv(GL_STENCIL_BITS, &stencil);
317*c8dee2aaSAndroid Build Coastguard Worker
318*c8dee2aaSAndroid Build Coastguard Worker return MakeOnScreenGLSurface(dContext, width, height, colorSpace, sampleCnt, stencil);
319*c8dee2aaSAndroid Build Coastguard Worker }
320*c8dee2aaSAndroid Build Coastguard Worker
MakeRenderTarget(sk_sp<GrDirectContext> dContext,int width,int height)321*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrDirectContext> dContext, int width, int height) {
322*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo info = SkImageInfo::MakeN32(
323*c8dee2aaSAndroid Build Coastguard Worker width, height, SkAlphaType::kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
324*c8dee2aaSAndroid Build Coastguard Worker
325*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface(SkSurfaces::RenderTarget(dContext.get(),
326*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kYes,
327*c8dee2aaSAndroid Build Coastguard Worker info,
328*c8dee2aaSAndroid Build Coastguard Worker 0,
329*c8dee2aaSAndroid Build Coastguard Worker kBottomLeft_GrSurfaceOrigin,
330*c8dee2aaSAndroid Build Coastguard Worker nullptr,
331*c8dee2aaSAndroid Build Coastguard Worker true));
332*c8dee2aaSAndroid Build Coastguard Worker return surface;
333*c8dee2aaSAndroid Build Coastguard Worker }
334*c8dee2aaSAndroid Build Coastguard Worker
MakeRenderTarget(sk_sp<GrDirectContext> dContext,SimpleImageInfo sii)335*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrDirectContext> dContext, SimpleImageInfo sii) {
336*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface(SkSurfaces::RenderTarget(dContext.get(),
337*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kYes,
338*c8dee2aaSAndroid Build Coastguard Worker toSkImageInfo(sii),
339*c8dee2aaSAndroid Build Coastguard Worker 0,
340*c8dee2aaSAndroid Build Coastguard Worker kBottomLeft_GrSurfaceOrigin,
341*c8dee2aaSAndroid Build Coastguard Worker nullptr,
342*c8dee2aaSAndroid Build Coastguard Worker true));
343*c8dee2aaSAndroid Build Coastguard Worker return surface;
344*c8dee2aaSAndroid Build Coastguard Worker }
345*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGL
346*c8dee2aaSAndroid Build Coastguard Worker
347*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGPU
348*c8dee2aaSAndroid Build Coastguard Worker
MakeGrContext()349*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrDirectContext> MakeGrContext() {
350*c8dee2aaSAndroid Build Coastguard Worker GrContextOptions options;
351*c8dee2aaSAndroid Build Coastguard Worker wgpu::Device device = wgpu::Device::Acquire(emscripten_webgpu_get_device());
352*c8dee2aaSAndroid Build Coastguard Worker return GrDirectContext::MakeDawn(device, options);
353*c8dee2aaSAndroid Build Coastguard Worker }
354*c8dee2aaSAndroid Build Coastguard Worker
MakeGPUTextureSurface(sk_sp<GrDirectContext> dContext,uint32_t textureHandle,uint32_t textureFormat,int width,int height,sk_sp<SkColorSpace> colorSpace)355*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> MakeGPUTextureSurface(sk_sp<GrDirectContext> dContext,
356*c8dee2aaSAndroid Build Coastguard Worker uint32_t textureHandle, uint32_t textureFormat,
357*c8dee2aaSAndroid Build Coastguard Worker int width, int height, sk_sp<SkColorSpace> colorSpace) {
358*c8dee2aaSAndroid Build Coastguard Worker if (!colorSpace) {
359*c8dee2aaSAndroid Build Coastguard Worker colorSpace = SkColorSpace::MakeSRGB();
360*c8dee2aaSAndroid Build Coastguard Worker }
361*c8dee2aaSAndroid Build Coastguard Worker
362*c8dee2aaSAndroid Build Coastguard Worker wgpu::TextureFormat format = static_cast<wgpu::TextureFormat>(textureFormat);
363*c8dee2aaSAndroid Build Coastguard Worker wgpu::Texture texture(emscripten_webgpu_import_texture(textureHandle));
364*c8dee2aaSAndroid Build Coastguard Worker emscripten_webgpu_release_js_handle(textureHandle);
365*c8dee2aaSAndroid Build Coastguard Worker
366*c8dee2aaSAndroid Build Coastguard Worker // GrDawnRenderTargetInfo currently only supports a 1-mip TextureView.
367*c8dee2aaSAndroid Build Coastguard Worker constexpr uint32_t mipLevelCount = 1;
368*c8dee2aaSAndroid Build Coastguard Worker constexpr uint32_t sampleCount = 1;
369*c8dee2aaSAndroid Build Coastguard Worker
370*c8dee2aaSAndroid Build Coastguard Worker GrDawnTextureInfo info;
371*c8dee2aaSAndroid Build Coastguard Worker info.fTexture = texture;
372*c8dee2aaSAndroid Build Coastguard Worker info.fFormat = format;
373*c8dee2aaSAndroid Build Coastguard Worker info.fLevelCount = mipLevelCount;
374*c8dee2aaSAndroid Build Coastguard Worker
375*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture target(width, height, info);
376*c8dee2aaSAndroid Build Coastguard Worker return SkSurfaces::WrapBackendTexture(
377*c8dee2aaSAndroid Build Coastguard Worker dContext.get(),
378*c8dee2aaSAndroid Build Coastguard Worker target,
379*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
380*c8dee2aaSAndroid Build Coastguard Worker sampleCount,
381*c8dee2aaSAndroid Build Coastguard Worker colorSpace->isSRGB() ? kRGBA_8888_SkColorType : kRGBA_F16_SkColorType,
382*c8dee2aaSAndroid Build Coastguard Worker colorSpace,
383*c8dee2aaSAndroid Build Coastguard Worker nullptr);
384*c8dee2aaSAndroid Build Coastguard Worker }
385*c8dee2aaSAndroid Build Coastguard Worker
ReplaceBackendTexture(SkSurface & surface,uint32_t textureHandle,uint32_t textureFormat,int width,int height)386*c8dee2aaSAndroid Build Coastguard Worker bool ReplaceBackendTexture(SkSurface& surface, uint32_t textureHandle, uint32_t textureFormat,
387*c8dee2aaSAndroid Build Coastguard Worker int width, int height) {
388*c8dee2aaSAndroid Build Coastguard Worker wgpu::TextureFormat format = static_cast<wgpu::TextureFormat>(textureFormat);
389*c8dee2aaSAndroid Build Coastguard Worker wgpu::Texture texture(emscripten_webgpu_import_texture(textureHandle));
390*c8dee2aaSAndroid Build Coastguard Worker emscripten_webgpu_release_js_handle(textureHandle);
391*c8dee2aaSAndroid Build Coastguard Worker
392*c8dee2aaSAndroid Build Coastguard Worker GrDawnTextureInfo info;
393*c8dee2aaSAndroid Build Coastguard Worker info.fTexture = texture;
394*c8dee2aaSAndroid Build Coastguard Worker info.fFormat = format;
395*c8dee2aaSAndroid Build Coastguard Worker info.fLevelCount = 1;
396*c8dee2aaSAndroid Build Coastguard Worker
397*c8dee2aaSAndroid Build Coastguard Worker // Use kDiscard_ContentChangeMode to discard the contents of the old backing texture. This not
398*c8dee2aaSAndroid Build Coastguard Worker // only avoids an unnecessary blit, we also don't support copying the contents of a swapchain
399*c8dee2aaSAndroid Build Coastguard Worker // texture due to the default GPUCanvasConfiguration usage bits we used when configuring the
400*c8dee2aaSAndroid Build Coastguard Worker // GPUCanvasContext in JS.
401*c8dee2aaSAndroid Build Coastguard Worker //
402*c8dee2aaSAndroid Build Coastguard Worker // The default usage bits only contain GPUTextureUsage.RENDER_ATTACHMENT. To support a copy we
403*c8dee2aaSAndroid Build Coastguard Worker // would need to also set GPUTextureUsage.TEXTURE_BINDING (to sample it in a shader) or
404*c8dee2aaSAndroid Build Coastguard Worker // GPUTextureUsage.COPY_SRC (for a copy command).
405*c8dee2aaSAndroid Build Coastguard Worker //
406*c8dee2aaSAndroid Build Coastguard Worker // See https://www.w3.org/TR/webgpu/#namespacedef-gputextureusage and
407*c8dee2aaSAndroid Build Coastguard Worker // https://www.w3.org/TR/webgpu/#dictdef-gpucanvasconfiguration.
408*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture target(width, height, info);
409*c8dee2aaSAndroid Build Coastguard Worker return surface.replaceBackendTexture(target, kTopLeft_GrSurfaceOrigin,
410*c8dee2aaSAndroid Build Coastguard Worker SkSurface::kDiscard_ContentChangeMode);
411*c8dee2aaSAndroid Build Coastguard Worker }
412*c8dee2aaSAndroid Build Coastguard Worker
413*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGPU
414*c8dee2aaSAndroid Build Coastguard Worker
415*c8dee2aaSAndroid Build Coastguard Worker //========================================================================================
416*c8dee2aaSAndroid Build Coastguard Worker // Path things
417*c8dee2aaSAndroid Build Coastguard Worker //========================================================================================
418*c8dee2aaSAndroid Build Coastguard Worker
419*c8dee2aaSAndroid Build Coastguard Worker // All these Apply* methods are simple wrappers to avoid returning an object.
420*c8dee2aaSAndroid Build Coastguard Worker // The default WASM bindings produce code that will leak if a return value
421*c8dee2aaSAndroid Build Coastguard Worker // isn't assigned to a JS variable and has delete() called on it.
422*c8dee2aaSAndroid Build Coastguard Worker // These Apply methods, combined with the smarter binding code allow for chainable
423*c8dee2aaSAndroid Build Coastguard Worker // commands that don't leak if the return value is ignored (i.e. when used intuitively).
ApplyAddPath(SkPath & orig,const SkPath & newPath,SkScalar scaleX,SkScalar skewX,SkScalar transX,SkScalar skewY,SkScalar scaleY,SkScalar transY,SkScalar pers0,SkScalar pers1,SkScalar pers2,bool extendPath)424*c8dee2aaSAndroid Build Coastguard Worker void ApplyAddPath(SkPath& orig, const SkPath& newPath,
425*c8dee2aaSAndroid Build Coastguard Worker SkScalar scaleX, SkScalar skewX, SkScalar transX,
426*c8dee2aaSAndroid Build Coastguard Worker SkScalar skewY, SkScalar scaleY, SkScalar transY,
427*c8dee2aaSAndroid Build Coastguard Worker SkScalar pers0, SkScalar pers1, SkScalar pers2,
428*c8dee2aaSAndroid Build Coastguard Worker bool extendPath) {
429*c8dee2aaSAndroid Build Coastguard Worker SkMatrix m = SkMatrix::MakeAll(scaleX, skewX , transX,
430*c8dee2aaSAndroid Build Coastguard Worker skewY , scaleY, transY,
431*c8dee2aaSAndroid Build Coastguard Worker pers0 , pers1 , pers2);
432*c8dee2aaSAndroid Build Coastguard Worker orig.addPath(newPath, m, extendPath ? SkPath::kExtend_AddPathMode :
433*c8dee2aaSAndroid Build Coastguard Worker SkPath::kAppend_AddPathMode);
434*c8dee2aaSAndroid Build Coastguard Worker }
435*c8dee2aaSAndroid Build Coastguard Worker
ApplyArcToTangent(SkPath & p,SkScalar x1,SkScalar y1,SkScalar x2,SkScalar y2,SkScalar radius)436*c8dee2aaSAndroid Build Coastguard Worker void ApplyArcToTangent(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
437*c8dee2aaSAndroid Build Coastguard Worker SkScalar radius) {
438*c8dee2aaSAndroid Build Coastguard Worker p.arcTo(x1, y1, x2, y2, radius);
439*c8dee2aaSAndroid Build Coastguard Worker }
440*c8dee2aaSAndroid Build Coastguard Worker
ApplyArcToArcSize(SkPath & orig,SkScalar rx,SkScalar ry,SkScalar xAxisRotate,bool useSmallArc,bool ccw,SkScalar x,SkScalar y)441*c8dee2aaSAndroid Build Coastguard Worker void ApplyArcToArcSize(SkPath& orig, SkScalar rx, SkScalar ry, SkScalar xAxisRotate,
442*c8dee2aaSAndroid Build Coastguard Worker bool useSmallArc, bool ccw, SkScalar x, SkScalar y) {
443*c8dee2aaSAndroid Build Coastguard Worker auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize : SkPath::ArcSize::kLarge_ArcSize;
444*c8dee2aaSAndroid Build Coastguard Worker auto sweep = ccw ? SkPathDirection::kCCW : SkPathDirection::kCW;
445*c8dee2aaSAndroid Build Coastguard Worker orig.arcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
446*c8dee2aaSAndroid Build Coastguard Worker }
447*c8dee2aaSAndroid Build Coastguard Worker
ApplyRArcToArcSize(SkPath & orig,SkScalar rx,SkScalar ry,SkScalar xAxisRotate,bool useSmallArc,bool ccw,SkScalar dx,SkScalar dy)448*c8dee2aaSAndroid Build Coastguard Worker void ApplyRArcToArcSize(SkPath& orig, SkScalar rx, SkScalar ry, SkScalar xAxisRotate,
449*c8dee2aaSAndroid Build Coastguard Worker bool useSmallArc, bool ccw, SkScalar dx, SkScalar dy) {
450*c8dee2aaSAndroid Build Coastguard Worker auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize : SkPath::ArcSize::kLarge_ArcSize;
451*c8dee2aaSAndroid Build Coastguard Worker auto sweep = ccw ? SkPathDirection::kCCW : SkPathDirection::kCW;
452*c8dee2aaSAndroid Build Coastguard Worker orig.rArcTo(rx, ry, xAxisRotate, arcSize, sweep, dx, dy);
453*c8dee2aaSAndroid Build Coastguard Worker }
454*c8dee2aaSAndroid Build Coastguard Worker
ApplyClose(SkPath & p)455*c8dee2aaSAndroid Build Coastguard Worker void ApplyClose(SkPath& p) {
456*c8dee2aaSAndroid Build Coastguard Worker p.close();
457*c8dee2aaSAndroid Build Coastguard Worker }
458*c8dee2aaSAndroid Build Coastguard Worker
ApplyConicTo(SkPath & p,SkScalar x1,SkScalar y1,SkScalar x2,SkScalar y2,SkScalar w)459*c8dee2aaSAndroid Build Coastguard Worker void ApplyConicTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
460*c8dee2aaSAndroid Build Coastguard Worker SkScalar w) {
461*c8dee2aaSAndroid Build Coastguard Worker p.conicTo(x1, y1, x2, y2, w);
462*c8dee2aaSAndroid Build Coastguard Worker }
463*c8dee2aaSAndroid Build Coastguard Worker
ApplyRConicTo(SkPath & p,SkScalar dx1,SkScalar dy1,SkScalar dx2,SkScalar dy2,SkScalar w)464*c8dee2aaSAndroid Build Coastguard Worker void ApplyRConicTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
465*c8dee2aaSAndroid Build Coastguard Worker SkScalar w) {
466*c8dee2aaSAndroid Build Coastguard Worker p.rConicTo(dx1, dy1, dx2, dy2, w);
467*c8dee2aaSAndroid Build Coastguard Worker }
468*c8dee2aaSAndroid Build Coastguard Worker
ApplyCubicTo(SkPath & p,SkScalar x1,SkScalar y1,SkScalar x2,SkScalar y2,SkScalar x3,SkScalar y3)469*c8dee2aaSAndroid Build Coastguard Worker void ApplyCubicTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
470*c8dee2aaSAndroid Build Coastguard Worker SkScalar x3, SkScalar y3) {
471*c8dee2aaSAndroid Build Coastguard Worker p.cubicTo(x1, y1, x2, y2, x3, y3);
472*c8dee2aaSAndroid Build Coastguard Worker }
473*c8dee2aaSAndroid Build Coastguard Worker
ApplyRCubicTo(SkPath & p,SkScalar dx1,SkScalar dy1,SkScalar dx2,SkScalar dy2,SkScalar dx3,SkScalar dy3)474*c8dee2aaSAndroid Build Coastguard Worker void ApplyRCubicTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
475*c8dee2aaSAndroid Build Coastguard Worker SkScalar dx3, SkScalar dy3) {
476*c8dee2aaSAndroid Build Coastguard Worker p.rCubicTo(dx1, dy1, dx2, dy2, dx3, dy3);
477*c8dee2aaSAndroid Build Coastguard Worker }
478*c8dee2aaSAndroid Build Coastguard Worker
ApplyLineTo(SkPath & p,SkScalar x,SkScalar y)479*c8dee2aaSAndroid Build Coastguard Worker void ApplyLineTo(SkPath& p, SkScalar x, SkScalar y) {
480*c8dee2aaSAndroid Build Coastguard Worker p.lineTo(x, y);
481*c8dee2aaSAndroid Build Coastguard Worker }
482*c8dee2aaSAndroid Build Coastguard Worker
ApplyRLineTo(SkPath & p,SkScalar dx,SkScalar dy)483*c8dee2aaSAndroid Build Coastguard Worker void ApplyRLineTo(SkPath& p, SkScalar dx, SkScalar dy) {
484*c8dee2aaSAndroid Build Coastguard Worker p.rLineTo(dx, dy);
485*c8dee2aaSAndroid Build Coastguard Worker }
486*c8dee2aaSAndroid Build Coastguard Worker
ApplyMoveTo(SkPath & p,SkScalar x,SkScalar y)487*c8dee2aaSAndroid Build Coastguard Worker void ApplyMoveTo(SkPath& p, SkScalar x, SkScalar y) {
488*c8dee2aaSAndroid Build Coastguard Worker p.moveTo(x, y);
489*c8dee2aaSAndroid Build Coastguard Worker }
490*c8dee2aaSAndroid Build Coastguard Worker
ApplyRMoveTo(SkPath & p,SkScalar dx,SkScalar dy)491*c8dee2aaSAndroid Build Coastguard Worker void ApplyRMoveTo(SkPath& p, SkScalar dx, SkScalar dy) {
492*c8dee2aaSAndroid Build Coastguard Worker p.rMoveTo(dx, dy);
493*c8dee2aaSAndroid Build Coastguard Worker }
494*c8dee2aaSAndroid Build Coastguard Worker
ApplyReset(SkPath & p)495*c8dee2aaSAndroid Build Coastguard Worker void ApplyReset(SkPath& p) {
496*c8dee2aaSAndroid Build Coastguard Worker p.reset();
497*c8dee2aaSAndroid Build Coastguard Worker }
498*c8dee2aaSAndroid Build Coastguard Worker
ApplyRewind(SkPath & p)499*c8dee2aaSAndroid Build Coastguard Worker void ApplyRewind(SkPath& p) {
500*c8dee2aaSAndroid Build Coastguard Worker p.rewind();
501*c8dee2aaSAndroid Build Coastguard Worker }
502*c8dee2aaSAndroid Build Coastguard Worker
ApplyQuadTo(SkPath & p,SkScalar x1,SkScalar y1,SkScalar x2,SkScalar y2)503*c8dee2aaSAndroid Build Coastguard Worker void ApplyQuadTo(SkPath& p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
504*c8dee2aaSAndroid Build Coastguard Worker p.quadTo(x1, y1, x2, y2);
505*c8dee2aaSAndroid Build Coastguard Worker }
506*c8dee2aaSAndroid Build Coastguard Worker
ApplyRQuadTo(SkPath & p,SkScalar dx1,SkScalar dy1,SkScalar dx2,SkScalar dy2)507*c8dee2aaSAndroid Build Coastguard Worker void ApplyRQuadTo(SkPath& p, SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2) {
508*c8dee2aaSAndroid Build Coastguard Worker p.rQuadTo(dx1, dy1, dx2, dy2);
509*c8dee2aaSAndroid Build Coastguard Worker }
510*c8dee2aaSAndroid Build Coastguard Worker
ApplyTransform(SkPath & orig,SkScalar scaleX,SkScalar skewX,SkScalar transX,SkScalar skewY,SkScalar scaleY,SkScalar transY,SkScalar pers0,SkScalar pers1,SkScalar pers2)511*c8dee2aaSAndroid Build Coastguard Worker void ApplyTransform(SkPath& orig,
512*c8dee2aaSAndroid Build Coastguard Worker SkScalar scaleX, SkScalar skewX, SkScalar transX,
513*c8dee2aaSAndroid Build Coastguard Worker SkScalar skewY, SkScalar scaleY, SkScalar transY,
514*c8dee2aaSAndroid Build Coastguard Worker SkScalar pers0, SkScalar pers1, SkScalar pers2) {
515*c8dee2aaSAndroid Build Coastguard Worker SkMatrix m = SkMatrix::MakeAll(scaleX, skewX , transX,
516*c8dee2aaSAndroid Build Coastguard Worker skewY , scaleY, transY,
517*c8dee2aaSAndroid Build Coastguard Worker pers0 , pers1 , pers2);
518*c8dee2aaSAndroid Build Coastguard Worker orig.transform(m);
519*c8dee2aaSAndroid Build Coastguard Worker }
520*c8dee2aaSAndroid Build Coastguard Worker
521*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PATHOPS
ApplySimplify(SkPath & path)522*c8dee2aaSAndroid Build Coastguard Worker bool ApplySimplify(SkPath& path) {
523*c8dee2aaSAndroid Build Coastguard Worker return Simplify(path, &path);
524*c8dee2aaSAndroid Build Coastguard Worker }
525*c8dee2aaSAndroid Build Coastguard Worker
ApplyPathOp(SkPath & pathOne,const SkPath & pathTwo,SkPathOp op)526*c8dee2aaSAndroid Build Coastguard Worker bool ApplyPathOp(SkPath& pathOne, const SkPath& pathTwo, SkPathOp op) {
527*c8dee2aaSAndroid Build Coastguard Worker return Op(pathOne, pathTwo, op, &pathOne);
528*c8dee2aaSAndroid Build Coastguard Worker }
529*c8dee2aaSAndroid Build Coastguard Worker
MakePathFromOp(const SkPath & pathOne,const SkPath & pathTwo,SkPathOp op)530*c8dee2aaSAndroid Build Coastguard Worker SkPathOrNull MakePathFromOp(const SkPath& pathOne, const SkPath& pathTwo, SkPathOp op) {
531*c8dee2aaSAndroid Build Coastguard Worker SkPath out;
532*c8dee2aaSAndroid Build Coastguard Worker if (Op(pathOne, pathTwo, op, &out)) {
533*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(out);
534*c8dee2aaSAndroid Build Coastguard Worker }
535*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
536*c8dee2aaSAndroid Build Coastguard Worker }
537*c8dee2aaSAndroid Build Coastguard Worker
MakeAsWinding(const SkPath & self)538*c8dee2aaSAndroid Build Coastguard Worker SkPathOrNull MakeAsWinding(const SkPath& self) {
539*c8dee2aaSAndroid Build Coastguard Worker SkPath out;
540*c8dee2aaSAndroid Build Coastguard Worker if (AsWinding(self, &out)) {
541*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(out);
542*c8dee2aaSAndroid Build Coastguard Worker }
543*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
544*c8dee2aaSAndroid Build Coastguard Worker }
545*c8dee2aaSAndroid Build Coastguard Worker #endif
546*c8dee2aaSAndroid Build Coastguard Worker
ToSVGString(const SkPath & path)547*c8dee2aaSAndroid Build Coastguard Worker JSString ToSVGString(const SkPath& path) {
548*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(SkParsePath::ToSVGString(path).c_str());
549*c8dee2aaSAndroid Build Coastguard Worker }
550*c8dee2aaSAndroid Build Coastguard Worker
MakePathFromSVGString(std::string str)551*c8dee2aaSAndroid Build Coastguard Worker SkPathOrNull MakePathFromSVGString(std::string str) {
552*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
553*c8dee2aaSAndroid Build Coastguard Worker if (SkParsePath::FromSVGString(str.c_str(), &path)) {
554*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(path);
555*c8dee2aaSAndroid Build Coastguard Worker }
556*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
557*c8dee2aaSAndroid Build Coastguard Worker }
558*c8dee2aaSAndroid Build Coastguard Worker
CanInterpolate(const SkPath & path1,const SkPath & path2)559*c8dee2aaSAndroid Build Coastguard Worker bool CanInterpolate(const SkPath& path1, const SkPath& path2) {
560*c8dee2aaSAndroid Build Coastguard Worker return path1.isInterpolatable(path2);
561*c8dee2aaSAndroid Build Coastguard Worker }
562*c8dee2aaSAndroid Build Coastguard Worker
MakePathFromInterpolation(const SkPath & path1,const SkPath & path2,SkScalar weight)563*c8dee2aaSAndroid Build Coastguard Worker SkPathOrNull MakePathFromInterpolation(const SkPath& path1, const SkPath& path2, SkScalar weight) {
564*c8dee2aaSAndroid Build Coastguard Worker SkPath out;
565*c8dee2aaSAndroid Build Coastguard Worker bool succeed = path1.interpolate(path2, weight, &out);
566*c8dee2aaSAndroid Build Coastguard Worker if (succeed) {
567*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(out);
568*c8dee2aaSAndroid Build Coastguard Worker }
569*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
570*c8dee2aaSAndroid Build Coastguard Worker }
571*c8dee2aaSAndroid Build Coastguard Worker
CopyPath(const SkPath & a)572*c8dee2aaSAndroid Build Coastguard Worker SkPath CopyPath(const SkPath& a) {
573*c8dee2aaSAndroid Build Coastguard Worker SkPath copy(a);
574*c8dee2aaSAndroid Build Coastguard Worker return copy;
575*c8dee2aaSAndroid Build Coastguard Worker }
576*c8dee2aaSAndroid Build Coastguard Worker
Equals(const SkPath & a,const SkPath & b)577*c8dee2aaSAndroid Build Coastguard Worker bool Equals(const SkPath& a, const SkPath& b) {
578*c8dee2aaSAndroid Build Coastguard Worker return a == b;
579*c8dee2aaSAndroid Build Coastguard Worker }
580*c8dee2aaSAndroid Build Coastguard Worker
581*c8dee2aaSAndroid Build Coastguard Worker // =================================================================================
582*c8dee2aaSAndroid Build Coastguard Worker // Creating/Exporting Paths with cmd arrays
583*c8dee2aaSAndroid Build Coastguard Worker // =================================================================================
584*c8dee2aaSAndroid Build Coastguard Worker
585*c8dee2aaSAndroid Build Coastguard Worker static const int MOVE = 0;
586*c8dee2aaSAndroid Build Coastguard Worker static const int LINE = 1;
587*c8dee2aaSAndroid Build Coastguard Worker static const int QUAD = 2;
588*c8dee2aaSAndroid Build Coastguard Worker static const int CONIC = 3;
589*c8dee2aaSAndroid Build Coastguard Worker static const int CUBIC = 4;
590*c8dee2aaSAndroid Build Coastguard Worker static const int CLOSE = 5;
591*c8dee2aaSAndroid Build Coastguard Worker
ToCmds(const SkPath & path)592*c8dee2aaSAndroid Build Coastguard Worker Float32Array ToCmds(const SkPath& path) {
593*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkScalar> cmds;
594*c8dee2aaSAndroid Build Coastguard Worker for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
595*c8dee2aaSAndroid Build Coastguard Worker switch (verb) {
596*c8dee2aaSAndroid Build Coastguard Worker case SkPathVerb::kMove:
597*c8dee2aaSAndroid Build Coastguard Worker cmds.insert(cmds.end(), {MOVE, pts[0].x(), pts[0].y()});
598*c8dee2aaSAndroid Build Coastguard Worker break;
599*c8dee2aaSAndroid Build Coastguard Worker case SkPathVerb::kLine:
600*c8dee2aaSAndroid Build Coastguard Worker cmds.insert(cmds.end(), {LINE, pts[1].x(), pts[1].y()});
601*c8dee2aaSAndroid Build Coastguard Worker break;
602*c8dee2aaSAndroid Build Coastguard Worker case SkPathVerb::kQuad:
603*c8dee2aaSAndroid Build Coastguard Worker cmds.insert(cmds.end(), {QUAD, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y()});
604*c8dee2aaSAndroid Build Coastguard Worker break;
605*c8dee2aaSAndroid Build Coastguard Worker case SkPathVerb::kConic:
606*c8dee2aaSAndroid Build Coastguard Worker cmds.insert(cmds.end(), {CONIC,
607*c8dee2aaSAndroid Build Coastguard Worker pts[1].x(), pts[1].y(),
608*c8dee2aaSAndroid Build Coastguard Worker pts[2].x(), pts[2].y(), *w});
609*c8dee2aaSAndroid Build Coastguard Worker break;
610*c8dee2aaSAndroid Build Coastguard Worker case SkPathVerb::kCubic:
611*c8dee2aaSAndroid Build Coastguard Worker cmds.insert(cmds.end(), {CUBIC,
612*c8dee2aaSAndroid Build Coastguard Worker pts[1].x(), pts[1].y(),
613*c8dee2aaSAndroid Build Coastguard Worker pts[2].x(), pts[2].y(),
614*c8dee2aaSAndroid Build Coastguard Worker pts[3].x(), pts[3].y()});
615*c8dee2aaSAndroid Build Coastguard Worker break;
616*c8dee2aaSAndroid Build Coastguard Worker case SkPathVerb::kClose:
617*c8dee2aaSAndroid Build Coastguard Worker cmds.push_back(CLOSE);
618*c8dee2aaSAndroid Build Coastguard Worker break;
619*c8dee2aaSAndroid Build Coastguard Worker }
620*c8dee2aaSAndroid Build Coastguard Worker }
621*c8dee2aaSAndroid Build Coastguard Worker return MakeTypedArray(cmds.size(), (const float*)cmds.data());
622*c8dee2aaSAndroid Build Coastguard Worker }
623*c8dee2aaSAndroid Build Coastguard Worker
MakePathFromCmds(WASMPointerF32 cptr,int numCmds)624*c8dee2aaSAndroid Build Coastguard Worker SkPathOrNull MakePathFromCmds(WASMPointerF32 cptr, int numCmds) {
625*c8dee2aaSAndroid Build Coastguard Worker const auto* cmds = reinterpret_cast<const float*>(cptr);
626*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
627*c8dee2aaSAndroid Build Coastguard Worker float x1, y1, x2, y2, x3, y3;
628*c8dee2aaSAndroid Build Coastguard Worker
629*c8dee2aaSAndroid Build Coastguard Worker // if there are not enough arguments, bail with the path we've constructed so far.
630*c8dee2aaSAndroid Build Coastguard Worker #define CHECK_NUM_ARGS(n) \
631*c8dee2aaSAndroid Build Coastguard Worker if ((i + n) > numCmds) { \
632*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Not enough args to match the verbs. Saw %d commands\n", numCmds); \
633*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null(); \
634*c8dee2aaSAndroid Build Coastguard Worker }
635*c8dee2aaSAndroid Build Coastguard Worker
636*c8dee2aaSAndroid Build Coastguard Worker for(int i = 0; i < numCmds;){
637*c8dee2aaSAndroid Build Coastguard Worker switch (sk_float_floor2int(cmds[i++])) {
638*c8dee2aaSAndroid Build Coastguard Worker case MOVE:
639*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_ARGS(2)
640*c8dee2aaSAndroid Build Coastguard Worker x1 = cmds[i++]; y1 = cmds[i++];
641*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(x1, y1);
642*c8dee2aaSAndroid Build Coastguard Worker break;
643*c8dee2aaSAndroid Build Coastguard Worker case LINE:
644*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_ARGS(2)
645*c8dee2aaSAndroid Build Coastguard Worker x1 = cmds[i++]; y1 = cmds[i++];
646*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(x1, y1);
647*c8dee2aaSAndroid Build Coastguard Worker break;
648*c8dee2aaSAndroid Build Coastguard Worker case QUAD:
649*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_ARGS(4)
650*c8dee2aaSAndroid Build Coastguard Worker x1 = cmds[i++]; y1 = cmds[i++];
651*c8dee2aaSAndroid Build Coastguard Worker x2 = cmds[i++]; y2 = cmds[i++];
652*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(x1, y1, x2, y2);
653*c8dee2aaSAndroid Build Coastguard Worker break;
654*c8dee2aaSAndroid Build Coastguard Worker case CONIC:
655*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_ARGS(5)
656*c8dee2aaSAndroid Build Coastguard Worker x1 = cmds[i++]; y1 = cmds[i++];
657*c8dee2aaSAndroid Build Coastguard Worker x2 = cmds[i++]; y2 = cmds[i++];
658*c8dee2aaSAndroid Build Coastguard Worker x3 = cmds[i++]; // weight
659*c8dee2aaSAndroid Build Coastguard Worker path.conicTo(x1, y1, x2, y2, x3);
660*c8dee2aaSAndroid Build Coastguard Worker break;
661*c8dee2aaSAndroid Build Coastguard Worker case CUBIC:
662*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_ARGS(6)
663*c8dee2aaSAndroid Build Coastguard Worker x1 = cmds[i++]; y1 = cmds[i++];
664*c8dee2aaSAndroid Build Coastguard Worker x2 = cmds[i++]; y2 = cmds[i++];
665*c8dee2aaSAndroid Build Coastguard Worker x3 = cmds[i++]; y3 = cmds[i++];
666*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(x1, y1, x2, y2, x3, y3);
667*c8dee2aaSAndroid Build Coastguard Worker break;
668*c8dee2aaSAndroid Build Coastguard Worker case CLOSE:
669*c8dee2aaSAndroid Build Coastguard Worker path.close();
670*c8dee2aaSAndroid Build Coastguard Worker break;
671*c8dee2aaSAndroid Build Coastguard Worker default:
672*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" path: UNKNOWN command %f, aborting dump...\n", cmds[i-1]);
673*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
674*c8dee2aaSAndroid Build Coastguard Worker }
675*c8dee2aaSAndroid Build Coastguard Worker }
676*c8dee2aaSAndroid Build Coastguard Worker
677*c8dee2aaSAndroid Build Coastguard Worker #undef CHECK_NUM_ARGS
678*c8dee2aaSAndroid Build Coastguard Worker
679*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(path);
680*c8dee2aaSAndroid Build Coastguard Worker }
681*c8dee2aaSAndroid Build Coastguard Worker
PathAddVerbsPointsWeights(SkPath & path,WASMPointerU8 verbsPtr,int numVerbs,WASMPointerF32 ptsPtr,int numPts,WASMPointerF32 wtsPtr,int numWts)682*c8dee2aaSAndroid Build Coastguard Worker void PathAddVerbsPointsWeights(SkPath& path, WASMPointerU8 verbsPtr, int numVerbs,
683*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 ptsPtr, int numPts,
684*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 wtsPtr, int numWts) {
685*c8dee2aaSAndroid Build Coastguard Worker const uint8_t* verbs = reinterpret_cast<const uint8_t*>(verbsPtr);
686*c8dee2aaSAndroid Build Coastguard Worker const float* pts = reinterpret_cast<const float*>(ptsPtr);
687*c8dee2aaSAndroid Build Coastguard Worker const float* weights = reinterpret_cast<const float*>(wtsPtr);
688*c8dee2aaSAndroid Build Coastguard Worker
689*c8dee2aaSAndroid Build Coastguard Worker #define CHECK_NUM_POINTS(n) \
690*c8dee2aaSAndroid Build Coastguard Worker if ((ptIdx + n) > numPts) { \
691*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Not enough points to match the verbs. Saw %d points\n", numPts); \
692*c8dee2aaSAndroid Build Coastguard Worker return; \
693*c8dee2aaSAndroid Build Coastguard Worker }
694*c8dee2aaSAndroid Build Coastguard Worker #define CHECK_NUM_WEIGHTS(n) \
695*c8dee2aaSAndroid Build Coastguard Worker if ((wtIdx + n) > numWts) { \
696*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Not enough weights to match the verbs. Saw %d weights\n", numWts); \
697*c8dee2aaSAndroid Build Coastguard Worker return; \
698*c8dee2aaSAndroid Build Coastguard Worker }
699*c8dee2aaSAndroid Build Coastguard Worker
700*c8dee2aaSAndroid Build Coastguard Worker path.incReserve(numPts);
701*c8dee2aaSAndroid Build Coastguard Worker int ptIdx = 0;
702*c8dee2aaSAndroid Build Coastguard Worker int wtIdx = 0;
703*c8dee2aaSAndroid Build Coastguard Worker for (int v = 0; v < numVerbs; ++v) {
704*c8dee2aaSAndroid Build Coastguard Worker switch (verbs[v]) {
705*c8dee2aaSAndroid Build Coastguard Worker case MOVE:
706*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_POINTS(2)
707*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(pts[ptIdx], pts[ptIdx+1]);
708*c8dee2aaSAndroid Build Coastguard Worker ptIdx += 2;
709*c8dee2aaSAndroid Build Coastguard Worker break;
710*c8dee2aaSAndroid Build Coastguard Worker case LINE:
711*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_POINTS(2)
712*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(pts[ptIdx], pts[ptIdx+1]);
713*c8dee2aaSAndroid Build Coastguard Worker ptIdx += 2;
714*c8dee2aaSAndroid Build Coastguard Worker break;
715*c8dee2aaSAndroid Build Coastguard Worker case QUAD:
716*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_POINTS(4)
717*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(pts[ptIdx], pts[ptIdx+1], pts[ptIdx+2], pts[ptIdx+3]);
718*c8dee2aaSAndroid Build Coastguard Worker ptIdx += 4;
719*c8dee2aaSAndroid Build Coastguard Worker break;
720*c8dee2aaSAndroid Build Coastguard Worker case CONIC:
721*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_POINTS(4)
722*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_WEIGHTS(1)
723*c8dee2aaSAndroid Build Coastguard Worker path.conicTo(pts[ptIdx], pts[ptIdx+1], pts[ptIdx+2], pts[ptIdx+3],
724*c8dee2aaSAndroid Build Coastguard Worker weights[wtIdx]);
725*c8dee2aaSAndroid Build Coastguard Worker ptIdx += 4;
726*c8dee2aaSAndroid Build Coastguard Worker wtIdx++;
727*c8dee2aaSAndroid Build Coastguard Worker break;
728*c8dee2aaSAndroid Build Coastguard Worker case CUBIC:
729*c8dee2aaSAndroid Build Coastguard Worker CHECK_NUM_POINTS(6)
730*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(pts[ptIdx ], pts[ptIdx+1],
731*c8dee2aaSAndroid Build Coastguard Worker pts[ptIdx+2], pts[ptIdx+3],
732*c8dee2aaSAndroid Build Coastguard Worker pts[ptIdx+4], pts[ptIdx+5]);
733*c8dee2aaSAndroid Build Coastguard Worker ptIdx += 6;
734*c8dee2aaSAndroid Build Coastguard Worker break;
735*c8dee2aaSAndroid Build Coastguard Worker case CLOSE:
736*c8dee2aaSAndroid Build Coastguard Worker path.close();
737*c8dee2aaSAndroid Build Coastguard Worker break;
738*c8dee2aaSAndroid Build Coastguard Worker }
739*c8dee2aaSAndroid Build Coastguard Worker }
740*c8dee2aaSAndroid Build Coastguard Worker #undef CHECK_NUM_POINTS
741*c8dee2aaSAndroid Build Coastguard Worker #undef CHECK_NUM_WEIGHTS
742*c8dee2aaSAndroid Build Coastguard Worker }
743*c8dee2aaSAndroid Build Coastguard Worker
MakePathFromVerbsPointsWeights(WASMPointerU8 verbsPtr,int numVerbs,WASMPointerF32 ptsPtr,int numPts,WASMPointerF32 wtsPtr,int numWts)744*c8dee2aaSAndroid Build Coastguard Worker SkPath MakePathFromVerbsPointsWeights(WASMPointerU8 verbsPtr, int numVerbs,
745*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 ptsPtr, int numPts,
746*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 wtsPtr, int numWts) {
747*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
748*c8dee2aaSAndroid Build Coastguard Worker PathAddVerbsPointsWeights(path, verbsPtr, numVerbs, ptsPtr, numPts, wtsPtr, numWts);
749*c8dee2aaSAndroid Build Coastguard Worker return path;
750*c8dee2aaSAndroid Build Coastguard Worker }
751*c8dee2aaSAndroid Build Coastguard Worker
752*c8dee2aaSAndroid Build Coastguard Worker //========================================================================================
753*c8dee2aaSAndroid Build Coastguard Worker // Path Effects
754*c8dee2aaSAndroid Build Coastguard Worker //========================================================================================
755*c8dee2aaSAndroid Build Coastguard Worker
ApplyDash(SkPath & path,SkScalar on,SkScalar off,SkScalar phase)756*c8dee2aaSAndroid Build Coastguard Worker bool ApplyDash(SkPath& path, SkScalar on, SkScalar off, SkScalar phase) {
757*c8dee2aaSAndroid Build Coastguard Worker SkScalar intervals[] = { on, off };
758*c8dee2aaSAndroid Build Coastguard Worker auto pe = SkDashPathEffect::Make(intervals, 2, phase);
759*c8dee2aaSAndroid Build Coastguard Worker if (!pe) {
760*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Invalid args to dash()\n");
761*c8dee2aaSAndroid Build Coastguard Worker return false;
762*c8dee2aaSAndroid Build Coastguard Worker }
763*c8dee2aaSAndroid Build Coastguard Worker SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
764*c8dee2aaSAndroid Build Coastguard Worker if (pe->filterPath(&path, path, &rec, nullptr)) {
765*c8dee2aaSAndroid Build Coastguard Worker return true;
766*c8dee2aaSAndroid Build Coastguard Worker }
767*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not make dashed path\n");
768*c8dee2aaSAndroid Build Coastguard Worker return false;
769*c8dee2aaSAndroid Build Coastguard Worker }
770*c8dee2aaSAndroid Build Coastguard Worker
ApplyTrim(SkPath & path,SkScalar startT,SkScalar stopT,bool isComplement)771*c8dee2aaSAndroid Build Coastguard Worker bool ApplyTrim(SkPath& path, SkScalar startT, SkScalar stopT, bool isComplement) {
772*c8dee2aaSAndroid Build Coastguard Worker auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted : SkTrimPathEffect::Mode::kNormal;
773*c8dee2aaSAndroid Build Coastguard Worker auto pe = SkTrimPathEffect::Make(startT, stopT, mode);
774*c8dee2aaSAndroid Build Coastguard Worker if (!pe) {
775*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Invalid args to trim(): startT and stopT must be in [0,1]\n");
776*c8dee2aaSAndroid Build Coastguard Worker return false;
777*c8dee2aaSAndroid Build Coastguard Worker }
778*c8dee2aaSAndroid Build Coastguard Worker SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
779*c8dee2aaSAndroid Build Coastguard Worker if (pe->filterPath(&path, path, &rec, nullptr)) {
780*c8dee2aaSAndroid Build Coastguard Worker return true;
781*c8dee2aaSAndroid Build Coastguard Worker }
782*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not trim path\n");
783*c8dee2aaSAndroid Build Coastguard Worker return false;
784*c8dee2aaSAndroid Build Coastguard Worker }
785*c8dee2aaSAndroid Build Coastguard Worker
786*c8dee2aaSAndroid Build Coastguard Worker struct StrokeOpts {
787*c8dee2aaSAndroid Build Coastguard Worker // Default values are set in interface.js which allows clients
788*c8dee2aaSAndroid Build Coastguard Worker // to set any number of them. Otherwise, the binding code complains if
789*c8dee2aaSAndroid Build Coastguard Worker // any are omitted.
790*c8dee2aaSAndroid Build Coastguard Worker SkScalar width;
791*c8dee2aaSAndroid Build Coastguard Worker SkScalar miter_limit;
792*c8dee2aaSAndroid Build Coastguard Worker SkPaint::Join join;
793*c8dee2aaSAndroid Build Coastguard Worker SkPaint::Cap cap;
794*c8dee2aaSAndroid Build Coastguard Worker float precision;
795*c8dee2aaSAndroid Build Coastguard Worker };
796*c8dee2aaSAndroid Build Coastguard Worker
ApplyStroke(SkPath & path,StrokeOpts opts)797*c8dee2aaSAndroid Build Coastguard Worker bool ApplyStroke(SkPath& path, StrokeOpts opts) {
798*c8dee2aaSAndroid Build Coastguard Worker SkPaint p;
799*c8dee2aaSAndroid Build Coastguard Worker p.setStyle(SkPaint::kStroke_Style);
800*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeCap(opts.cap);
801*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeJoin(opts.join);
802*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeWidth(opts.width);
803*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeMiter(opts.miter_limit);
804*c8dee2aaSAndroid Build Coastguard Worker
805*c8dee2aaSAndroid Build Coastguard Worker return skpathutils::FillPathWithPaint(path, p, &path, nullptr, opts.precision);
806*c8dee2aaSAndroid Build Coastguard Worker }
807*c8dee2aaSAndroid Build Coastguard Worker
808*c8dee2aaSAndroid Build Coastguard Worker // This function is private, we call it in interface.js
computeTonalColors(WASMPointerF32 cPtrAmbi,WASMPointerF32 cPtrSpot)809*c8dee2aaSAndroid Build Coastguard Worker void computeTonalColors(WASMPointerF32 cPtrAmbi, WASMPointerF32 cPtrSpot) {
810*c8dee2aaSAndroid Build Coastguard Worker // private methods accepting colors take pointers to floats already copied into wasm memory.
811*c8dee2aaSAndroid Build Coastguard Worker float* ambiFloats = reinterpret_cast<float*>(cPtrAmbi);
812*c8dee2aaSAndroid Build Coastguard Worker float* spotFloats = reinterpret_cast<float*>(cPtrSpot);
813*c8dee2aaSAndroid Build Coastguard Worker SkColor4f ambiColor = { ambiFloats[0], ambiFloats[1], ambiFloats[2], ambiFloats[3]};
814*c8dee2aaSAndroid Build Coastguard Worker SkColor4f spotColor = { spotFloats[0], spotFloats[1], spotFloats[2], spotFloats[3]};
815*c8dee2aaSAndroid Build Coastguard Worker
816*c8dee2aaSAndroid Build Coastguard Worker // This function takes SkColor
817*c8dee2aaSAndroid Build Coastguard Worker SkColor resultAmbi, resultSpot;
818*c8dee2aaSAndroid Build Coastguard Worker SkShadowUtils::ComputeTonalColors(
819*c8dee2aaSAndroid Build Coastguard Worker ambiColor.toSkColor(), spotColor.toSkColor(),
820*c8dee2aaSAndroid Build Coastguard Worker &resultAmbi, &resultSpot);
821*c8dee2aaSAndroid Build Coastguard Worker
822*c8dee2aaSAndroid Build Coastguard Worker // Convert back to color4f
823*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f ambi4f = SkColor4f::FromColor(resultAmbi);
824*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f spot4f = SkColor4f::FromColor(resultSpot);
825*c8dee2aaSAndroid Build Coastguard Worker
826*c8dee2aaSAndroid Build Coastguard Worker // Re-use the caller's allocated memory to hold the result.
827*c8dee2aaSAndroid Build Coastguard Worker memcpy(ambiFloats, ambi4f.vec(), 4 * sizeof(SkScalar));
828*c8dee2aaSAndroid Build Coastguard Worker memcpy(spotFloats, spot4f.vec(), 4 * sizeof(SkScalar));
829*c8dee2aaSAndroid Build Coastguard Worker }
830*c8dee2aaSAndroid Build Coastguard Worker
831*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_RUNTIME_EFFECT
832*c8dee2aaSAndroid Build Coastguard Worker struct RuntimeEffectUniform {
833*c8dee2aaSAndroid Build Coastguard Worker int columns;
834*c8dee2aaSAndroid Build Coastguard Worker int rows;
835*c8dee2aaSAndroid Build Coastguard Worker int slot; // the index into the uniforms array that this uniform begins.
836*c8dee2aaSAndroid Build Coastguard Worker bool isInteger;
837*c8dee2aaSAndroid Build Coastguard Worker };
838*c8dee2aaSAndroid Build Coastguard Worker
fromUniform(const SkRuntimeEffect::Uniform & u)839*c8dee2aaSAndroid Build Coastguard Worker RuntimeEffectUniform fromUniform(const SkRuntimeEffect::Uniform& u) {
840*c8dee2aaSAndroid Build Coastguard Worker RuntimeEffectUniform su;
841*c8dee2aaSAndroid Build Coastguard Worker su.rows = u.count; // arrayLength
842*c8dee2aaSAndroid Build Coastguard Worker su.columns = 1;
843*c8dee2aaSAndroid Build Coastguard Worker su.isInteger = false;
844*c8dee2aaSAndroid Build Coastguard Worker using Type = SkRuntimeEffect::Uniform::Type;
845*c8dee2aaSAndroid Build Coastguard Worker switch (u.type) {
846*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat: break;
847*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat2: su.columns = 2; break;
848*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat3: su.columns = 3; break;
849*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat4: su.columns = 4; break;
850*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat2x2: su.columns = 2; su.rows *= 2; break;
851*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat3x3: su.columns = 3; su.rows *= 3; break;
852*c8dee2aaSAndroid Build Coastguard Worker case Type::kFloat4x4: su.columns = 4; su.rows *= 4; break;
853*c8dee2aaSAndroid Build Coastguard Worker case Type::kInt: su.isInteger = true; break;
854*c8dee2aaSAndroid Build Coastguard Worker case Type::kInt2: su.columns = 2; su.isInteger = true; break;
855*c8dee2aaSAndroid Build Coastguard Worker case Type::kInt3: su.columns = 3; su.isInteger = true; break;
856*c8dee2aaSAndroid Build Coastguard Worker case Type::kInt4: su.columns = 4; su.isInteger = true; break;
857*c8dee2aaSAndroid Build Coastguard Worker }
858*c8dee2aaSAndroid Build Coastguard Worker su.slot = u.offset / sizeof(float);
859*c8dee2aaSAndroid Build Coastguard Worker return su;
860*c8dee2aaSAndroid Build Coastguard Worker }
861*c8dee2aaSAndroid Build Coastguard Worker
castUniforms(void * data,size_t dataLen,const SkRuntimeEffect & effect)862*c8dee2aaSAndroid Build Coastguard Worker void castUniforms(void* data, size_t dataLen, const SkRuntimeEffect& effect) {
863*c8dee2aaSAndroid Build Coastguard Worker if (dataLen != effect.uniformSize()) {
864*c8dee2aaSAndroid Build Coastguard Worker // Incorrect number of uniforms. Our code below could read/write off the end of the buffer.
865*c8dee2aaSAndroid Build Coastguard Worker // However, shader creation is going to fail anyway, so just do nothing.
866*c8dee2aaSAndroid Build Coastguard Worker return;
867*c8dee2aaSAndroid Build Coastguard Worker }
868*c8dee2aaSAndroid Build Coastguard Worker
869*c8dee2aaSAndroid Build Coastguard Worker float* fltData = reinterpret_cast<float*>(data);
870*c8dee2aaSAndroid Build Coastguard Worker for (const auto& u : effect.uniforms()) {
871*c8dee2aaSAndroid Build Coastguard Worker RuntimeEffectUniform reu = fromUniform(u);
872*c8dee2aaSAndroid Build Coastguard Worker if (reu.isInteger) {
873*c8dee2aaSAndroid Build Coastguard Worker // The SkSL is expecting integers in the uniform data
874*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < reu.columns * reu.rows; ++i) {
875*c8dee2aaSAndroid Build Coastguard Worker int numAsInt = static_cast<int>(fltData[reu.slot + i]);
876*c8dee2aaSAndroid Build Coastguard Worker fltData[reu.slot + i] = SkBits2Float(numAsInt);
877*c8dee2aaSAndroid Build Coastguard Worker }
878*c8dee2aaSAndroid Build Coastguard Worker }
879*c8dee2aaSAndroid Build Coastguard Worker }
880*c8dee2aaSAndroid Build Coastguard Worker }
881*c8dee2aaSAndroid Build Coastguard Worker #endif
882*c8dee2aaSAndroid Build Coastguard Worker
alwaysSaveTypefaceBytes(SkTypeface * face,void *)883*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> alwaysSaveTypefaceBytes(SkTypeface* face, void*) {
884*c8dee2aaSAndroid Build Coastguard Worker return face->serialize(SkTypeface::SerializeBehavior::kDoIncludeData);
885*c8dee2aaSAndroid Build Coastguard Worker }
886*c8dee2aaSAndroid Build Coastguard Worker
887*c8dee2aaSAndroid Build Coastguard Worker // These objects have private destructors / delete methods - I don't think
888*c8dee2aaSAndroid Build Coastguard Worker // we need to do anything other than tell emscripten to do nothing.
889*c8dee2aaSAndroid Build Coastguard Worker namespace emscripten {
890*c8dee2aaSAndroid Build Coastguard Worker namespace internal {
891*c8dee2aaSAndroid Build Coastguard Worker template<typename ClassType>
892*c8dee2aaSAndroid Build Coastguard Worker void raw_destructor(ClassType*);
893*c8dee2aaSAndroid Build Coastguard Worker
894*c8dee2aaSAndroid Build Coastguard Worker template<>
raw_destructor(SkContourMeasure * ptr)895*c8dee2aaSAndroid Build Coastguard Worker void raw_destructor<SkContourMeasure>(SkContourMeasure* ptr) {
896*c8dee2aaSAndroid Build Coastguard Worker }
897*c8dee2aaSAndroid Build Coastguard Worker
898*c8dee2aaSAndroid Build Coastguard Worker template<>
raw_destructor(SkVertices * ptr)899*c8dee2aaSAndroid Build Coastguard Worker void raw_destructor<SkVertices>(SkVertices* ptr) {
900*c8dee2aaSAndroid Build Coastguard Worker }
901*c8dee2aaSAndroid Build Coastguard Worker
902*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
903*c8dee2aaSAndroid Build Coastguard Worker template<>
raw_destructor(SkTextBlob * ptr)904*c8dee2aaSAndroid Build Coastguard Worker void raw_destructor<SkTextBlob>(SkTextBlob* ptr) {
905*c8dee2aaSAndroid Build Coastguard Worker }
906*c8dee2aaSAndroid Build Coastguard Worker
907*c8dee2aaSAndroid Build Coastguard Worker template<>
raw_destructor(SkTypeface * ptr)908*c8dee2aaSAndroid Build Coastguard Worker void raw_destructor<SkTypeface>(SkTypeface* ptr) {
909*c8dee2aaSAndroid Build Coastguard Worker }
910*c8dee2aaSAndroid Build Coastguard Worker #endif
911*c8dee2aaSAndroid Build Coastguard Worker }
912*c8dee2aaSAndroid Build Coastguard Worker }
913*c8dee2aaSAndroid Build Coastguard Worker
914*c8dee2aaSAndroid Build Coastguard Worker // toBytes returns a Uint8Array that has a copy of the data in the given SkData.
toBytes(sk_sp<SkData> data)915*c8dee2aaSAndroid Build Coastguard Worker Uint8Array toBytes(sk_sp<SkData> data) {
916*c8dee2aaSAndroid Build Coastguard Worker // By making the copy using the JS transliteration, we don't risk the SkData object being
917*c8dee2aaSAndroid Build Coastguard Worker // cleaned up before we make the copy.
918*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(
919*c8dee2aaSAndroid Build Coastguard Worker // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-views
920*c8dee2aaSAndroid Build Coastguard Worker typed_memory_view(data->size(), data->bytes())
921*c8dee2aaSAndroid Build Coastguard Worker ).call<Uint8Array>("slice"); // slice with no args makes a copy of the memory view.
922*c8dee2aaSAndroid Build Coastguard Worker }
923*c8dee2aaSAndroid Build Coastguard Worker
924*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
925*c8dee2aaSAndroid Build Coastguard Worker // We need to call into the JS side of things to free webGL contexts. This object will be called
926*c8dee2aaSAndroid Build Coastguard Worker // with _setTextureCleanup after CanvasKit loads. The object will have one attribute,
927*c8dee2aaSAndroid Build Coastguard Worker // a function called deleteTexture that takes two ints.
928*c8dee2aaSAndroid Build Coastguard Worker JSObject textureCleanup = emscripten::val::null();
929*c8dee2aaSAndroid Build Coastguard Worker
930*c8dee2aaSAndroid Build Coastguard Worker struct TextureReleaseContext {
931*c8dee2aaSAndroid Build Coastguard Worker // This refers to which webgl context, i.e. which surface, owns the texture. We need this
932*c8dee2aaSAndroid Build Coastguard Worker // to route the deleteTexture to the right context.
933*c8dee2aaSAndroid Build Coastguard Worker uint32_t webglHandle;
934*c8dee2aaSAndroid Build Coastguard Worker // This refers to the index of the texture in the complete list of textures.
935*c8dee2aaSAndroid Build Coastguard Worker uint32_t texHandle;
936*c8dee2aaSAndroid Build Coastguard Worker };
937*c8dee2aaSAndroid Build Coastguard Worker
deleteJSTexture(SkImages::ReleaseContext rc)938*c8dee2aaSAndroid Build Coastguard Worker void deleteJSTexture(SkImages::ReleaseContext rc) {
939*c8dee2aaSAndroid Build Coastguard Worker auto ctx = reinterpret_cast<TextureReleaseContext*>(rc);
940*c8dee2aaSAndroid Build Coastguard Worker textureCleanup.call<void>("deleteTexture", ctx->webglHandle, ctx->texHandle);
941*c8dee2aaSAndroid Build Coastguard Worker delete ctx;
942*c8dee2aaSAndroid Build Coastguard Worker }
943*c8dee2aaSAndroid Build Coastguard Worker
944*c8dee2aaSAndroid Build Coastguard Worker class ExternalWebGLTexture : public GrExternalTexture {
945*c8dee2aaSAndroid Build Coastguard Worker public:
ExternalWebGLTexture(GrBackendTexture backendTexture,uint32_t textureHandle,EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)946*c8dee2aaSAndroid Build Coastguard Worker ExternalWebGLTexture(GrBackendTexture backendTexture, uint32_t textureHandle, EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context) :
947*c8dee2aaSAndroid Build Coastguard Worker fBackendTexture(backendTexture), fWebglHandle(context), fTextureHandle(textureHandle) {}
948*c8dee2aaSAndroid Build Coastguard Worker
getBackendTexture()949*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture getBackendTexture() override {
950*c8dee2aaSAndroid Build Coastguard Worker return fBackendTexture;
951*c8dee2aaSAndroid Build Coastguard Worker }
952*c8dee2aaSAndroid Build Coastguard Worker
dispose()953*c8dee2aaSAndroid Build Coastguard Worker void dispose() override {
954*c8dee2aaSAndroid Build Coastguard Worker textureCleanup.call<void>("deleteTexture", fWebglHandle, fTextureHandle);
955*c8dee2aaSAndroid Build Coastguard Worker }
956*c8dee2aaSAndroid Build Coastguard Worker private:
957*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture fBackendTexture;
958*c8dee2aaSAndroid Build Coastguard Worker
959*c8dee2aaSAndroid Build Coastguard Worker // This refers to which webgl context, i.e. which surface, owns the texture. We need this
960*c8dee2aaSAndroid Build Coastguard Worker // to route the deleteTexture to the right context.
961*c8dee2aaSAndroid Build Coastguard Worker uint32_t fWebglHandle;
962*c8dee2aaSAndroid Build Coastguard Worker // This refers to the index of the texture in the complete list of textures.
963*c8dee2aaSAndroid Build Coastguard Worker uint32_t fTextureHandle;
964*c8dee2aaSAndroid Build Coastguard Worker };
965*c8dee2aaSAndroid Build Coastguard Worker
966*c8dee2aaSAndroid Build Coastguard Worker class WebGLTextureImageGenerator : public GrExternalTextureGenerator {
967*c8dee2aaSAndroid Build Coastguard Worker public:
WebGLTextureImageGenerator(SkImageInfo ii,JSObject callbackObj)968*c8dee2aaSAndroid Build Coastguard Worker WebGLTextureImageGenerator(SkImageInfo ii, JSObject callbackObj):
969*c8dee2aaSAndroid Build Coastguard Worker GrExternalTextureGenerator(ii),
970*c8dee2aaSAndroid Build Coastguard Worker fCallback(callbackObj) {}
971*c8dee2aaSAndroid Build Coastguard Worker
~WebGLTextureImageGenerator()972*c8dee2aaSAndroid Build Coastguard Worker ~WebGLTextureImageGenerator() override {
973*c8dee2aaSAndroid Build Coastguard Worker // This cleans up the associated TextureSource that is used to make the texture
974*c8dee2aaSAndroid Build Coastguard Worker // (i.e. "makeTexture" below). We expect this destructor to be called when the
975*c8dee2aaSAndroid Build Coastguard Worker // SkImage that this Generator belongs to is destroyed.
976*c8dee2aaSAndroid Build Coastguard Worker fCallback.call<void>("freeSrc");
977*c8dee2aaSAndroid Build Coastguard Worker }
978*c8dee2aaSAndroid Build Coastguard Worker
generateExternalTexture(GrRecordingContext * ctx,skgpu::Mipmapped)979*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrExternalTexture> generateExternalTexture(GrRecordingContext* ctx,
980*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped) override {
981*c8dee2aaSAndroid Build Coastguard Worker GrGLTextureInfo glInfo;
982*c8dee2aaSAndroid Build Coastguard Worker
983*c8dee2aaSAndroid Build Coastguard Worker // This callback is defined in webgl.js
984*c8dee2aaSAndroid Build Coastguard Worker glInfo.fID = fCallback.call<uint32_t>("makeTexture");
985*c8dee2aaSAndroid Build Coastguard Worker
986*c8dee2aaSAndroid Build Coastguard Worker // The format and target should match how we make the texture on the JS side
987*c8dee2aaSAndroid Build Coastguard Worker // See the implementation of the makeTexture function.
988*c8dee2aaSAndroid Build Coastguard Worker glInfo.fFormat = GR_GL_RGBA8;
989*c8dee2aaSAndroid Build Coastguard Worker glInfo.fTarget = GR_GL_TEXTURE_2D;
990*c8dee2aaSAndroid Build Coastguard Worker
991*c8dee2aaSAndroid Build Coastguard Worker // These textures are unlikely to actually have mipmaps generated (we might even be on
992*c8dee2aaSAndroid Build Coastguard Worker // WebGL 1, where Skia doesn't support mipmapping at all). Therefore, we ignore any request
993*c8dee2aaSAndroid Build Coastguard Worker // for mipmapping here. See: b/338095525
994*c8dee2aaSAndroid Build Coastguard Worker auto backendTexture = GrBackendTextures::MakeGL(
995*c8dee2aaSAndroid Build Coastguard Worker fInfo.width(), fInfo.height(), skgpu::Mipmapped::kNo, glInfo);
996*c8dee2aaSAndroid Build Coastguard Worker
997*c8dee2aaSAndroid Build Coastguard Worker // In order to bind the image source to the texture, makeTexture has changed which
998*c8dee2aaSAndroid Build Coastguard Worker // texture is "in focus" for the WebGL context.
999*c8dee2aaSAndroid Build Coastguard Worker GrAsDirectContext(ctx)->resetContext(kTextureBinding_GrGLBackendState);
1000*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<ExternalWebGLTexture>(
1001*c8dee2aaSAndroid Build Coastguard Worker backendTexture, glInfo.fID, emscripten_webgl_get_current_context());
1002*c8dee2aaSAndroid Build Coastguard Worker }
1003*c8dee2aaSAndroid Build Coastguard Worker
1004*c8dee2aaSAndroid Build Coastguard Worker private:
1005*c8dee2aaSAndroid Build Coastguard Worker JSObject fCallback;
1006*c8dee2aaSAndroid Build Coastguard Worker };
1007*c8dee2aaSAndroid Build Coastguard Worker
1008*c8dee2aaSAndroid Build Coastguard Worker // callbackObj has two functions in it, one to create a texture "makeTexture" and one to clean up
1009*c8dee2aaSAndroid Build Coastguard Worker // the underlying texture source "freeSrc". This way, we can create WebGL textures for each
1010*c8dee2aaSAndroid Build Coastguard Worker // surface/WebGLContext that the image is used on (we cannot share WebGLTextures across contexts).
MakeImageFromGenerator(SimpleImageInfo ii,JSObject callbackObj)1011*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> MakeImageFromGenerator(SimpleImageInfo ii, JSObject callbackObj) {
1012*c8dee2aaSAndroid Build Coastguard Worker auto gen = std::make_unique<WebGLTextureImageGenerator>(toSkImageInfo(ii), callbackObj);
1013*c8dee2aaSAndroid Build Coastguard Worker return SkImages::DeferredFromTextureGenerator(std::move(gen));
1014*c8dee2aaSAndroid Build Coastguard Worker }
1015*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGL
1016*c8dee2aaSAndroid Build Coastguard Worker
1017*c8dee2aaSAndroid Build Coastguard Worker
encodeImage(GrDirectContext * dContext,sk_sp<SkImage> img,SkEncodedImageFormat fmt,int quality)1018*c8dee2aaSAndroid Build Coastguard Worker static Uint8Array encodeImage(GrDirectContext* dContext,
1019*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> img,
1020*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat fmt,
1021*c8dee2aaSAndroid Build Coastguard Worker int quality) {
1022*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = nullptr;
1023*c8dee2aaSAndroid Build Coastguard Worker if (fmt == SkEncodedImageFormat::kJPEG) {
1024*c8dee2aaSAndroid Build Coastguard Worker SkJpegEncoder::Options opts;
1025*c8dee2aaSAndroid Build Coastguard Worker opts.fQuality = quality;
1026*c8dee2aaSAndroid Build Coastguard Worker data = SkJpegEncoder::Encode(dContext, img.get(), opts);
1027*c8dee2aaSAndroid Build Coastguard Worker } else if (fmt == SkEncodedImageFormat::kPNG) {
1028*c8dee2aaSAndroid Build Coastguard Worker data = SkPngEncoder::Encode(dContext, img.get(), {});
1029*c8dee2aaSAndroid Build Coastguard Worker } else {
1030*c8dee2aaSAndroid Build Coastguard Worker SkWebpEncoder::Options opts;
1031*c8dee2aaSAndroid Build Coastguard Worker if (quality >= 100) {
1032*c8dee2aaSAndroid Build Coastguard Worker opts.fCompression = SkWebpEncoder::Compression::kLossless;
1033*c8dee2aaSAndroid Build Coastguard Worker opts.fQuality = 75; // This is effort to compress
1034*c8dee2aaSAndroid Build Coastguard Worker } else {
1035*c8dee2aaSAndroid Build Coastguard Worker opts.fCompression = SkWebpEncoder::Compression::kLossy;
1036*c8dee2aaSAndroid Build Coastguard Worker opts.fQuality = quality;
1037*c8dee2aaSAndroid Build Coastguard Worker }
1038*c8dee2aaSAndroid Build Coastguard Worker data = SkWebpEncoder::Encode(dContext, img.get(), opts);
1039*c8dee2aaSAndroid Build Coastguard Worker }
1040*c8dee2aaSAndroid Build Coastguard Worker if (!data) {
1041*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
1042*c8dee2aaSAndroid Build Coastguard Worker }
1043*c8dee2aaSAndroid Build Coastguard Worker return toBytes(data);
1044*c8dee2aaSAndroid Build Coastguard Worker }
1045*c8dee2aaSAndroid Build Coastguard Worker
EMSCRIPTEN_BINDINGS(Skia)1046*c8dee2aaSAndroid Build Coastguard Worker EMSCRIPTEN_BINDINGS(Skia) {
1047*c8dee2aaSAndroid Build Coastguard Worker #ifdef ENABLE_GPU
1048*c8dee2aaSAndroid Build Coastguard Worker constant("gpu", true);
1049*c8dee2aaSAndroid Build Coastguard Worker function("_MakeGrContext", &MakeGrContext);
1050*c8dee2aaSAndroid Build Coastguard Worker #endif // ENABLE_GPU
1051*c8dee2aaSAndroid Build Coastguard Worker
1052*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
1053*c8dee2aaSAndroid Build Coastguard Worker constant("webgl", true);
1054*c8dee2aaSAndroid Build Coastguard Worker function("_MakeOnScreenGLSurface", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int, sk_sp<SkColorSpace>)>(&MakeOnScreenGLSurface));
1055*c8dee2aaSAndroid Build Coastguard Worker function("_MakeOnScreenGLSurface", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int, sk_sp<SkColorSpace>, int, int)>(&MakeOnScreenGLSurface));
1056*c8dee2aaSAndroid Build Coastguard Worker function("_MakeRenderTargetWH", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int)>(&MakeRenderTarget));
1057*c8dee2aaSAndroid Build Coastguard Worker function("_MakeRenderTargetII", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, SimpleImageInfo)>(&MakeRenderTarget));
1058*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGL
1059*c8dee2aaSAndroid Build Coastguard Worker
1060*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGPU
1061*c8dee2aaSAndroid Build Coastguard Worker constant("webgpu", true);
1062*c8dee2aaSAndroid Build Coastguard Worker function("_MakeGPUTextureSurface", &MakeGPUTextureSurface);
1063*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGPU
1064*c8dee2aaSAndroid Build Coastguard Worker
1065*c8dee2aaSAndroid Build Coastguard Worker function("getDecodeCacheLimitBytes", &SkResourceCache::GetTotalByteLimit);
1066*c8dee2aaSAndroid Build Coastguard Worker function("setDecodeCacheLimitBytes", &SkResourceCache::SetTotalByteLimit);
1067*c8dee2aaSAndroid Build Coastguard Worker function("getDecodeCacheUsedBytes" , &SkResourceCache::GetTotalBytesUsed);
1068*c8dee2aaSAndroid Build Coastguard Worker
1069*c8dee2aaSAndroid Build Coastguard Worker function("_computeTonalColors", &computeTonalColors);
1070*c8dee2aaSAndroid Build Coastguard Worker function("_decodeAnimatedImage", optional_override([](WASMPointerU8 iptr,
1071*c8dee2aaSAndroid Build Coastguard Worker size_t length)->sk_sp<SkAnimatedImage> {
1072*c8dee2aaSAndroid Build Coastguard Worker uint8_t* imgData = reinterpret_cast<uint8_t*>(iptr);
1073*c8dee2aaSAndroid Build Coastguard Worker auto bytes = SkData::MakeFromMalloc(imgData, length);
1074*c8dee2aaSAndroid Build Coastguard Worker auto codec = DecodeImageData(bytes);
1075*c8dee2aaSAndroid Build Coastguard Worker if (codec == nullptr) {
1076*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
1077*c8dee2aaSAndroid Build Coastguard Worker }
1078*c8dee2aaSAndroid Build Coastguard Worker auto aCodec = SkAndroidCodec::MakeFromCodec(std::move(codec));
1079*c8dee2aaSAndroid Build Coastguard Worker if (aCodec == nullptr) {
1080*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
1081*c8dee2aaSAndroid Build Coastguard Worker }
1082*c8dee2aaSAndroid Build Coastguard Worker
1083*c8dee2aaSAndroid Build Coastguard Worker return SkAnimatedImage::Make(std::move(aCodec));
1084*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1085*c8dee2aaSAndroid Build Coastguard Worker function("_decodeImage", optional_override([](WASMPointerU8 iptr,
1086*c8dee2aaSAndroid Build Coastguard Worker size_t length)->sk_sp<SkImage> {
1087*c8dee2aaSAndroid Build Coastguard Worker uint8_t* imgData = reinterpret_cast<uint8_t*>(iptr);
1088*c8dee2aaSAndroid Build Coastguard Worker auto bytes = SkData::MakeFromMalloc(imgData, length);
1089*c8dee2aaSAndroid Build Coastguard Worker auto codec = DecodeImageData(bytes);
1090*c8dee2aaSAndroid Build Coastguard Worker if (codec == nullptr) {
1091*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
1092*c8dee2aaSAndroid Build Coastguard Worker }
1093*c8dee2aaSAndroid Build Coastguard Worker return std::get<0>(codec->getImage());
1094*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1095*c8dee2aaSAndroid Build Coastguard Worker
1096*c8dee2aaSAndroid Build Coastguard Worker // These won't be called directly, there are corresponding JS helpers to deal with arrays.
1097*c8dee2aaSAndroid Build Coastguard Worker function("_MakeImage", optional_override([](SimpleImageInfo ii,
1098*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU8 pPtr, int plen,
1099*c8dee2aaSAndroid Build Coastguard Worker size_t rowBytes)->sk_sp<SkImage> {
1100*c8dee2aaSAndroid Build Coastguard Worker uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1101*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo info = toSkImageInfo(ii);
1102*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> pixelData = SkData::MakeFromMalloc(pixels, plen);
1103*c8dee2aaSAndroid Build Coastguard Worker
1104*c8dee2aaSAndroid Build Coastguard Worker return SkImages::RasterFromData(info, pixelData, rowBytes);
1105*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1106*c8dee2aaSAndroid Build Coastguard Worker
1107*c8dee2aaSAndroid Build Coastguard Worker function("_getShadowLocalBounds", optional_override([](
1108*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 ctmPtr, const SkPath& path,
1109*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 zPlaneParamPtr, WASMPointerF32 lightPosPtr,
1110*c8dee2aaSAndroid Build Coastguard Worker SkScalar lightRadius, uint32_t flags, WASMPointerF32 outPtr) -> bool {
1111*c8dee2aaSAndroid Build Coastguard Worker SkMatrix ctm;
1112*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* nineMatrixValues = reinterpret_cast<const SkScalar*>(ctmPtr);
1113*c8dee2aaSAndroid Build Coastguard Worker ctm.set9(nineMatrixValues);
1114*c8dee2aaSAndroid Build Coastguard Worker const SkVector3* zPlaneParams = reinterpret_cast<const SkVector3*>(zPlaneParamPtr);
1115*c8dee2aaSAndroid Build Coastguard Worker const SkVector3* lightPos = reinterpret_cast<const SkVector3*>(lightPosPtr);
1116*c8dee2aaSAndroid Build Coastguard Worker SkRect* outputBounds = reinterpret_cast<SkRect*>(outPtr);
1117*c8dee2aaSAndroid Build Coastguard Worker return SkShadowUtils::GetLocalBounds(ctm, path, *zPlaneParams, *lightPos, lightRadius,
1118*c8dee2aaSAndroid Build Coastguard Worker flags, outputBounds);
1119*c8dee2aaSAndroid Build Coastguard Worker }));
1120*c8dee2aaSAndroid Build Coastguard Worker
1121*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_SERIALIZE_SKP
1122*c8dee2aaSAndroid Build Coastguard Worker function("_MakePicture", optional_override([](WASMPointerU8 dPtr,
1123*c8dee2aaSAndroid Build Coastguard Worker size_t bytes)->sk_sp<SkPicture> {
1124*c8dee2aaSAndroid Build Coastguard Worker uint8_t* d = reinterpret_cast<uint8_t*>(dPtr);
1125*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = SkData::MakeFromMalloc(d, bytes);
1126*c8dee2aaSAndroid Build Coastguard Worker
1127*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
1128*c8dee2aaSAndroid Build Coastguard Worker // Be sure we can process the data stored when serializing the SkPicture.
1129*c8dee2aaSAndroid Build Coastguard Worker static SkOnce once;
1130*c8dee2aaSAndroid Build Coastguard Worker once([] {
1131*c8dee2aaSAndroid Build Coastguard Worker SkTypeface::Register(SkTypeface_FreeType::FactoryId,
1132*c8dee2aaSAndroid Build Coastguard Worker SkTypeface_FreeType::MakeFromStream );
1133*c8dee2aaSAndroid Build Coastguard Worker });
1134*c8dee2aaSAndroid Build Coastguard Worker #endif
1135*c8dee2aaSAndroid Build Coastguard Worker
1136*c8dee2aaSAndroid Build Coastguard Worker SkDeserialProcs dp;
1137*c8dee2aaSAndroid Build Coastguard Worker dp.fImageDataProc = [](sk_sp<SkData> bytes, std::optional<SkAlphaType> at, void* ctx) -> sk_sp<SkImage> {
1138*c8dee2aaSAndroid Build Coastguard Worker auto codec = DecodeImageData(bytes);
1139*c8dee2aaSAndroid Build Coastguard Worker if (codec == nullptr) {
1140*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
1141*c8dee2aaSAndroid Build Coastguard Worker }
1142*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo info = codec->getInfo();
1143*c8dee2aaSAndroid Build Coastguard Worker if (at.has_value()) {
1144*c8dee2aaSAndroid Build Coastguard Worker info = info.makeAlphaType(*at);
1145*c8dee2aaSAndroid Build Coastguard Worker } else if (kUnpremul_SkAlphaType == info.alphaType()) {
1146*c8dee2aaSAndroid Build Coastguard Worker // Otherwise, prefer premul over unpremul (this produces better filtering in general)
1147*c8dee2aaSAndroid Build Coastguard Worker info = info.makeAlphaType(kPremul_SkAlphaType);
1148*c8dee2aaSAndroid Build Coastguard Worker }
1149*c8dee2aaSAndroid Build Coastguard Worker return std::get<0>(codec->getImage(info));
1150*c8dee2aaSAndroid Build Coastguard Worker };
1151*c8dee2aaSAndroid Build Coastguard Worker
1152*c8dee2aaSAndroid Build Coastguard Worker return SkPicture::MakeFromData(data.get(), nullptr);
1153*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1154*c8dee2aaSAndroid Build Coastguard Worker #endif
1155*c8dee2aaSAndroid Build Coastguard Worker
1156*c8dee2aaSAndroid Build Coastguard Worker #ifdef ENABLE_GPU
1157*c8dee2aaSAndroid Build Coastguard Worker class_<GrDirectContext>("GrDirectContext")
1158*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<GrDirectContext>>("sk_sp<GrDirectContext>")
1159*c8dee2aaSAndroid Build Coastguard Worker .function("_getResourceCacheLimitBytes",
1160*c8dee2aaSAndroid Build Coastguard Worker optional_override([](GrDirectContext& self)->size_t {
1161*c8dee2aaSAndroid Build Coastguard Worker int maxResources = 0;// ignored
1162*c8dee2aaSAndroid Build Coastguard Worker size_t currMax = 0;
1163*c8dee2aaSAndroid Build Coastguard Worker self.getResourceCacheLimits(&maxResources, &currMax);
1164*c8dee2aaSAndroid Build Coastguard Worker return currMax;
1165*c8dee2aaSAndroid Build Coastguard Worker }))
1166*c8dee2aaSAndroid Build Coastguard Worker .function("_getResourceCacheUsageBytes",
1167*c8dee2aaSAndroid Build Coastguard Worker optional_override([](GrDirectContext& self)->size_t {
1168*c8dee2aaSAndroid Build Coastguard Worker int usedResources = 0;// ignored
1169*c8dee2aaSAndroid Build Coastguard Worker size_t currUsage = 0;
1170*c8dee2aaSAndroid Build Coastguard Worker self.getResourceCacheUsage(&usedResources, &currUsage);
1171*c8dee2aaSAndroid Build Coastguard Worker return currUsage;
1172*c8dee2aaSAndroid Build Coastguard Worker }))
1173*c8dee2aaSAndroid Build Coastguard Worker .function("_releaseResourcesAndAbandonContext",
1174*c8dee2aaSAndroid Build Coastguard Worker &GrDirectContext::releaseResourcesAndAbandonContext)
1175*c8dee2aaSAndroid Build Coastguard Worker .function("_setResourceCacheLimitBytes",
1176*c8dee2aaSAndroid Build Coastguard Worker optional_override([](GrDirectContext& self, size_t maxResourceBytes)->void {
1177*c8dee2aaSAndroid Build Coastguard Worker int maxResources = 0;
1178*c8dee2aaSAndroid Build Coastguard Worker size_t currMax = 0; // ignored
1179*c8dee2aaSAndroid Build Coastguard Worker self.getResourceCacheLimits(&maxResources, &currMax);
1180*c8dee2aaSAndroid Build Coastguard Worker self.setResourceCacheLimits(maxResources, maxResourceBytes);
1181*c8dee2aaSAndroid Build Coastguard Worker }));
1182*c8dee2aaSAndroid Build Coastguard Worker #endif // ENABLE_GPU
1183*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
1184*c8dee2aaSAndroid Build Coastguard Worker // This allows us to give the C++ code a JS callback to delete textures that
1185*c8dee2aaSAndroid Build Coastguard Worker // have been passed in via makeImageFromTexture and makeImageFromTextureSource.
1186*c8dee2aaSAndroid Build Coastguard Worker function("_setTextureCleanup", optional_override([](JSObject callbackObj)->void {
1187*c8dee2aaSAndroid Build Coastguard Worker textureCleanup = callbackObj;
1188*c8dee2aaSAndroid Build Coastguard Worker }));
1189*c8dee2aaSAndroid Build Coastguard Worker #endif
1190*c8dee2aaSAndroid Build Coastguard Worker
1191*c8dee2aaSAndroid Build Coastguard Worker class_<SkAnimatedImage>("AnimatedImage")
1192*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkAnimatedImage>>("sk_sp<AnimatedImage>")
1193*c8dee2aaSAndroid Build Coastguard Worker .function("currentFrameDuration", &SkAnimatedImage::currentFrameDuration)
1194*c8dee2aaSAndroid Build Coastguard Worker .function("decodeNextFrame", &SkAnimatedImage::decodeNextFrame)
1195*c8dee2aaSAndroid Build Coastguard Worker .function("getFrameCount", &SkAnimatedImage::getFrameCount)
1196*c8dee2aaSAndroid Build Coastguard Worker .function("getRepetitionCount", &SkAnimatedImage::getRepetitionCount)
1197*c8dee2aaSAndroid Build Coastguard Worker .function("height", optional_override([](SkAnimatedImage& self)->int32_t {
1198*c8dee2aaSAndroid Build Coastguard Worker // getBounds returns an SkRect, but internally, the width and height are ints.
1199*c8dee2aaSAndroid Build Coastguard Worker return SkScalarFloorToInt(self.getBounds().height());
1200*c8dee2aaSAndroid Build Coastguard Worker }))
1201*c8dee2aaSAndroid Build Coastguard Worker .function("makeImageAtCurrentFrame", &SkAnimatedImage::getCurrentFrame)
1202*c8dee2aaSAndroid Build Coastguard Worker .function("reset", &SkAnimatedImage::reset)
1203*c8dee2aaSAndroid Build Coastguard Worker .function("width", optional_override([](SkAnimatedImage& self)->int32_t {
1204*c8dee2aaSAndroid Build Coastguard Worker return SkScalarFloorToInt(self.getBounds().width());
1205*c8dee2aaSAndroid Build Coastguard Worker }));
1206*c8dee2aaSAndroid Build Coastguard Worker
1207*c8dee2aaSAndroid Build Coastguard Worker class_<SkBlender>("Blender")
1208*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkBlender>>("sk_sp<Blender>")
1209*c8dee2aaSAndroid Build Coastguard Worker .class_function("Mode", &SkBlender::Mode);
1210*c8dee2aaSAndroid Build Coastguard Worker
1211*c8dee2aaSAndroid Build Coastguard Worker class_<SkCanvas>("Canvas")
1212*c8dee2aaSAndroid Build Coastguard Worker .constructor<>()
1213*c8dee2aaSAndroid Build Coastguard Worker .constructor<SkScalar,SkScalar>()
1214*c8dee2aaSAndroid Build Coastguard Worker .function("_clear", optional_override([](SkCanvas& self, WASMPointerF32 cPtr) {
1215*c8dee2aaSAndroid Build Coastguard Worker self.clear(ptrToSkColor4f(cPtr));
1216*c8dee2aaSAndroid Build Coastguard Worker }))
1217*c8dee2aaSAndroid Build Coastguard Worker .function("clipPath", select_overload<void (const SkPath&, SkClipOp, bool)>(&SkCanvas::clipPath))
1218*c8dee2aaSAndroid Build Coastguard Worker .function("_clipRRect", optional_override([](SkCanvas& self, WASMPointerF32 fPtr, SkClipOp op, bool doAntiAlias) {
1219*c8dee2aaSAndroid Build Coastguard Worker self.clipRRect(ptrToSkRRect(fPtr), op, doAntiAlias);
1220*c8dee2aaSAndroid Build Coastguard Worker }))
1221*c8dee2aaSAndroid Build Coastguard Worker .function("_clipRect", optional_override([](SkCanvas& self, WASMPointerF32 fPtr, SkClipOp op, bool doAntiAlias) {
1222*c8dee2aaSAndroid Build Coastguard Worker const SkRect* rect = reinterpret_cast<const SkRect*>(fPtr);
1223*c8dee2aaSAndroid Build Coastguard Worker self.clipRect(*rect, op, doAntiAlias);
1224*c8dee2aaSAndroid Build Coastguard Worker }))
1225*c8dee2aaSAndroid Build Coastguard Worker .function("_concat", optional_override([](SkCanvas& self, WASMPointerF32 mPtr) {
1226*c8dee2aaSAndroid Build Coastguard Worker //TODO(skbug.com/10108): make the JS side be column major.
1227*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* sixteenMatrixValues = reinterpret_cast<const SkScalar*>(mPtr);
1228*c8dee2aaSAndroid Build Coastguard Worker SkM44 m = SkM44::RowMajor(sixteenMatrixValues);
1229*c8dee2aaSAndroid Build Coastguard Worker self.concat(m);
1230*c8dee2aaSAndroid Build Coastguard Worker }))
1231*c8dee2aaSAndroid Build Coastguard Worker .function("_drawArc", optional_override([](SkCanvas& self, WASMPointerF32 fPtr,
1232*c8dee2aaSAndroid Build Coastguard Worker SkScalar startAngle, SkScalar sweepAngle,
1233*c8dee2aaSAndroid Build Coastguard Worker bool useCenter, const SkPaint& paint) {
1234*c8dee2aaSAndroid Build Coastguard Worker const SkRect* oval = reinterpret_cast<const SkRect*>(fPtr);
1235*c8dee2aaSAndroid Build Coastguard Worker self.drawArc(*oval, startAngle, sweepAngle, useCenter, paint);
1236*c8dee2aaSAndroid Build Coastguard Worker }))
1237*c8dee2aaSAndroid Build Coastguard Worker .function("_drawAtlasOptions", optional_override([](SkCanvas& self,
1238*c8dee2aaSAndroid Build Coastguard Worker const sk_sp<SkImage>& atlas, WASMPointerF32 xptr,
1239*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 rptr, WASMPointerU32 cptr, int count,
1240*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode mode, SkFilterMode filter, SkMipmapMode mipmap,
1241*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint)->void {
1242*c8dee2aaSAndroid Build Coastguard Worker const SkRSXform* dstXforms = reinterpret_cast<const SkRSXform*>(xptr);
1243*c8dee2aaSAndroid Build Coastguard Worker const SkRect* srcRects = reinterpret_cast<const SkRect*>(rptr);
1244*c8dee2aaSAndroid Build Coastguard Worker const SkColor* colors = nullptr;
1245*c8dee2aaSAndroid Build Coastguard Worker if (cptr) {
1246*c8dee2aaSAndroid Build Coastguard Worker colors = reinterpret_cast<const SkColor*>(cptr);
1247*c8dee2aaSAndroid Build Coastguard Worker }
1248*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions sampling(filter, mipmap);
1249*c8dee2aaSAndroid Build Coastguard Worker self.drawAtlas(atlas.get(), dstXforms, srcRects, colors, count, mode, sampling,
1250*c8dee2aaSAndroid Build Coastguard Worker nullptr, paint);
1251*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1252*c8dee2aaSAndroid Build Coastguard Worker .function("_drawAtlasCubic", optional_override([](SkCanvas& self,
1253*c8dee2aaSAndroid Build Coastguard Worker const sk_sp<SkImage>& atlas, WASMPointerF32 xptr,
1254*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 rptr, WASMPointerU32 cptr, int count,
1255*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode mode, float B, float C, const SkPaint* paint)->void {
1256*c8dee2aaSAndroid Build Coastguard Worker const SkRSXform* dstXforms = reinterpret_cast<const SkRSXform*>(xptr);
1257*c8dee2aaSAndroid Build Coastguard Worker const SkRect* srcRects = reinterpret_cast<const SkRect*>(rptr);
1258*c8dee2aaSAndroid Build Coastguard Worker const SkColor* colors = nullptr;
1259*c8dee2aaSAndroid Build Coastguard Worker if (cptr) {
1260*c8dee2aaSAndroid Build Coastguard Worker colors = reinterpret_cast<const SkColor*>(cptr);
1261*c8dee2aaSAndroid Build Coastguard Worker }
1262*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions sampling({B, C});
1263*c8dee2aaSAndroid Build Coastguard Worker self.drawAtlas(atlas.get(), dstXforms, srcRects, colors, count, mode, sampling,
1264*c8dee2aaSAndroid Build Coastguard Worker nullptr, paint);
1265*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1266*c8dee2aaSAndroid Build Coastguard Worker .function("_drawCircle", select_overload<void (SkScalar, SkScalar, SkScalar, const SkPaint& paint)>(&SkCanvas::drawCircle))
1267*c8dee2aaSAndroid Build Coastguard Worker .function("_drawColor", optional_override([](SkCanvas& self, WASMPointerF32 cPtr) {
1268*c8dee2aaSAndroid Build Coastguard Worker self.drawColor(ptrToSkColor4f(cPtr));
1269*c8dee2aaSAndroid Build Coastguard Worker }))
1270*c8dee2aaSAndroid Build Coastguard Worker .function("_drawColor", optional_override([](SkCanvas& self, WASMPointerF32 cPtr, SkBlendMode mode) {
1271*c8dee2aaSAndroid Build Coastguard Worker self.drawColor(ptrToSkColor4f(cPtr), mode);
1272*c8dee2aaSAndroid Build Coastguard Worker }))
1273*c8dee2aaSAndroid Build Coastguard Worker .function("_drawColorInt", optional_override([](SkCanvas& self, SkColor color, SkBlendMode mode) {
1274*c8dee2aaSAndroid Build Coastguard Worker self.drawColor(color, mode);
1275*c8dee2aaSAndroid Build Coastguard Worker }))
1276*c8dee2aaSAndroid Build Coastguard Worker .function("_drawDRRect", optional_override([](SkCanvas& self, WASMPointerF32 outerPtr,
1277*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 innerPtr, const SkPaint& paint) {
1278*c8dee2aaSAndroid Build Coastguard Worker self.drawDRRect(ptrToSkRRect(outerPtr), ptrToSkRRect(innerPtr), paint);
1279*c8dee2aaSAndroid Build Coastguard Worker }))
1280*c8dee2aaSAndroid Build Coastguard Worker .function("_drawGlyphs", optional_override([](SkCanvas& self,
1281*c8dee2aaSAndroid Build Coastguard Worker int count,
1282*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU16 glyphs,
1283*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 positions,
1284*c8dee2aaSAndroid Build Coastguard Worker float x, float y,
1285*c8dee2aaSAndroid Build Coastguard Worker const SkFont& font,
1286*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint)->void {
1287*c8dee2aaSAndroid Build Coastguard Worker self.drawGlyphs(count,
1288*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<const uint16_t*>(glyphs),
1289*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<const SkPoint*>(positions),
1290*c8dee2aaSAndroid Build Coastguard Worker {x, y}, font, paint);
1291*c8dee2aaSAndroid Build Coastguard Worker }))
1292*c8dee2aaSAndroid Build Coastguard Worker // TODO: deprecate this version, and require sampling
1293*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImage", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
1294*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, SkScalar y, const SkPaint* paint) {
1295*c8dee2aaSAndroid Build Coastguard Worker self.drawImage(image.get(), x, y, SkSamplingOptions(), paint);
1296*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1297*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImageCubic", optional_override([](SkCanvas& self, const sk_sp<SkImage>& img,
1298*c8dee2aaSAndroid Build Coastguard Worker SkScalar left, SkScalar top,
1299*c8dee2aaSAndroid Build Coastguard Worker float B, float C, // See SkSamplingOptions.h for docs.
1300*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint)->void {
1301*c8dee2aaSAndroid Build Coastguard Worker self.drawImage(img.get(), left, top, SkSamplingOptions({B, C}), paint);
1302*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1303*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImageOptions", optional_override([](SkCanvas& self, const sk_sp<SkImage>& img,
1304*c8dee2aaSAndroid Build Coastguard Worker SkScalar left, SkScalar top,
1305*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode filter, SkMipmapMode mipmap,
1306*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint)->void {
1307*c8dee2aaSAndroid Build Coastguard Worker self.drawImage(img.get(), left, top, {filter, mipmap}, paint);
1308*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1309*c8dee2aaSAndroid Build Coastguard Worker
1310*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImageNine", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
1311*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU32 centerPtr, WASMPointerF32 dstPtr,
1312*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode filter, const SkPaint* paint)->void {
1313*c8dee2aaSAndroid Build Coastguard Worker const SkIRect* center = reinterpret_cast<const SkIRect*>(centerPtr);
1314*c8dee2aaSAndroid Build Coastguard Worker const SkRect* dst = reinterpret_cast<const SkRect*>(dstPtr);
1315*c8dee2aaSAndroid Build Coastguard Worker
1316*c8dee2aaSAndroid Build Coastguard Worker self.drawImageNine(image.get(), *center, *dst, filter, paint);
1317*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1318*c8dee2aaSAndroid Build Coastguard Worker // TODO: deprecate this version, and require sampling
1319*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImageRect", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
1320*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 srcPtr, WASMPointerF32 dstPtr,
1321*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint, bool fastSample)->void {
1322*c8dee2aaSAndroid Build Coastguard Worker const SkRect* src = reinterpret_cast<const SkRect*>(srcPtr);
1323*c8dee2aaSAndroid Build Coastguard Worker const SkRect* dst = reinterpret_cast<const SkRect*>(dstPtr);
1324*c8dee2aaSAndroid Build Coastguard Worker self.drawImageRect(image, *src, *dst, SkSamplingOptions(), paint,
1325*c8dee2aaSAndroid Build Coastguard Worker fastSample ? SkCanvas::kFast_SrcRectConstraint:
1326*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::kStrict_SrcRectConstraint);
1327*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1328*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImageRectCubic", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
1329*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 srcPtr, WASMPointerF32 dstPtr,
1330*c8dee2aaSAndroid Build Coastguard Worker float B, float C, // See SkSamplingOptions.h for docs.
1331*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint)->void {
1332*c8dee2aaSAndroid Build Coastguard Worker const SkRect* src = reinterpret_cast<const SkRect*>(srcPtr);
1333*c8dee2aaSAndroid Build Coastguard Worker const SkRect* dst = reinterpret_cast<const SkRect*>(dstPtr);
1334*c8dee2aaSAndroid Build Coastguard Worker auto constraint = SkCanvas::kStrict_SrcRectConstraint; // TODO: get from caller
1335*c8dee2aaSAndroid Build Coastguard Worker self.drawImageRect(image.get(), *src, *dst, SkSamplingOptions({B, C}), paint, constraint);
1336*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1337*c8dee2aaSAndroid Build Coastguard Worker .function("_drawImageRectOptions", optional_override([](SkCanvas& self, const sk_sp<SkImage>& image,
1338*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 srcPtr, WASMPointerF32 dstPtr,
1339*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode filter, SkMipmapMode mipmap,
1340*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint)->void {
1341*c8dee2aaSAndroid Build Coastguard Worker const SkRect* src = reinterpret_cast<const SkRect*>(srcPtr);
1342*c8dee2aaSAndroid Build Coastguard Worker const SkRect* dst = reinterpret_cast<const SkRect*>(dstPtr);
1343*c8dee2aaSAndroid Build Coastguard Worker auto constraint = SkCanvas::kStrict_SrcRectConstraint; // TODO: get from caller
1344*c8dee2aaSAndroid Build Coastguard Worker self.drawImageRect(image.get(), *src, *dst, {filter, mipmap}, paint, constraint);
1345*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1346*c8dee2aaSAndroid Build Coastguard Worker .function("_drawLine", select_overload<void (SkScalar, SkScalar, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawLine))
1347*c8dee2aaSAndroid Build Coastguard Worker .function("_drawOval", optional_override([](SkCanvas& self, WASMPointerF32 fPtr,
1348*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint)->void {
1349*c8dee2aaSAndroid Build Coastguard Worker const SkRect* oval = reinterpret_cast<const SkRect*>(fPtr);
1350*c8dee2aaSAndroid Build Coastguard Worker self.drawOval(*oval, paint);
1351*c8dee2aaSAndroid Build Coastguard Worker }))
1352*c8dee2aaSAndroid Build Coastguard Worker .function("_drawPaint", &SkCanvas::drawPaint)
1353*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PARAGRAPH
1354*c8dee2aaSAndroid Build Coastguard Worker .function("_drawParagraph", optional_override([](SkCanvas& self, skia::textlayout::Paragraph* p,
1355*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, SkScalar y) {
1356*c8dee2aaSAndroid Build Coastguard Worker p->paint(&self, x, y);
1357*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1358*c8dee2aaSAndroid Build Coastguard Worker #endif
1359*c8dee2aaSAndroid Build Coastguard Worker .function("_drawPath", &SkCanvas::drawPath)
1360*c8dee2aaSAndroid Build Coastguard Worker .function("_drawPatch", optional_override([](SkCanvas& self,
1361*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cubics,
1362*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU32 colors,
1363*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 texs,
1364*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode mode,
1365*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint)->void {
1366*c8dee2aaSAndroid Build Coastguard Worker self.drawPatch(reinterpret_cast<const SkPoint*>(cubics),
1367*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<const SkColor*>(colors),
1368*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<const SkPoint*>(texs),
1369*c8dee2aaSAndroid Build Coastguard Worker mode, paint);
1370*c8dee2aaSAndroid Build Coastguard Worker }))
1371*c8dee2aaSAndroid Build Coastguard Worker // Of note, picture is *not* what is colloquially thought of as a "picture", what we call
1372*c8dee2aaSAndroid Build Coastguard Worker // a bitmap. An SkPicture is a series of draw commands.
1373*c8dee2aaSAndroid Build Coastguard Worker .function("_drawPicture", select_overload<void (const sk_sp<SkPicture>&)>(&SkCanvas::drawPicture))
1374*c8dee2aaSAndroid Build Coastguard Worker .function("_drawPoints", optional_override([](SkCanvas& self, SkCanvas::PointMode mode,
1375*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 pptr,
1376*c8dee2aaSAndroid Build Coastguard Worker int count, SkPaint& paint)->void {
1377*c8dee2aaSAndroid Build Coastguard Worker const SkPoint* pts = reinterpret_cast<const SkPoint*>(pptr);
1378*c8dee2aaSAndroid Build Coastguard Worker self.drawPoints(mode, count, pts, paint);
1379*c8dee2aaSAndroid Build Coastguard Worker }))
1380*c8dee2aaSAndroid Build Coastguard Worker .function("_drawRRect",optional_override([](SkCanvas& self, WASMPointerF32 fPtr, const SkPaint& paint) {
1381*c8dee2aaSAndroid Build Coastguard Worker self.drawRRect(ptrToSkRRect(fPtr), paint);
1382*c8dee2aaSAndroid Build Coastguard Worker }))
1383*c8dee2aaSAndroid Build Coastguard Worker .function("_drawRect", optional_override([](SkCanvas& self, WASMPointerF32 fPtr,
1384*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint)->void {
1385*c8dee2aaSAndroid Build Coastguard Worker const SkRect* rect = reinterpret_cast<const SkRect*>(fPtr);
1386*c8dee2aaSAndroid Build Coastguard Worker self.drawRect(*rect, paint);
1387*c8dee2aaSAndroid Build Coastguard Worker }))
1388*c8dee2aaSAndroid Build Coastguard Worker .function("_drawRect4f", optional_override([](SkCanvas& self, SkScalar left, SkScalar top,
1389*c8dee2aaSAndroid Build Coastguard Worker SkScalar right, SkScalar bottom,
1390*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint)->void {
1391*c8dee2aaSAndroid Build Coastguard Worker const SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
1392*c8dee2aaSAndroid Build Coastguard Worker self.drawRect(rect, paint);
1393*c8dee2aaSAndroid Build Coastguard Worker }))
1394*c8dee2aaSAndroid Build Coastguard Worker .function("_drawShadow", optional_override([](SkCanvas& self, const SkPath& path,
1395*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 zPlaneParamPtr,
1396*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 lightPosPtr,
1397*c8dee2aaSAndroid Build Coastguard Worker SkScalar lightRadius,
1398*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 ambientColorPtr,
1399*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 spotColorPtr,
1400*c8dee2aaSAndroid Build Coastguard Worker uint32_t flags) {
1401*c8dee2aaSAndroid Build Coastguard Worker const SkVector3* zPlaneParams = reinterpret_cast<const SkVector3*>(zPlaneParamPtr);
1402*c8dee2aaSAndroid Build Coastguard Worker const SkVector3* lightPos = reinterpret_cast<const SkVector3*>(lightPosPtr);
1403*c8dee2aaSAndroid Build Coastguard Worker
1404*c8dee2aaSAndroid Build Coastguard Worker SkShadowUtils::DrawShadow(&self, path, *zPlaneParams, *lightPos, lightRadius,
1405*c8dee2aaSAndroid Build Coastguard Worker ptrToSkColor4f(ambientColorPtr).toSkColor(),
1406*c8dee2aaSAndroid Build Coastguard Worker ptrToSkColor4f(spotColorPtr).toSkColor(),
1407*c8dee2aaSAndroid Build Coastguard Worker flags);
1408*c8dee2aaSAndroid Build Coastguard Worker }))
1409*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
1410*c8dee2aaSAndroid Build Coastguard Worker .function("_drawSimpleText", optional_override([](SkCanvas& self, WASMPointerU8 sptr,
1411*c8dee2aaSAndroid Build Coastguard Worker size_t len, SkScalar x, SkScalar y, const SkFont& font,
1412*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint) {
1413*c8dee2aaSAndroid Build Coastguard Worker const char* str = reinterpret_cast<const char*>(sptr);
1414*c8dee2aaSAndroid Build Coastguard Worker
1415*c8dee2aaSAndroid Build Coastguard Worker self.drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
1416*c8dee2aaSAndroid Build Coastguard Worker }))
1417*c8dee2aaSAndroid Build Coastguard Worker .function("_drawTextBlob", select_overload<void (const sk_sp<SkTextBlob>&, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawTextBlob))
1418*c8dee2aaSAndroid Build Coastguard Worker #endif
1419*c8dee2aaSAndroid Build Coastguard Worker .function("_drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices))
1420*c8dee2aaSAndroid Build Coastguard Worker
1421*c8dee2aaSAndroid Build Coastguard Worker .function("_getDeviceClipBounds", optional_override([](const SkCanvas& self, WASMPointerI32 iPtr) {
1422*c8dee2aaSAndroid Build Coastguard Worker SkIRect* outputRect = reinterpret_cast<SkIRect*>(iPtr);
1423*c8dee2aaSAndroid Build Coastguard Worker if (!outputRect) {
1424*c8dee2aaSAndroid Build Coastguard Worker return; // output pointer cannot be null
1425*c8dee2aaSAndroid Build Coastguard Worker }
1426*c8dee2aaSAndroid Build Coastguard Worker self.getDeviceClipBounds(outputRect);
1427*c8dee2aaSAndroid Build Coastguard Worker }))
1428*c8dee2aaSAndroid Build Coastguard Worker
1429*c8dee2aaSAndroid Build Coastguard Worker .function("_quickReject", optional_override([](const SkCanvas& self, WASMPointerF32 fPtr)->bool {
1430*c8dee2aaSAndroid Build Coastguard Worker const SkRect* rect = reinterpret_cast<const SkRect*>(fPtr);
1431*c8dee2aaSAndroid Build Coastguard Worker return self.quickReject(*rect);
1432*c8dee2aaSAndroid Build Coastguard Worker }))
1433*c8dee2aaSAndroid Build Coastguard Worker
1434*c8dee2aaSAndroid Build Coastguard Worker // 4x4 matrix functions
1435*c8dee2aaSAndroid Build Coastguard Worker // Just like with getTotalMatrix, we allocate the buffer for the 16 floats to go in from
1436*c8dee2aaSAndroid Build Coastguard Worker // interface.js, so it can also free them when its done.
1437*c8dee2aaSAndroid Build Coastguard Worker .function("_getLocalToDevice", optional_override([](const SkCanvas& self, WASMPointerF32 mPtr) {
1438*c8dee2aaSAndroid Build Coastguard Worker SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
1439*c8dee2aaSAndroid Build Coastguard Worker if (!sixteenMatrixValues) {
1440*c8dee2aaSAndroid Build Coastguard Worker return; // matrix cannot be null
1441*c8dee2aaSAndroid Build Coastguard Worker }
1442*c8dee2aaSAndroid Build Coastguard Worker SkM44 m = self.getLocalToDevice();
1443*c8dee2aaSAndroid Build Coastguard Worker m.getRowMajor(sixteenMatrixValues);
1444*c8dee2aaSAndroid Build Coastguard Worker }))
1445*c8dee2aaSAndroid Build Coastguard Worker .function("getSaveCount", &SkCanvas::getSaveCount)
1446*c8dee2aaSAndroid Build Coastguard Worker // We allocate room for the matrix from the JS side and free it there so as to not have
1447*c8dee2aaSAndroid Build Coastguard Worker // an awkward moment where we malloc something here and "just know" to free it on the
1448*c8dee2aaSAndroid Build Coastguard Worker // JS side.
1449*c8dee2aaSAndroid Build Coastguard Worker .function("_getTotalMatrix", optional_override([](const SkCanvas& self, WASMPointerU8 mPtr) {
1450*c8dee2aaSAndroid Build Coastguard Worker SkScalar* nineMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
1451*c8dee2aaSAndroid Build Coastguard Worker if (!nineMatrixValues) {
1452*c8dee2aaSAndroid Build Coastguard Worker return; // matrix cannot be null
1453*c8dee2aaSAndroid Build Coastguard Worker }
1454*c8dee2aaSAndroid Build Coastguard Worker SkMatrix m = self.getTotalMatrix();
1455*c8dee2aaSAndroid Build Coastguard Worker m.get9(nineMatrixValues);
1456*c8dee2aaSAndroid Build Coastguard Worker }))
1457*c8dee2aaSAndroid Build Coastguard Worker .function("_makeSurface", optional_override([](SkCanvas& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
1458*c8dee2aaSAndroid Build Coastguard Worker return self.makeSurface(toSkImageInfo(sii), nullptr);
1459*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1460*c8dee2aaSAndroid Build Coastguard Worker
1461*c8dee2aaSAndroid Build Coastguard Worker .function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
1462*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU8 pPtr,
1463*c8dee2aaSAndroid Build Coastguard Worker size_t dstRowBytes, int srcX, int srcY) {
1464*c8dee2aaSAndroid Build Coastguard Worker uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1465*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo dstInfo = toSkImageInfo(di);
1466*c8dee2aaSAndroid Build Coastguard Worker
1467*c8dee2aaSAndroid Build Coastguard Worker return self.readPixels(dstInfo, pixels, dstRowBytes, srcX, srcY);
1468*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1469*c8dee2aaSAndroid Build Coastguard Worker .function("restore", &SkCanvas::restore)
1470*c8dee2aaSAndroid Build Coastguard Worker .function("restoreToCount", &SkCanvas::restoreToCount)
1471*c8dee2aaSAndroid Build Coastguard Worker .function("rotate", select_overload<void (SkScalar, SkScalar, SkScalar)>(&SkCanvas::rotate))
1472*c8dee2aaSAndroid Build Coastguard Worker .function("save", &SkCanvas::save)
1473*c8dee2aaSAndroid Build Coastguard Worker .function("_saveLayer", optional_override([](SkCanvas& self, const SkPaint* p, WASMPointerF32 fPtr,
1474*c8dee2aaSAndroid Build Coastguard Worker const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags,
1475*c8dee2aaSAndroid Build Coastguard Worker SkTileMode backdropFilterTileMode)->int {
1476*c8dee2aaSAndroid Build Coastguard Worker SkRect* bounds = reinterpret_cast<SkRect*>(fPtr);
1477*c8dee2aaSAndroid Build Coastguard Worker return self.saveLayer(SkCanvas::SaveLayerRec(bounds, p, backdrop, backdropFilterTileMode, nullptr, flags));
1478*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1479*c8dee2aaSAndroid Build Coastguard Worker .function("saveLayerPaint", optional_override([](SkCanvas& self, const SkPaint p)->int {
1480*c8dee2aaSAndroid Build Coastguard Worker return self.saveLayer(SkCanvas::SaveLayerRec(nullptr, &p, 0));
1481*c8dee2aaSAndroid Build Coastguard Worker }))
1482*c8dee2aaSAndroid Build Coastguard Worker .function("scale", &SkCanvas::scale)
1483*c8dee2aaSAndroid Build Coastguard Worker .function("skew", &SkCanvas::skew)
1484*c8dee2aaSAndroid Build Coastguard Worker .function("translate", &SkCanvas::translate)
1485*c8dee2aaSAndroid Build Coastguard Worker .function("_writePixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
1486*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU8 pPtr,
1487*c8dee2aaSAndroid Build Coastguard Worker size_t srcRowBytes, int dstX, int dstY) {
1488*c8dee2aaSAndroid Build Coastguard Worker uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1489*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo dstInfo = toSkImageInfo(di);
1490*c8dee2aaSAndroid Build Coastguard Worker
1491*c8dee2aaSAndroid Build Coastguard Worker return self.writePixels(dstInfo, pixels, srcRowBytes, dstX, dstY);
1492*c8dee2aaSAndroid Build Coastguard Worker }));
1493*c8dee2aaSAndroid Build Coastguard Worker
1494*c8dee2aaSAndroid Build Coastguard Worker class_<SkColorFilter>("ColorFilter")
1495*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkColorFilter>>("sk_sp<ColorFilter>>")
1496*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeBlend", optional_override([](WASMPointerF32 cPtr, SkBlendMode mode,
1497*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace)->sk_sp<SkColorFilter> {
1498*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::Blend(ptrToSkColor4f(cPtr), colorSpace, mode);
1499*c8dee2aaSAndroid Build Coastguard Worker }))
1500*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeCompose", &SkColorFilters::Compose)
1501*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeLerp", &SkColorFilters::Lerp)
1502*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeLinearToSRGBGamma", &SkColorFilters::LinearToSRGBGamma)
1503*c8dee2aaSAndroid Build Coastguard Worker .class_function("_makeMatrix", optional_override([](WASMPointerF32 fPtr) {
1504*c8dee2aaSAndroid Build Coastguard Worker float* twentyFloats = reinterpret_cast<float*>(fPtr);
1505*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::Matrix(twentyFloats);
1506*c8dee2aaSAndroid Build Coastguard Worker }))
1507*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeSRGBToLinearGamma", &SkColorFilters::SRGBToLinearGamma)
1508*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeLuma", &SkLumaColorFilter::Make);
1509*c8dee2aaSAndroid Build Coastguard Worker
1510*c8dee2aaSAndroid Build Coastguard Worker class_<SkContourMeasureIter>("ContourMeasureIter")
1511*c8dee2aaSAndroid Build Coastguard Worker .constructor<const SkPath&, bool, SkScalar>()
1512*c8dee2aaSAndroid Build Coastguard Worker .function("next", &SkContourMeasureIter::next);
1513*c8dee2aaSAndroid Build Coastguard Worker
1514*c8dee2aaSAndroid Build Coastguard Worker class_<SkContourMeasure>("ContourMeasure")
1515*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkContourMeasure>>("sk_sp<ContourMeasure>>")
1516*c8dee2aaSAndroid Build Coastguard Worker .function("_getPosTan", optional_override([](SkContourMeasure& self,
1517*c8dee2aaSAndroid Build Coastguard Worker SkScalar distance,
1518*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 oPtr) -> void {
1519*c8dee2aaSAndroid Build Coastguard Worker SkPoint* pointAndVector = reinterpret_cast<SkPoint*>(oPtr);
1520*c8dee2aaSAndroid Build Coastguard Worker if (!self.getPosTan(distance, pointAndVector, pointAndVector + 1)) {
1521*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("zero-length path in getPosTan\n");
1522*c8dee2aaSAndroid Build Coastguard Worker }
1523*c8dee2aaSAndroid Build Coastguard Worker }))
1524*c8dee2aaSAndroid Build Coastguard Worker .function("getSegment", optional_override([](SkContourMeasure& self, SkScalar startD,
1525*c8dee2aaSAndroid Build Coastguard Worker SkScalar stopD, bool startWithMoveTo) -> SkPath {
1526*c8dee2aaSAndroid Build Coastguard Worker SkPath p;
1527*c8dee2aaSAndroid Build Coastguard Worker bool ok = self.getSegment(startD, stopD, &p, startWithMoveTo);
1528*c8dee2aaSAndroid Build Coastguard Worker if (ok) {
1529*c8dee2aaSAndroid Build Coastguard Worker return p;
1530*c8dee2aaSAndroid Build Coastguard Worker }
1531*c8dee2aaSAndroid Build Coastguard Worker return SkPath();
1532*c8dee2aaSAndroid Build Coastguard Worker }))
1533*c8dee2aaSAndroid Build Coastguard Worker .function("isClosed", &SkContourMeasure::isClosed)
1534*c8dee2aaSAndroid Build Coastguard Worker .function("length", &SkContourMeasure::length);
1535*c8dee2aaSAndroid Build Coastguard Worker
1536*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
1537*c8dee2aaSAndroid Build Coastguard Worker class_<SkFont>("Font")
1538*c8dee2aaSAndroid Build Coastguard Worker .constructor<>()
1539*c8dee2aaSAndroid Build Coastguard Worker .constructor<sk_sp<SkTypeface>>()
1540*c8dee2aaSAndroid Build Coastguard Worker .constructor<sk_sp<SkTypeface>, SkScalar>()
1541*c8dee2aaSAndroid Build Coastguard Worker .constructor<sk_sp<SkTypeface>, SkScalar, SkScalar, SkScalar>()
1542*c8dee2aaSAndroid Build Coastguard Worker .function("_getGlyphWidthBounds", optional_override([](SkFont& self, WASMPointerU16 gPtr,
1543*c8dee2aaSAndroid Build Coastguard Worker int numGlyphs, WASMPointerF32 wPtr,
1544*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 rPtr,
1545*c8dee2aaSAndroid Build Coastguard Worker SkPaint* paint) {
1546*c8dee2aaSAndroid Build Coastguard Worker const SkGlyphID* glyphs = reinterpret_cast<const SkGlyphID*>(gPtr);
1547*c8dee2aaSAndroid Build Coastguard Worker // On the JS side only one of these is set at a time for easier ergonomics.
1548*c8dee2aaSAndroid Build Coastguard Worker SkRect* outputRects = reinterpret_cast<SkRect*>(rPtr);
1549*c8dee2aaSAndroid Build Coastguard Worker SkScalar* outputWidths = reinterpret_cast<SkScalar*>(wPtr);
1550*c8dee2aaSAndroid Build Coastguard Worker self.getWidthsBounds(glyphs, numGlyphs, outputWidths, outputRects, paint);
1551*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1552*c8dee2aaSAndroid Build Coastguard Worker .function("_getGlyphIDs", optional_override([](SkFont& self, WASMPointerU8 sptr,
1553*c8dee2aaSAndroid Build Coastguard Worker size_t strLen, size_t expectedCodePoints,
1554*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU16 iPtr) -> int {
1555*c8dee2aaSAndroid Build Coastguard Worker char* str = reinterpret_cast<char*>(sptr);
1556*c8dee2aaSAndroid Build Coastguard Worker SkGlyphID* glyphIDs = reinterpret_cast<SkGlyphID*>(iPtr);
1557*c8dee2aaSAndroid Build Coastguard Worker
1558*c8dee2aaSAndroid Build Coastguard Worker int actualCodePoints = self.textToGlyphs(str, strLen, SkTextEncoding::kUTF8,
1559*c8dee2aaSAndroid Build Coastguard Worker glyphIDs, expectedCodePoints);
1560*c8dee2aaSAndroid Build Coastguard Worker return actualCodePoints;
1561*c8dee2aaSAndroid Build Coastguard Worker }))
1562*c8dee2aaSAndroid Build Coastguard Worker .function("getMetrics", optional_override([](SkFont& self) -> JSObject {
1563*c8dee2aaSAndroid Build Coastguard Worker SkFontMetrics fm;
1564*c8dee2aaSAndroid Build Coastguard Worker self.getMetrics(&fm);
1565*c8dee2aaSAndroid Build Coastguard Worker
1566*c8dee2aaSAndroid Build Coastguard Worker JSObject j = emscripten::val::object();
1567*c8dee2aaSAndroid Build Coastguard Worker j.set("ascent", fm.fAscent);
1568*c8dee2aaSAndroid Build Coastguard Worker j.set("descent", fm.fDescent);
1569*c8dee2aaSAndroid Build Coastguard Worker j.set("leading", fm.fLeading);
1570*c8dee2aaSAndroid Build Coastguard Worker if (!(fm.fFlags & SkFontMetrics::kBoundsInvalid_Flag)) {
1571*c8dee2aaSAndroid Build Coastguard Worker const float rect[] = {
1572*c8dee2aaSAndroid Build Coastguard Worker fm.fXMin, fm.fTop, fm.fXMax, fm.fBottom
1573*c8dee2aaSAndroid Build Coastguard Worker };
1574*c8dee2aaSAndroid Build Coastguard Worker j.set("bounds", MakeTypedArray(4, rect));
1575*c8dee2aaSAndroid Build Coastguard Worker }
1576*c8dee2aaSAndroid Build Coastguard Worker return j;
1577*c8dee2aaSAndroid Build Coastguard Worker }))
1578*c8dee2aaSAndroid Build Coastguard Worker .function("_getGlyphIntercepts", optional_override([](SkFont& self,
1579*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU16 gPtr, size_t numGlyphs, bool ownGlyphs,
1580*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 pPtr, size_t numPos, bool ownPos,
1581*c8dee2aaSAndroid Build Coastguard Worker float top, float bottom) -> Float32Array {
1582*c8dee2aaSAndroid Build Coastguard Worker JSSpan<uint16_t> glyphs(gPtr, numGlyphs, ownGlyphs);
1583*c8dee2aaSAndroid Build Coastguard Worker JSSpan<float> pos (pPtr, numPos, ownPos);
1584*c8dee2aaSAndroid Build Coastguard Worker if (glyphs.size() > (pos.size() >> 1)) {
1585*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val("Not enough x,y position pairs for glyphs");
1586*c8dee2aaSAndroid Build Coastguard Worker }
1587*c8dee2aaSAndroid Build Coastguard Worker auto sects = self.getIntercepts(glyphs.data(), SkToInt(glyphs.size()),
1588*c8dee2aaSAndroid Build Coastguard Worker (const SkPoint*)pos.data(), top, bottom);
1589*c8dee2aaSAndroid Build Coastguard Worker return MakeTypedArray(sects.size(), (const float*)sects.data());
1590*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1591*c8dee2aaSAndroid Build Coastguard Worker .function("getScaleX", &SkFont::getScaleX)
1592*c8dee2aaSAndroid Build Coastguard Worker .function("getSize", &SkFont::getSize)
1593*c8dee2aaSAndroid Build Coastguard Worker .function("getSkewX", &SkFont::getSkewX)
1594*c8dee2aaSAndroid Build Coastguard Worker .function("isEmbolden", &SkFont::isEmbolden)
1595*c8dee2aaSAndroid Build Coastguard Worker .function("getTypeface", &SkFont::getTypeface, allow_raw_pointers())
1596*c8dee2aaSAndroid Build Coastguard Worker .function("setEdging", &SkFont::setEdging)
1597*c8dee2aaSAndroid Build Coastguard Worker .function("setEmbeddedBitmaps", &SkFont::setEmbeddedBitmaps)
1598*c8dee2aaSAndroid Build Coastguard Worker .function("setHinting", &SkFont::setHinting)
1599*c8dee2aaSAndroid Build Coastguard Worker .function("setLinearMetrics", &SkFont::setLinearMetrics)
1600*c8dee2aaSAndroid Build Coastguard Worker .function("setScaleX", &SkFont::setScaleX)
1601*c8dee2aaSAndroid Build Coastguard Worker .function("setSize", &SkFont::setSize)
1602*c8dee2aaSAndroid Build Coastguard Worker .function("setSkewX", &SkFont::setSkewX)
1603*c8dee2aaSAndroid Build Coastguard Worker .function("setEmbolden", &SkFont::setEmbolden)
1604*c8dee2aaSAndroid Build Coastguard Worker .function("setSubpixel", &SkFont::setSubpixel)
1605*c8dee2aaSAndroid Build Coastguard Worker .function("setTypeface", &SkFont::setTypeface, allow_raw_pointers());
1606*c8dee2aaSAndroid Build Coastguard Worker
1607*c8dee2aaSAndroid Build Coastguard Worker class_<SkFontMgr>("FontMgr")
1608*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkFontMgr>>("sk_sp<FontMgr>")
1609*c8dee2aaSAndroid Build Coastguard Worker .class_function("_fromData", optional_override([](WASMPointerU32 dPtr,
1610*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU32 sPtr,
1611*c8dee2aaSAndroid Build Coastguard Worker int numFonts)->sk_sp<SkFontMgr> {
1612*c8dee2aaSAndroid Build Coastguard Worker auto datas = reinterpret_cast<const uint8_t**>(dPtr);
1613*c8dee2aaSAndroid Build Coastguard Worker auto sizes = reinterpret_cast<const size_t*>(sPtr);
1614*c8dee2aaSAndroid Build Coastguard Worker
1615*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<sk_sp<SkData>[]> skdatas(new sk_sp<SkData>[numFonts]);
1616*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < numFonts; ++i) {
1617*c8dee2aaSAndroid Build Coastguard Worker skdatas[i] = SkData::MakeFromMalloc(datas[i], sizes[i]);
1618*c8dee2aaSAndroid Build Coastguard Worker }
1619*c8dee2aaSAndroid Build Coastguard Worker
1620*c8dee2aaSAndroid Build Coastguard Worker return SkFontMgr_New_Custom_Data(SkSpan(skdatas.get(), numFonts));
1621*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1622*c8dee2aaSAndroid Build Coastguard Worker .function("countFamilies", &SkFontMgr::countFamilies)
1623*c8dee2aaSAndroid Build Coastguard Worker .function("getFamilyName", optional_override([](SkFontMgr& self, int index)->JSString {
1624*c8dee2aaSAndroid Build Coastguard Worker if (index < 0 || index >= self.countFamilies()) {
1625*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
1626*c8dee2aaSAndroid Build Coastguard Worker }
1627*c8dee2aaSAndroid Build Coastguard Worker SkString s;
1628*c8dee2aaSAndroid Build Coastguard Worker self.getFamilyName(index, &s);
1629*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(s.c_str());
1630*c8dee2aaSAndroid Build Coastguard Worker }))
1631*c8dee2aaSAndroid Build Coastguard Worker .function("matchFamilyStyle", optional_override([](SkFontMgr& self, std::string name, emscripten::val jsFontStyle)->sk_sp<SkTypeface> {
1632*c8dee2aaSAndroid Build Coastguard Worker auto weight = SkFontStyle::Weight(jsFontStyle["weight"].isUndefined() ? SkFontStyle::kNormal_Weight : jsFontStyle["weight"].as<int>());
1633*c8dee2aaSAndroid Build Coastguard Worker auto width = SkFontStyle::Width(jsFontStyle["width"].isUndefined() ? SkFontStyle::kNormal_Width : jsFontStyle["width"].as<int>());
1634*c8dee2aaSAndroid Build Coastguard Worker auto slant = SkFontStyle::Slant(jsFontStyle["slant"].isUndefined() ? SkFontStyle::kUpright_Slant : static_cast<SkFontStyle::Slant>(jsFontStyle["slant"].as<int>()));
1635*c8dee2aaSAndroid Build Coastguard Worker
1636*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle style(weight, width, slant);
1637*c8dee2aaSAndroid Build Coastguard Worker
1638*c8dee2aaSAndroid Build Coastguard Worker return self.matchFamilyStyle(name.c_str(), style);
1639*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1640*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
1641*c8dee2aaSAndroid Build Coastguard Worker .function("dumpFamilies", optional_override([](SkFontMgr& self) {
1642*c8dee2aaSAndroid Build Coastguard Worker int numFam = self.countFamilies();
1643*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("There are %d font families\n", numFam);
1644*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0 ; i< numFam; i++) {
1645*c8dee2aaSAndroid Build Coastguard Worker SkString s;
1646*c8dee2aaSAndroid Build Coastguard Worker self.getFamilyName(i, &s);
1647*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\t%s\n", s.c_str());
1648*c8dee2aaSAndroid Build Coastguard Worker }
1649*c8dee2aaSAndroid Build Coastguard Worker }))
1650*c8dee2aaSAndroid Build Coastguard Worker #endif
1651*c8dee2aaSAndroid Build Coastguard Worker .function("_makeTypefaceFromData", optional_override([](SkFontMgr& self,
1652*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU8 fPtr,
1653*c8dee2aaSAndroid Build Coastguard Worker int flen)->sk_sp<SkTypeface> {
1654*c8dee2aaSAndroid Build Coastguard Worker uint8_t* font = reinterpret_cast<uint8_t*>(fPtr);
1655*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> fontData = SkData::MakeFromMalloc(font, flen);
1656*c8dee2aaSAndroid Build Coastguard Worker
1657*c8dee2aaSAndroid Build Coastguard Worker return self.makeFromData(fontData);
1658*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1659*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_NO_FONTS
1660*c8dee2aaSAndroid Build Coastguard Worker
1661*c8dee2aaSAndroid Build Coastguard Worker class_<SkImage>("Image")
1662*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkImage>>("sk_sp<Image>")
1663*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
1664*c8dee2aaSAndroid Build Coastguard Worker .class_function("_makeFromGenerator", &MakeImageFromGenerator)
1665*c8dee2aaSAndroid Build Coastguard Worker #endif
1666*c8dee2aaSAndroid Build Coastguard Worker // Note that this needs to be cleaned up with delete().
1667*c8dee2aaSAndroid Build Coastguard Worker .function("getColorSpace", optional_override([](sk_sp<SkImage> self)->sk_sp<SkColorSpace> {
1668*c8dee2aaSAndroid Build Coastguard Worker return self->imageInfo().refColorSpace();
1669*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1670*c8dee2aaSAndroid Build Coastguard Worker .function("getImageInfo", optional_override([](sk_sp<SkImage> self)->JSObject {
1671*c8dee2aaSAndroid Build Coastguard Worker // We cannot return a SimpleImageInfo because the colorspace object would be leaked.
1672*c8dee2aaSAndroid Build Coastguard Worker JSObject result = emscripten::val::object();
1673*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo ii = self->imageInfo();
1674*c8dee2aaSAndroid Build Coastguard Worker result.set("alphaType", ii.alphaType());
1675*c8dee2aaSAndroid Build Coastguard Worker result.set("colorType", ii.colorType());
1676*c8dee2aaSAndroid Build Coastguard Worker result.set("height", ii.height());
1677*c8dee2aaSAndroid Build Coastguard Worker result.set("width", ii.width());
1678*c8dee2aaSAndroid Build Coastguard Worker return result;
1679*c8dee2aaSAndroid Build Coastguard Worker }))
1680*c8dee2aaSAndroid Build Coastguard Worker .function("height", &SkImage::height)
1681*c8dee2aaSAndroid Build Coastguard Worker .function("_encodeToBytes", optional_override([](sk_sp<SkImage> self,
1682*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat fmt,
1683*c8dee2aaSAndroid Build Coastguard Worker int quality) -> Uint8Array {
1684*c8dee2aaSAndroid Build Coastguard Worker return encodeImage(nullptr, self, fmt, quality);
1685*c8dee2aaSAndroid Build Coastguard Worker }))
1686*c8dee2aaSAndroid Build Coastguard Worker #if defined(ENABLE_GPU)
1687*c8dee2aaSAndroid Build Coastguard Worker .function("_encodeToBytes", optional_override([](sk_sp<SkImage> self,
1688*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat fmt,
1689*c8dee2aaSAndroid Build Coastguard Worker int quality,
1690*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* dContext) -> Uint8Array {
1691*c8dee2aaSAndroid Build Coastguard Worker return encodeImage(dContext, self, fmt, quality);
1692*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1693*c8dee2aaSAndroid Build Coastguard Worker #endif
1694*c8dee2aaSAndroid Build Coastguard Worker .function("makeCopyWithDefaultMipmaps", optional_override([](sk_sp<SkImage> self)->sk_sp<SkImage> {
1695*c8dee2aaSAndroid Build Coastguard Worker return self->withDefaultMipmaps();
1696*c8dee2aaSAndroid Build Coastguard Worker }))
1697*c8dee2aaSAndroid Build Coastguard Worker .function("_makeShaderCubic", optional_override([](sk_sp<SkImage> self,
1698*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tx, SkTileMode ty,
1699*c8dee2aaSAndroid Build Coastguard Worker float B, float C, // See SkSamplingOptions.h for docs.
1700*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr)->sk_sp<SkShader> {
1701*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
1702*c8dee2aaSAndroid Build Coastguard Worker return self->makeShader(tx, ty, SkSamplingOptions({B, C}), mPtr ? &localMatrix
1703*c8dee2aaSAndroid Build Coastguard Worker : nullptr);
1704*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1705*c8dee2aaSAndroid Build Coastguard Worker .function("_makeShaderOptions", optional_override([](sk_sp<SkImage> self,
1706*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tx, SkTileMode ty,
1707*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode filter, SkMipmapMode mipmap,
1708*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr)->sk_sp<SkShader> {
1709*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
1710*c8dee2aaSAndroid Build Coastguard Worker return self->makeShader(tx, ty, {filter, mipmap}, mPtr ? &localMatrix : nullptr);
1711*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1712*c8dee2aaSAndroid Build Coastguard Worker #if defined(ENABLE_GPU)
1713*c8dee2aaSAndroid Build Coastguard Worker .function("_readPixels", optional_override([](sk_sp<SkImage> self,
1714*c8dee2aaSAndroid Build Coastguard Worker SimpleImageInfo sii, WASMPointerU8 pPtr,
1715*c8dee2aaSAndroid Build Coastguard Worker size_t dstRowBytes, int srcX, int srcY,
1716*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* dContext)->bool {
1717*c8dee2aaSAndroid Build Coastguard Worker uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1718*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo ii = toSkImageInfo(sii);
1719*c8dee2aaSAndroid Build Coastguard Worker return self->readPixels(dContext, ii, pixels, dstRowBytes, srcX, srcY);
1720*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1721*c8dee2aaSAndroid Build Coastguard Worker #endif
1722*c8dee2aaSAndroid Build Coastguard Worker .function("_readPixels", optional_override([](sk_sp<SkImage> self,
1723*c8dee2aaSAndroid Build Coastguard Worker SimpleImageInfo sii, WASMPointerU8 pPtr,
1724*c8dee2aaSAndroid Build Coastguard Worker size_t dstRowBytes, int srcX, int srcY)->bool {
1725*c8dee2aaSAndroid Build Coastguard Worker uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
1726*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo ii = toSkImageInfo(sii);
1727*c8dee2aaSAndroid Build Coastguard Worker return self->readPixels(nullptr, ii, pixels, dstRowBytes, srcX, srcY);
1728*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1729*c8dee2aaSAndroid Build Coastguard Worker .function("width", &SkImage::width);
1730*c8dee2aaSAndroid Build Coastguard Worker
1731*c8dee2aaSAndroid Build Coastguard Worker class_<SkImageFilter>("ImageFilter")
1732*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkImageFilter>>("sk_sp<ImageFilter>")
1733*c8dee2aaSAndroid Build Coastguard Worker .function("_getOutputBounds", optional_override([](const SkImageFilter& self, WASMPointerF32 bPtr, WASMPointerF32 mPtr, WASMPointerU32 oPtr)->void {
1734*c8dee2aaSAndroid Build Coastguard Worker SkRect* rect = reinterpret_cast<SkRect*>(bPtr);
1735*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix ctm(mPtr);
1736*c8dee2aaSAndroid Build Coastguard Worker SkIRect* output = reinterpret_cast<SkIRect*>(oPtr);
1737*c8dee2aaSAndroid Build Coastguard Worker output[0] = self.filterBounds(ctm.mapRect(*rect).roundOut(), ctm, SkImageFilter::kForward_MapDirection);
1738*c8dee2aaSAndroid Build Coastguard Worker }))
1739*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeBlend", optional_override([](SkBlendMode mode, sk_sp<SkImageFilter> background,
1740*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> foreground)->sk_sp<SkImageFilter> {
1741*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Blend(mode, background, foreground);
1742*c8dee2aaSAndroid Build Coastguard Worker }))
1743*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeBlur", optional_override([](SkScalar sigmaX, SkScalar sigmaY,
1744*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tileMode, sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1745*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Blur(sigmaX, sigmaY, tileMode, input);
1746*c8dee2aaSAndroid Build Coastguard Worker }))
1747*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeColorFilter", optional_override([](sk_sp<SkColorFilter> cf,
1748*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1749*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::ColorFilter(cf, input);
1750*c8dee2aaSAndroid Build Coastguard Worker }))
1751*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeCompose", &SkImageFilters::Compose)
1752*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeDilate", optional_override([](SkScalar radiusX, SkScalar radiusY,
1753*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1754*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Dilate(radiusX, radiusY, input);
1755*c8dee2aaSAndroid Build Coastguard Worker }))
1756*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeDisplacementMap", optional_override([](SkColorChannel xChannelSelector,
1757*c8dee2aaSAndroid Build Coastguard Worker SkColorChannel yChannelSelector,
1758*c8dee2aaSAndroid Build Coastguard Worker SkScalar scale, sk_sp<SkImageFilter> displacement,
1759*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> color)->sk_sp<SkImageFilter> {
1760*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DisplacementMap(xChannelSelector, yChannelSelector,
1761*c8dee2aaSAndroid Build Coastguard Worker scale, displacement, color);
1762*c8dee2aaSAndroid Build Coastguard Worker }))
1763*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeShader", optional_override([](sk_sp<SkShader> shader)->sk_sp<SkImageFilter> {
1764*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Shader(shader);
1765*c8dee2aaSAndroid Build Coastguard Worker }))
1766*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeDropShadow", optional_override([](SkScalar dx, SkScalar dy,
1767*c8dee2aaSAndroid Build Coastguard Worker SkScalar sigmaX, SkScalar sigmaY,
1768*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cPtr, sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1769*c8dee2aaSAndroid Build Coastguard Worker SkColor4f c = ptrToSkColor4f(cPtr);
1770*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DropShadow(dx, dy, sigmaX, sigmaY, c.toSkColor(), input);
1771*c8dee2aaSAndroid Build Coastguard Worker }))
1772*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeDropShadowOnly", optional_override([](SkScalar dx, SkScalar dy,
1773*c8dee2aaSAndroid Build Coastguard Worker SkScalar sigmaX, SkScalar sigmaY,
1774*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cPtr, sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1775*c8dee2aaSAndroid Build Coastguard Worker SkColor4f c = ptrToSkColor4f(cPtr);
1776*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DropShadowOnly(dx, dy, sigmaX, sigmaY, c.toSkColor(), input);
1777*c8dee2aaSAndroid Build Coastguard Worker }))
1778*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeErode", optional_override([](SkScalar radiusX, SkScalar radiusY,
1779*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1780*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Erode(radiusX, radiusY, input);
1781*c8dee2aaSAndroid Build Coastguard Worker }))
1782*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeImageCubic", optional_override([](sk_sp<SkImage> image,
1783*c8dee2aaSAndroid Build Coastguard Worker float B, float C,
1784*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 srcPtr,
1785*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 dstPtr
1786*c8dee2aaSAndroid Build Coastguard Worker )->sk_sp<SkImageFilter> {
1787*c8dee2aaSAndroid Build Coastguard Worker const SkRect* src = reinterpret_cast<const SkRect*>(srcPtr);
1788*c8dee2aaSAndroid Build Coastguard Worker const SkRect* dst = reinterpret_cast<const SkRect*>(dstPtr);
1789*c8dee2aaSAndroid Build Coastguard Worker if (src && dst) {
1790*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Image(image, *src, *dst, SkSamplingOptions({B, C}));
1791*c8dee2aaSAndroid Build Coastguard Worker }
1792*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Image(image, SkSamplingOptions({B, C}));
1793*c8dee2aaSAndroid Build Coastguard Worker }))
1794*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeImageOptions", optional_override([](sk_sp<SkImage> image,
1795*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode fm,
1796*c8dee2aaSAndroid Build Coastguard Worker SkMipmapMode mm,
1797*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 srcPtr,
1798*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 dstPtr
1799*c8dee2aaSAndroid Build Coastguard Worker )->sk_sp<SkImageFilter> {
1800*c8dee2aaSAndroid Build Coastguard Worker const SkRect* src = reinterpret_cast<const SkRect*>(srcPtr);
1801*c8dee2aaSAndroid Build Coastguard Worker const SkRect* dst = reinterpret_cast<const SkRect*>(dstPtr);
1802*c8dee2aaSAndroid Build Coastguard Worker if (src && dst) {
1803*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Image(image, *src, *dst, SkSamplingOptions(fm, mm));
1804*c8dee2aaSAndroid Build Coastguard Worker }
1805*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Image(image, SkSamplingOptions(fm, mm));
1806*c8dee2aaSAndroid Build Coastguard Worker }))
1807*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeMatrixTransformCubic",
1808*c8dee2aaSAndroid Build Coastguard Worker optional_override([](WASMPointerF32 mPtr, float B, float C,
1809*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1810*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix matr(mPtr);
1811*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::MatrixTransform(matr, SkSamplingOptions({B, C}), input);
1812*c8dee2aaSAndroid Build Coastguard Worker }))
1813*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeMatrixTransformOptions",
1814*c8dee2aaSAndroid Build Coastguard Worker optional_override([](WASMPointerF32 mPtr, SkFilterMode fm, SkMipmapMode mm,
1815*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1816*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix matr(mPtr);
1817*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::MatrixTransform(matr, SkSamplingOptions(fm, mm), input);
1818*c8dee2aaSAndroid Build Coastguard Worker }))
1819*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeOffset", optional_override([](SkScalar dx, SkScalar dy,
1820*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
1821*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Offset(dx, dy, input);
1822*c8dee2aaSAndroid Build Coastguard Worker }));
1823*c8dee2aaSAndroid Build Coastguard Worker
1824*c8dee2aaSAndroid Build Coastguard Worker class_<SkMaskFilter>("MaskFilter")
1825*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkMaskFilter>>("sk_sp<MaskFilter>")
1826*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeBlur", optional_override([](SkBlurStyle style, SkScalar sigma, bool respectCTM)->sk_sp<SkMaskFilter> {
1827*c8dee2aaSAndroid Build Coastguard Worker // Adds a little helper because emscripten doesn't expose default params.
1828*c8dee2aaSAndroid Build Coastguard Worker return SkMaskFilter::MakeBlur(style, sigma, respectCTM);
1829*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1830*c8dee2aaSAndroid Build Coastguard Worker
1831*c8dee2aaSAndroid Build Coastguard Worker class_<SkPaint>("Paint")
1832*c8dee2aaSAndroid Build Coastguard Worker .constructor<>()
1833*c8dee2aaSAndroid Build Coastguard Worker .function("copy", optional_override([](const SkPaint& self)->SkPaint {
1834*c8dee2aaSAndroid Build Coastguard Worker SkPaint p(self);
1835*c8dee2aaSAndroid Build Coastguard Worker return p;
1836*c8dee2aaSAndroid Build Coastguard Worker }))
1837*c8dee2aaSAndroid Build Coastguard Worker // provide an allocated place to put the returned color
1838*c8dee2aaSAndroid Build Coastguard Worker .function("_getColor", optional_override([](SkPaint& self, WASMPointerF32 cPtr)->void {
1839*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f& c = self.getColor4f();
1840*c8dee2aaSAndroid Build Coastguard Worker float* fourFloats = reinterpret_cast<float*>(cPtr);
1841*c8dee2aaSAndroid Build Coastguard Worker memcpy(fourFloats, c.vec(), 4 * sizeof(SkScalar));
1842*c8dee2aaSAndroid Build Coastguard Worker }))
1843*c8dee2aaSAndroid Build Coastguard Worker .function("getStrokeCap", &SkPaint::getStrokeCap)
1844*c8dee2aaSAndroid Build Coastguard Worker .function("getStrokeJoin", &SkPaint::getStrokeJoin)
1845*c8dee2aaSAndroid Build Coastguard Worker .function("getStrokeMiter", &SkPaint::getStrokeMiter)
1846*c8dee2aaSAndroid Build Coastguard Worker .function("getStrokeWidth", &SkPaint::getStrokeWidth)
1847*c8dee2aaSAndroid Build Coastguard Worker .function("setAntiAlias", &SkPaint::setAntiAlias)
1848*c8dee2aaSAndroid Build Coastguard Worker .function("setAlphaf", &SkPaint::setAlphaf)
1849*c8dee2aaSAndroid Build Coastguard Worker .function("setBlendMode", &SkPaint::setBlendMode)
1850*c8dee2aaSAndroid Build Coastguard Worker .function("setBlender", &SkPaint::setBlender)
1851*c8dee2aaSAndroid Build Coastguard Worker .function("_setColor", optional_override([](SkPaint& self, WASMPointerF32 cPtr,
1852*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace) {
1853*c8dee2aaSAndroid Build Coastguard Worker self.setColor(ptrToSkColor4f(cPtr), colorSpace.get());
1854*c8dee2aaSAndroid Build Coastguard Worker }))
1855*c8dee2aaSAndroid Build Coastguard Worker .function("setColorInt", optional_override([](SkPaint& self, SkColor color) {
1856*c8dee2aaSAndroid Build Coastguard Worker self.setColor(SkColor4f::FromColor(color), nullptr);
1857*c8dee2aaSAndroid Build Coastguard Worker }))
1858*c8dee2aaSAndroid Build Coastguard Worker .function("setColorInt", optional_override([](SkPaint& self, SkColor color,
1859*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace) {
1860*c8dee2aaSAndroid Build Coastguard Worker self.setColor(SkColor4f::FromColor(color), colorSpace.get());
1861*c8dee2aaSAndroid Build Coastguard Worker }))
1862*c8dee2aaSAndroid Build Coastguard Worker .function("setColorFilter", &SkPaint::setColorFilter)
1863*c8dee2aaSAndroid Build Coastguard Worker .function("setDither", &SkPaint::setDither)
1864*c8dee2aaSAndroid Build Coastguard Worker .function("setImageFilter", &SkPaint::setImageFilter)
1865*c8dee2aaSAndroid Build Coastguard Worker .function("setMaskFilter", &SkPaint::setMaskFilter)
1866*c8dee2aaSAndroid Build Coastguard Worker .function("setPathEffect", &SkPaint::setPathEffect)
1867*c8dee2aaSAndroid Build Coastguard Worker .function("setShader", &SkPaint::setShader)
1868*c8dee2aaSAndroid Build Coastguard Worker .function("setStrokeCap", &SkPaint::setStrokeCap)
1869*c8dee2aaSAndroid Build Coastguard Worker .function("setStrokeJoin", &SkPaint::setStrokeJoin)
1870*c8dee2aaSAndroid Build Coastguard Worker .function("setStrokeMiter", &SkPaint::setStrokeMiter)
1871*c8dee2aaSAndroid Build Coastguard Worker .function("setStrokeWidth", &SkPaint::setStrokeWidth)
1872*c8dee2aaSAndroid Build Coastguard Worker .function("setStyle", &SkPaint::setStyle);
1873*c8dee2aaSAndroid Build Coastguard Worker
1874*c8dee2aaSAndroid Build Coastguard Worker class_<SkColorSpace>("ColorSpace")
1875*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkColorSpace>>("sk_sp<ColorSpace>")
1876*c8dee2aaSAndroid Build Coastguard Worker .class_function("Equals", optional_override([](sk_sp<SkColorSpace> a, sk_sp<SkColorSpace> b)->bool {
1877*c8dee2aaSAndroid Build Coastguard Worker return SkColorSpace::Equals(a.get(), b.get());
1878*c8dee2aaSAndroid Build Coastguard Worker }))
1879*c8dee2aaSAndroid Build Coastguard Worker // These are private because they are to be called once in interface.js to
1880*c8dee2aaSAndroid Build Coastguard Worker // avoid clients having to delete the returned objects.
1881*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeSRGB", &SkColorSpace::MakeSRGB)
1882*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeDisplayP3", optional_override([]()->sk_sp<SkColorSpace> {
1883*c8dee2aaSAndroid Build Coastguard Worker return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3);
1884*c8dee2aaSAndroid Build Coastguard Worker }))
1885*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeAdobeRGB", optional_override([]()->sk_sp<SkColorSpace> {
1886*c8dee2aaSAndroid Build Coastguard Worker return SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB);
1887*c8dee2aaSAndroid Build Coastguard Worker }));
1888*c8dee2aaSAndroid Build Coastguard Worker
1889*c8dee2aaSAndroid Build Coastguard Worker class_<SkPathEffect>("PathEffect")
1890*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkPathEffect>>("sk_sp<PathEffect>")
1891*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeCorner", &SkCornerPathEffect::Make)
1892*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeDash", optional_override([](WASMPointerF32 cptr, int count,
1893*c8dee2aaSAndroid Build Coastguard Worker SkScalar phase)->sk_sp<SkPathEffect> {
1894*c8dee2aaSAndroid Build Coastguard Worker const float* intervals = reinterpret_cast<const float*>(cptr);
1895*c8dee2aaSAndroid Build Coastguard Worker return SkDashPathEffect::Make(intervals, count, phase);
1896*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1897*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeDiscrete", &SkDiscretePathEffect::Make)
1898*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeLine2D", optional_override([](SkScalar width,
1899*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr)->sk_sp<SkPathEffect> {
1900*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
1901*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* nineMatrixValues = reinterpret_cast<const SkScalar*>(mPtr);
1902*c8dee2aaSAndroid Build Coastguard Worker matrix.set9(nineMatrixValues);
1903*c8dee2aaSAndroid Build Coastguard Worker return SkLine2DPathEffect::Make(width, matrix);
1904*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
1905*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakePath1D", &SkPath1DPathEffect::Make)
1906*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakePath2D", optional_override([](WASMPointerF32 mPtr,
1907*c8dee2aaSAndroid Build Coastguard Worker SkPath path)->sk_sp<SkPathEffect> {
1908*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
1909*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* nineMatrixValues = reinterpret_cast<const SkScalar*>(mPtr);
1910*c8dee2aaSAndroid Build Coastguard Worker matrix.set9(nineMatrixValues);
1911*c8dee2aaSAndroid Build Coastguard Worker return SkPath2DPathEffect::Make(matrix, path);
1912*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
1913*c8dee2aaSAndroid Build Coastguard Worker
1914*c8dee2aaSAndroid Build Coastguard Worker // TODO(kjlubick, reed) Make SkPath immutable and only creatable via a factory/builder.
1915*c8dee2aaSAndroid Build Coastguard Worker class_<SkPath>("Path")
1916*c8dee2aaSAndroid Build Coastguard Worker .constructor<>()
1917*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PATHOPS
1918*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeFromOp", &MakePathFromOp)
1919*c8dee2aaSAndroid Build Coastguard Worker #endif
1920*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeFromSVGString", &MakePathFromSVGString)
1921*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeFromPathInterpolation", &MakePathFromInterpolation)
1922*c8dee2aaSAndroid Build Coastguard Worker .class_function("CanInterpolate", &CanInterpolate)
1923*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeFromCmds", &MakePathFromCmds)
1924*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeFromVerbsPointsWeights", &MakePathFromVerbsPointsWeights)
1925*c8dee2aaSAndroid Build Coastguard Worker .function("_addArc", optional_override([](SkPath& self,
1926*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
1927*c8dee2aaSAndroid Build Coastguard Worker SkScalar startAngle, SkScalar sweepAngle)->void {
1928*c8dee2aaSAndroid Build Coastguard Worker const SkRect* oval = reinterpret_cast<const SkRect*>(fPtr);
1929*c8dee2aaSAndroid Build Coastguard Worker self.addArc(*oval, startAngle, sweepAngle);
1930*c8dee2aaSAndroid Build Coastguard Worker }))
1931*c8dee2aaSAndroid Build Coastguard Worker .function("_addOval", optional_override([](SkPath& self,
1932*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
1933*c8dee2aaSAndroid Build Coastguard Worker bool ccw, unsigned start)->void {
1934*c8dee2aaSAndroid Build Coastguard Worker const SkRect* oval = reinterpret_cast<const SkRect*>(fPtr);
1935*c8dee2aaSAndroid Build Coastguard Worker self.addOval(*oval, ccw ? SkPathDirection::kCCW : SkPathDirection::kCW, start);
1936*c8dee2aaSAndroid Build Coastguard Worker }))
1937*c8dee2aaSAndroid Build Coastguard Worker .function("_addCircle", optional_override([](SkPath& self,
1938*c8dee2aaSAndroid Build Coastguard Worker SkScalar x,
1939*c8dee2aaSAndroid Build Coastguard Worker SkScalar y,
1940*c8dee2aaSAndroid Build Coastguard Worker SkScalar r,
1941*c8dee2aaSAndroid Build Coastguard Worker bool ccw)->void {
1942*c8dee2aaSAndroid Build Coastguard Worker self.addCircle(x, y, r, ccw ? SkPathDirection::kCCW : SkPathDirection::kCW);
1943*c8dee2aaSAndroid Build Coastguard Worker }))
1944*c8dee2aaSAndroid Build Coastguard Worker // interface.js has 3 overloads of addPath
1945*c8dee2aaSAndroid Build Coastguard Worker .function("_addPath", &ApplyAddPath)
1946*c8dee2aaSAndroid Build Coastguard Worker .function("_addPoly", optional_override([](SkPath& self,
1947*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
1948*c8dee2aaSAndroid Build Coastguard Worker int count, bool close)->void {
1949*c8dee2aaSAndroid Build Coastguard Worker const SkPoint* pts = reinterpret_cast<const SkPoint*>(fPtr);
1950*c8dee2aaSAndroid Build Coastguard Worker self.addPoly(pts, count, close);
1951*c8dee2aaSAndroid Build Coastguard Worker }))
1952*c8dee2aaSAndroid Build Coastguard Worker .function("_addRect", optional_override([](SkPath& self,
1953*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
1954*c8dee2aaSAndroid Build Coastguard Worker bool ccw)->void {
1955*c8dee2aaSAndroid Build Coastguard Worker const SkRect* rect = reinterpret_cast<const SkRect*>(fPtr);
1956*c8dee2aaSAndroid Build Coastguard Worker self.addRect(*rect, ccw ? SkPathDirection::kCCW : SkPathDirection::kCW);
1957*c8dee2aaSAndroid Build Coastguard Worker }))
1958*c8dee2aaSAndroid Build Coastguard Worker .function("_addRRect", optional_override([](SkPath& self,
1959*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
1960*c8dee2aaSAndroid Build Coastguard Worker bool ccw)->void {
1961*c8dee2aaSAndroid Build Coastguard Worker self.addRRect(ptrToSkRRect(fPtr), ccw ? SkPathDirection::kCCW : SkPathDirection::kCW);
1962*c8dee2aaSAndroid Build Coastguard Worker }))
1963*c8dee2aaSAndroid Build Coastguard Worker .function("_addVerbsPointsWeights", &PathAddVerbsPointsWeights)
1964*c8dee2aaSAndroid Build Coastguard Worker .function("_arcToOval", optional_override([](SkPath& self,
1965*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr, SkScalar startAngle,
1966*c8dee2aaSAndroid Build Coastguard Worker SkScalar sweepAngle, bool forceMoveTo)->void {
1967*c8dee2aaSAndroid Build Coastguard Worker const SkRect* oval = reinterpret_cast<const SkRect*>(fPtr);
1968*c8dee2aaSAndroid Build Coastguard Worker self.arcTo(*oval, startAngle, sweepAngle, forceMoveTo);
1969*c8dee2aaSAndroid Build Coastguard Worker }))
1970*c8dee2aaSAndroid Build Coastguard Worker .function("_arcToRotated", &ApplyArcToArcSize)
1971*c8dee2aaSAndroid Build Coastguard Worker .function("_arcToTangent", ApplyArcToTangent)
1972*c8dee2aaSAndroid Build Coastguard Worker .function("_close", &ApplyClose)
1973*c8dee2aaSAndroid Build Coastguard Worker .function("_conicTo", &ApplyConicTo)
1974*c8dee2aaSAndroid Build Coastguard Worker .function("countPoints", &SkPath::countPoints)
1975*c8dee2aaSAndroid Build Coastguard Worker .function("contains", &SkPath::contains)
1976*c8dee2aaSAndroid Build Coastguard Worker .function("_cubicTo", &ApplyCubicTo)
1977*c8dee2aaSAndroid Build Coastguard Worker .function("_getPoint", optional_override([](SkPath& self, int index,
1978*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 oPtr)->void {
1979*c8dee2aaSAndroid Build Coastguard Worker SkPoint* output = reinterpret_cast<SkPoint*>(oPtr);
1980*c8dee2aaSAndroid Build Coastguard Worker *output = self.getPoint(index);
1981*c8dee2aaSAndroid Build Coastguard Worker }))
1982*c8dee2aaSAndroid Build Coastguard Worker .function("isEmpty", &SkPath::isEmpty)
1983*c8dee2aaSAndroid Build Coastguard Worker .function("isVolatile", &SkPath::isVolatile)
1984*c8dee2aaSAndroid Build Coastguard Worker .function("_lineTo", &ApplyLineTo)
1985*c8dee2aaSAndroid Build Coastguard Worker .function("_moveTo", &ApplyMoveTo)
1986*c8dee2aaSAndroid Build Coastguard Worker .function("_quadTo", &ApplyQuadTo)
1987*c8dee2aaSAndroid Build Coastguard Worker .function("_rArcTo", &ApplyRArcToArcSize)
1988*c8dee2aaSAndroid Build Coastguard Worker .function("_rConicTo", &ApplyRConicTo)
1989*c8dee2aaSAndroid Build Coastguard Worker .function("_rCubicTo", &ApplyRCubicTo)
1990*c8dee2aaSAndroid Build Coastguard Worker .function("_rLineTo", &ApplyRLineTo)
1991*c8dee2aaSAndroid Build Coastguard Worker .function("_rMoveTo", &ApplyRMoveTo)
1992*c8dee2aaSAndroid Build Coastguard Worker .function("_rQuadTo", &ApplyRQuadTo)
1993*c8dee2aaSAndroid Build Coastguard Worker .function("reset", &ApplyReset)
1994*c8dee2aaSAndroid Build Coastguard Worker .function("rewind", &ApplyRewind)
1995*c8dee2aaSAndroid Build Coastguard Worker .function("setIsVolatile", &SkPath::setIsVolatile)
1996*c8dee2aaSAndroid Build Coastguard Worker .function("_transform", select_overload<void(SkPath&, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar, SkScalar)>(&ApplyTransform))
1997*c8dee2aaSAndroid Build Coastguard Worker
1998*c8dee2aaSAndroid Build Coastguard Worker // PathEffects
1999*c8dee2aaSAndroid Build Coastguard Worker .function("_dash", &ApplyDash)
2000*c8dee2aaSAndroid Build Coastguard Worker .function("_trim", &ApplyTrim)
2001*c8dee2aaSAndroid Build Coastguard Worker .function("_stroke", &ApplyStroke)
2002*c8dee2aaSAndroid Build Coastguard Worker
2003*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PATHOPS
2004*c8dee2aaSAndroid Build Coastguard Worker // PathOps
2005*c8dee2aaSAndroid Build Coastguard Worker .function("_simplify", &ApplySimplify)
2006*c8dee2aaSAndroid Build Coastguard Worker .function("_op", &ApplyPathOp)
2007*c8dee2aaSAndroid Build Coastguard Worker .function("makeAsWinding", &MakeAsWinding)
2008*c8dee2aaSAndroid Build Coastguard Worker #endif
2009*c8dee2aaSAndroid Build Coastguard Worker // Exporting
2010*c8dee2aaSAndroid Build Coastguard Worker .function("toSVGString", &ToSVGString)
2011*c8dee2aaSAndroid Build Coastguard Worker .function("toCmds", &ToCmds)
2012*c8dee2aaSAndroid Build Coastguard Worker
2013*c8dee2aaSAndroid Build Coastguard Worker .function("setFillType", select_overload<void(SkPathFillType)>(&SkPath::setFillType))
2014*c8dee2aaSAndroid Build Coastguard Worker .function("getFillType", &SkPath::getFillType)
2015*c8dee2aaSAndroid Build Coastguard Worker .function("_getBounds", optional_override([](SkPath& self,
2016*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr)->void {
2017*c8dee2aaSAndroid Build Coastguard Worker SkRect* output = reinterpret_cast<SkRect*>(fPtr);
2018*c8dee2aaSAndroid Build Coastguard Worker output[0] = self.getBounds();
2019*c8dee2aaSAndroid Build Coastguard Worker }))
2020*c8dee2aaSAndroid Build Coastguard Worker .function("_computeTightBounds", optional_override([](SkPath& self,
2021*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr)->void {
2022*c8dee2aaSAndroid Build Coastguard Worker SkRect* output = reinterpret_cast<SkRect*>(fPtr);
2023*c8dee2aaSAndroid Build Coastguard Worker output[0] = self.computeTightBounds();
2024*c8dee2aaSAndroid Build Coastguard Worker }))
2025*c8dee2aaSAndroid Build Coastguard Worker .function("equals", &Equals)
2026*c8dee2aaSAndroid Build Coastguard Worker .function("copy", &CopyPath)
2027*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
2028*c8dee2aaSAndroid Build Coastguard Worker .function("dump", select_overload<void() const>(&SkPath::dump))
2029*c8dee2aaSAndroid Build Coastguard Worker .function("dumpHex", select_overload<void() const>(&SkPath::dumpHex))
2030*c8dee2aaSAndroid Build Coastguard Worker #endif
2031*c8dee2aaSAndroid Build Coastguard Worker ;
2032*c8dee2aaSAndroid Build Coastguard Worker
2033*c8dee2aaSAndroid Build Coastguard Worker static SkRTreeFactory bbhFactory;
2034*c8dee2aaSAndroid Build Coastguard Worker class_<SkPictureRecorder>("PictureRecorder")
2035*c8dee2aaSAndroid Build Coastguard Worker .constructor<>()
2036*c8dee2aaSAndroid Build Coastguard Worker .function("_beginRecording", optional_override([](SkPictureRecorder& self,
2037*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
2038*c8dee2aaSAndroid Build Coastguard Worker bool computeBounds) -> SkCanvas* {
2039*c8dee2aaSAndroid Build Coastguard Worker SkRect* bounds = reinterpret_cast<SkRect*>(fPtr);
2040*c8dee2aaSAndroid Build Coastguard Worker return self.beginRecording(*bounds, computeBounds ? &bbhFactory : nullptr);
2041*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2042*c8dee2aaSAndroid Build Coastguard Worker .function("finishRecordingAsPicture", optional_override([](SkPictureRecorder& self)
2043*c8dee2aaSAndroid Build Coastguard Worker -> sk_sp<SkPicture> {
2044*c8dee2aaSAndroid Build Coastguard Worker return self.finishRecordingAsPicture();
2045*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
2046*c8dee2aaSAndroid Build Coastguard Worker
2047*c8dee2aaSAndroid Build Coastguard Worker class_<SkPicture>("Picture")
2048*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkPicture>>("sk_sp<Picture>")
2049*c8dee2aaSAndroid Build Coastguard Worker .function("_makeShader", optional_override([](SkPicture& self,
2050*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tmx, SkTileMode tmy, SkFilterMode mode,
2051*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr, WASMPointerF32 rPtr) -> sk_sp<SkShader> {
2052*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2053*c8dee2aaSAndroid Build Coastguard Worker SkRect* tileRect = reinterpret_cast<SkRect*>(rPtr);
2054*c8dee2aaSAndroid Build Coastguard Worker return self.makeShader(tmx, tmy, mode, mPtr ? &localMatrix : nullptr, tileRect);
2055*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2056*c8dee2aaSAndroid Build Coastguard Worker .function("_cullRect", optional_override([](SkPicture& self,
2057*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr)->void {
2058*c8dee2aaSAndroid Build Coastguard Worker SkRect* output = reinterpret_cast<SkRect*>(fPtr);
2059*c8dee2aaSAndroid Build Coastguard Worker output[0] = self.cullRect();
2060*c8dee2aaSAndroid Build Coastguard Worker }))
2061*c8dee2aaSAndroid Build Coastguard Worker .function("approximateBytesUsed", &SkPicture::approximateBytesUsed)
2062*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_SERIALIZE_SKP
2063*c8dee2aaSAndroid Build Coastguard Worker // The serialized format of an SkPicture (informally called an "skp"), is not something
2064*c8dee2aaSAndroid Build Coastguard Worker // that clients should ever rely on. The format may change at anytime and no promises
2065*c8dee2aaSAndroid Build Coastguard Worker // are made for backwards or forward compatibility.
2066*c8dee2aaSAndroid Build Coastguard Worker .function("serialize", optional_override([](SkPicture& self) -> Uint8Array {
2067*c8dee2aaSAndroid Build Coastguard Worker // We want to make sure we always save the underlying data of the Typeface to the
2068*c8dee2aaSAndroid Build Coastguard Worker // SkPicture. By default, the data for "system" fonts is not saved, just an identifier
2069*c8dee2aaSAndroid Build Coastguard Worker // (e.g. the family name and style). We do not want the user to have to supply a
2070*c8dee2aaSAndroid Build Coastguard Worker // FontMgr with the correct fonts by name when deserializing, so we choose to always
2071*c8dee2aaSAndroid Build Coastguard Worker // serialize the underlying data. This makes the SKPs a bit bigger, but easier to use.
2072*c8dee2aaSAndroid Build Coastguard Worker SkSerialProcs sp;
2073*c8dee2aaSAndroid Build Coastguard Worker sp.fTypefaceProc = &alwaysSaveTypefaceBytes;
2074*c8dee2aaSAndroid Build Coastguard Worker sp.fImageProc = [](SkImage* img, void*) -> sk_sp<SkData> {
2075*c8dee2aaSAndroid Build Coastguard Worker return SkPngEncoder::Encode(nullptr, img, SkPngEncoder::Options{});
2076*c8dee2aaSAndroid Build Coastguard Worker };
2077*c8dee2aaSAndroid Build Coastguard Worker
2078*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = self.serialize(&sp);
2079*c8dee2aaSAndroid Build Coastguard Worker if (!data) {
2080*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val::null();
2081*c8dee2aaSAndroid Build Coastguard Worker }
2082*c8dee2aaSAndroid Build Coastguard Worker return toBytes(data);
2083*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2084*c8dee2aaSAndroid Build Coastguard Worker #endif
2085*c8dee2aaSAndroid Build Coastguard Worker ;
2086*c8dee2aaSAndroid Build Coastguard Worker
2087*c8dee2aaSAndroid Build Coastguard Worker class_<SkShader>("Shader")
2088*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkShader>>("sk_sp<Shader>")
2089*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeBlend", select_overload<sk_sp<SkShader>(SkBlendMode, sk_sp<SkShader>, sk_sp<SkShader>)>(&SkShaders::Blend))
2090*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeColor",
2091*c8dee2aaSAndroid Build Coastguard Worker optional_override([](WASMPointerF32 cPtr, sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
2092*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::Color(ptrToSkColor4f(cPtr), colorSpace);
2093*c8dee2aaSAndroid Build Coastguard Worker })
2094*c8dee2aaSAndroid Build Coastguard Worker )
2095*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeFractalNoise", optional_override([](
2096*c8dee2aaSAndroid Build Coastguard Worker SkScalar baseFreqX, SkScalar baseFreqY,
2097*c8dee2aaSAndroid Build Coastguard Worker int numOctaves, SkScalar seed,
2098*c8dee2aaSAndroid Build Coastguard Worker int tileW, int tileH)->sk_sp<SkShader> {
2099*c8dee2aaSAndroid Build Coastguard Worker // if tileSize is empty (e.g. tileW <= 0 or tileH <= 0, it will be ignored.
2100*c8dee2aaSAndroid Build Coastguard Worker SkISize tileSize = SkISize::Make(tileW, tileH);
2101*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::MakeFractalNoise(baseFreqX, baseFreqY, numOctaves, seed, &tileSize);
2102*c8dee2aaSAndroid Build Coastguard Worker }))
2103*c8dee2aaSAndroid Build Coastguard Worker // Here and in other gradient functions, cPtr is a pointer to an array of data
2104*c8dee2aaSAndroid Build Coastguard Worker // representing colors. whether this is an array of SkColor or SkColor4f is indicated
2105*c8dee2aaSAndroid Build Coastguard Worker // by the colorType argument. Only RGBA_8888 and RGBA_F32 are accepted.
2106*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeLinearGradient", optional_override([](
2107*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fourFloatsPtr,
2108*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cPtr, SkColorType colorType,
2109*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 pPtr,
2110*c8dee2aaSAndroid Build Coastguard Worker int count, SkTileMode mode, uint32_t flags,
2111*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr,
2112*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
2113*c8dee2aaSAndroid Build Coastguard Worker const SkPoint* points = reinterpret_cast<const SkPoint*>(fourFloatsPtr);
2114*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
2115*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2116*c8dee2aaSAndroid Build Coastguard Worker
2117*c8dee2aaSAndroid Build Coastguard Worker if (colorType == SkColorType::kRGBA_F32_SkColorType) {
2118*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
2119*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeLinear(points, colors, colorSpace, positions, count,
2120*c8dee2aaSAndroid Build Coastguard Worker mode, flags,
2121*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2122*c8dee2aaSAndroid Build Coastguard Worker } else if (colorType == SkColorType::kRGBA_8888_SkColorType) {
2123*c8dee2aaSAndroid Build Coastguard Worker const SkColor* colors = reinterpret_cast<const SkColor*>(cPtr);
2124*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeLinear(points, colors, positions, count,
2125*c8dee2aaSAndroid Build Coastguard Worker mode, flags,
2126*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2127*c8dee2aaSAndroid Build Coastguard Worker }
2128*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%d is not an accepted colorType\n", colorType);
2129*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2130*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2131*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeRadialGradient", optional_override([](
2132*c8dee2aaSAndroid Build Coastguard Worker SkScalar cx, SkScalar cy, SkScalar radius,
2133*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cPtr, SkColorType colorType,
2134*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 pPtr,
2135*c8dee2aaSAndroid Build Coastguard Worker int count, SkTileMode mode, uint32_t flags,
2136*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr,
2137*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
2138*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
2139*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2140*c8dee2aaSAndroid Build Coastguard Worker if (colorType == SkColorType::kRGBA_F32_SkColorType) {
2141*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
2142*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeRadial({cx, cy}, radius, colors, colorSpace,
2143*c8dee2aaSAndroid Build Coastguard Worker positions, count, mode, flags,
2144*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2145*c8dee2aaSAndroid Build Coastguard Worker } else if (colorType == SkColorType::kRGBA_8888_SkColorType) {
2146*c8dee2aaSAndroid Build Coastguard Worker const SkColor* colors = reinterpret_cast<const SkColor*>(cPtr);
2147*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeRadial({cx, cy}, radius, colors, positions,
2148*c8dee2aaSAndroid Build Coastguard Worker count, mode, flags,
2149*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2150*c8dee2aaSAndroid Build Coastguard Worker }
2151*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%d is not an accepted colorType\n", colorType);
2152*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2153*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2154*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeSweepGradient", optional_override([](SkScalar cx, SkScalar cy,
2155*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cPtr, SkColorType colorType,
2156*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 pPtr,
2157*c8dee2aaSAndroid Build Coastguard Worker int count, SkTileMode mode,
2158*c8dee2aaSAndroid Build Coastguard Worker SkScalar startAngle, SkScalar endAngle,
2159*c8dee2aaSAndroid Build Coastguard Worker uint32_t flags,
2160*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr,
2161*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
2162*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
2163*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2164*c8dee2aaSAndroid Build Coastguard Worker if (colorType == SkColorType::kRGBA_F32_SkColorType) {
2165*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
2166*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeSweep(cx, cy, colors, colorSpace, positions, count,
2167*c8dee2aaSAndroid Build Coastguard Worker mode, startAngle, endAngle, flags,
2168*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2169*c8dee2aaSAndroid Build Coastguard Worker } else if (colorType == SkColorType::kRGBA_8888_SkColorType) {
2170*c8dee2aaSAndroid Build Coastguard Worker const SkColor* colors = reinterpret_cast<const SkColor*>(cPtr);
2171*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeSweep(cx, cy, colors, positions, count,
2172*c8dee2aaSAndroid Build Coastguard Worker mode, startAngle, endAngle, flags,
2173*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2174*c8dee2aaSAndroid Build Coastguard Worker }
2175*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%d is not an accepted colorType\n", colorType);
2176*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2177*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2178*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeTurbulence", optional_override([](
2179*c8dee2aaSAndroid Build Coastguard Worker SkScalar baseFreqX, SkScalar baseFreqY,
2180*c8dee2aaSAndroid Build Coastguard Worker int numOctaves, SkScalar seed,
2181*c8dee2aaSAndroid Build Coastguard Worker int tileW, int tileH)->sk_sp<SkShader> {
2182*c8dee2aaSAndroid Build Coastguard Worker // if tileSize is empty (e.g. tileW <= 0 or tileH <= 0, it will be ignored.
2183*c8dee2aaSAndroid Build Coastguard Worker SkISize tileSize = SkISize::Make(tileW, tileH);
2184*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::MakeTurbulence(baseFreqX, baseFreqY, numOctaves, seed, &tileSize);
2185*c8dee2aaSAndroid Build Coastguard Worker }))
2186*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeTwoPointConicalGradient", optional_override([](
2187*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fourFloatsPtr,
2188*c8dee2aaSAndroid Build Coastguard Worker SkScalar startRadius, SkScalar endRadius,
2189*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 cPtr, SkColorType colorType,
2190*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 pPtr,
2191*c8dee2aaSAndroid Build Coastguard Worker int count, SkTileMode mode, uint32_t flags,
2192*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr,
2193*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
2194*c8dee2aaSAndroid Build Coastguard Worker const SkPoint* startAndEnd = reinterpret_cast<const SkPoint*>(fourFloatsPtr);
2195*c8dee2aaSAndroid Build Coastguard Worker const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
2196*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2197*c8dee2aaSAndroid Build Coastguard Worker
2198*c8dee2aaSAndroid Build Coastguard Worker if (colorType == SkColorType::kRGBA_F32_SkColorType) {
2199*c8dee2aaSAndroid Build Coastguard Worker const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
2200*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeTwoPointConical(startAndEnd[0], startRadius,
2201*c8dee2aaSAndroid Build Coastguard Worker startAndEnd[1], endRadius,
2202*c8dee2aaSAndroid Build Coastguard Worker colors, colorSpace, positions, count, mode,
2203*c8dee2aaSAndroid Build Coastguard Worker flags,
2204*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2205*c8dee2aaSAndroid Build Coastguard Worker } else if (colorType == SkColorType::kRGBA_8888_SkColorType) {
2206*c8dee2aaSAndroid Build Coastguard Worker const SkColor* colors = reinterpret_cast<const SkColor*>(cPtr);
2207*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeTwoPointConical(startAndEnd[0],
2208*c8dee2aaSAndroid Build Coastguard Worker startRadius,
2209*c8dee2aaSAndroid Build Coastguard Worker startAndEnd[1],
2210*c8dee2aaSAndroid Build Coastguard Worker endRadius,
2211*c8dee2aaSAndroid Build Coastguard Worker colors,
2212*c8dee2aaSAndroid Build Coastguard Worker positions,
2213*c8dee2aaSAndroid Build Coastguard Worker count,
2214*c8dee2aaSAndroid Build Coastguard Worker mode,
2215*c8dee2aaSAndroid Build Coastguard Worker flags,
2216*c8dee2aaSAndroid Build Coastguard Worker mPtr ? &localMatrix : nullptr);
2217*c8dee2aaSAndroid Build Coastguard Worker }
2218*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%d is not an accepted colorType\n", colorType);
2219*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2220*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
2221*c8dee2aaSAndroid Build Coastguard Worker
2222*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_RUNTIME_EFFECT
2223*c8dee2aaSAndroid Build Coastguard Worker class_<SkSL::DebugTrace>("DebugTrace")
2224*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkSL::DebugTrace>>("sk_sp<DebugTrace>")
2225*c8dee2aaSAndroid Build Coastguard Worker .function("writeTrace", optional_override([](SkSL::DebugTrace& self) -> std::string {
2226*c8dee2aaSAndroid Build Coastguard Worker SkDynamicMemoryWStream wstream;
2227*c8dee2aaSAndroid Build Coastguard Worker self.writeTrace(&wstream);
2228*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> trace = wstream.detachAsData();
2229*c8dee2aaSAndroid Build Coastguard Worker return std::string(reinterpret_cast<const char*>(trace->bytes()), trace->size());
2230*c8dee2aaSAndroid Build Coastguard Worker }));
2231*c8dee2aaSAndroid Build Coastguard Worker
2232*c8dee2aaSAndroid Build Coastguard Worker value_object<SkRuntimeEffect::TracedShader>("TracedShader")
2233*c8dee2aaSAndroid Build Coastguard Worker .field("shader", &SkRuntimeEffect::TracedShader::shader)
2234*c8dee2aaSAndroid Build Coastguard Worker .field("debugTrace", &SkRuntimeEffect::TracedShader::debugTrace);
2235*c8dee2aaSAndroid Build Coastguard Worker
2236*c8dee2aaSAndroid Build Coastguard Worker class_<SkRuntimeEffect>("RuntimeEffect")
2237*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkRuntimeEffect>>("sk_sp<RuntimeEffect>")
2238*c8dee2aaSAndroid Build Coastguard Worker .class_function("_Make", optional_override([](std::string sksl,
2239*c8dee2aaSAndroid Build Coastguard Worker emscripten::val errHandler
2240*c8dee2aaSAndroid Build Coastguard Worker )->sk_sp<SkRuntimeEffect> {
2241*c8dee2aaSAndroid Build Coastguard Worker SkString s(sksl.c_str(), sksl.length());
2242*c8dee2aaSAndroid Build Coastguard Worker auto [effect, errorText] = SkRuntimeEffect::MakeForShader(s);
2243*c8dee2aaSAndroid Build Coastguard Worker if (!effect) {
2244*c8dee2aaSAndroid Build Coastguard Worker errHandler.call<void>("onError", val(errorText.c_str()));
2245*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2246*c8dee2aaSAndroid Build Coastguard Worker }
2247*c8dee2aaSAndroid Build Coastguard Worker return effect;
2248*c8dee2aaSAndroid Build Coastguard Worker }))
2249*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeForBlender", optional_override([](std::string sksl,
2250*c8dee2aaSAndroid Build Coastguard Worker emscripten::val errHandler
2251*c8dee2aaSAndroid Build Coastguard Worker )->sk_sp<SkRuntimeEffect> {
2252*c8dee2aaSAndroid Build Coastguard Worker SkString s(sksl.c_str(), sksl.length());
2253*c8dee2aaSAndroid Build Coastguard Worker auto [effect, errorText] = SkRuntimeEffect::MakeForBlender(s);
2254*c8dee2aaSAndroid Build Coastguard Worker if (!effect) {
2255*c8dee2aaSAndroid Build Coastguard Worker errHandler.call<void>("onError", val(errorText.c_str()));
2256*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2257*c8dee2aaSAndroid Build Coastguard Worker }
2258*c8dee2aaSAndroid Build Coastguard Worker return effect;
2259*c8dee2aaSAndroid Build Coastguard Worker }))
2260*c8dee2aaSAndroid Build Coastguard Worker .class_function("MakeTraced", optional_override([](
2261*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> shader,
2262*c8dee2aaSAndroid Build Coastguard Worker int traceCoordX,
2263*c8dee2aaSAndroid Build Coastguard Worker int traceCoordY) -> SkRuntimeEffect::TracedShader {
2264*c8dee2aaSAndroid Build Coastguard Worker return SkRuntimeEffect::MakeTraced(shader, SkIPoint::Make(traceCoordX, traceCoordY));
2265*c8dee2aaSAndroid Build Coastguard Worker }))
2266*c8dee2aaSAndroid Build Coastguard Worker .function("_makeShader", optional_override([](SkRuntimeEffect& self,
2267*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
2268*c8dee2aaSAndroid Build Coastguard Worker size_t fLen,
2269*c8dee2aaSAndroid Build Coastguard Worker bool shouldOwnUniforms,
2270*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr)->sk_sp<SkShader> {
2271*c8dee2aaSAndroid Build Coastguard Worker void* uniformData = reinterpret_cast<void*>(fPtr);
2272*c8dee2aaSAndroid Build Coastguard Worker castUniforms(uniformData, fLen, self);
2273*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> uniforms;
2274*c8dee2aaSAndroid Build Coastguard Worker if (shouldOwnUniforms) {
2275*c8dee2aaSAndroid Build Coastguard Worker uniforms = SkData::MakeFromMalloc(uniformData, fLen);
2276*c8dee2aaSAndroid Build Coastguard Worker } else {
2277*c8dee2aaSAndroid Build Coastguard Worker uniforms = SkData::MakeWithoutCopy(uniformData, fLen);
2278*c8dee2aaSAndroid Build Coastguard Worker }
2279*c8dee2aaSAndroid Build Coastguard Worker
2280*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2281*c8dee2aaSAndroid Build Coastguard Worker return self.makeShader(uniforms, nullptr, 0, mPtr ? &localMatrix : nullptr);
2282*c8dee2aaSAndroid Build Coastguard Worker }))
2283*c8dee2aaSAndroid Build Coastguard Worker .function("_makeShaderWithChildren", optional_override([](SkRuntimeEffect& self,
2284*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
2285*c8dee2aaSAndroid Build Coastguard Worker size_t fLen,
2286*c8dee2aaSAndroid Build Coastguard Worker bool shouldOwnUniforms,
2287*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU32 cPtrs,
2288*c8dee2aaSAndroid Build Coastguard Worker size_t cLen,
2289*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 mPtr)->sk_sp<SkShader> {
2290*c8dee2aaSAndroid Build Coastguard Worker void* uniformData = reinterpret_cast<void*>(fPtr);
2291*c8dee2aaSAndroid Build Coastguard Worker castUniforms(uniformData, fLen, self);
2292*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> uniforms;
2293*c8dee2aaSAndroid Build Coastguard Worker if (shouldOwnUniforms) {
2294*c8dee2aaSAndroid Build Coastguard Worker uniforms = SkData::MakeFromMalloc(uniformData, fLen);
2295*c8dee2aaSAndroid Build Coastguard Worker } else {
2296*c8dee2aaSAndroid Build Coastguard Worker uniforms = SkData::MakeWithoutCopy(uniformData, fLen);
2297*c8dee2aaSAndroid Build Coastguard Worker }
2298*c8dee2aaSAndroid Build Coastguard Worker
2299*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader>* children = new sk_sp<SkShader>[cLen];
2300*c8dee2aaSAndroid Build Coastguard Worker SkShader** childrenPtrs = reinterpret_cast<SkShader**>(cPtrs);
2301*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < cLen; i++) {
2302*c8dee2aaSAndroid Build Coastguard Worker // This bare pointer was already part of an sk_sp (owned outside of here),
2303*c8dee2aaSAndroid Build Coastguard Worker // so we want to ref the new sk_sp so makeShader doesn't clean it up.
2304*c8dee2aaSAndroid Build Coastguard Worker children[i] = sk_ref_sp<SkShader>(childrenPtrs[i]);
2305*c8dee2aaSAndroid Build Coastguard Worker }
2306*c8dee2aaSAndroid Build Coastguard Worker OptionalMatrix localMatrix(mPtr);
2307*c8dee2aaSAndroid Build Coastguard Worker auto s = self.makeShader(uniforms, children, cLen, mPtr ? &localMatrix : nullptr);
2308*c8dee2aaSAndroid Build Coastguard Worker delete[] children;
2309*c8dee2aaSAndroid Build Coastguard Worker return s;
2310*c8dee2aaSAndroid Build Coastguard Worker }))
2311*c8dee2aaSAndroid Build Coastguard Worker .function("_makeBlender", optional_override([](SkRuntimeEffect& self,
2312*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr,
2313*c8dee2aaSAndroid Build Coastguard Worker size_t fLen,
2314*c8dee2aaSAndroid Build Coastguard Worker bool shouldOwnUniforms)->sk_sp<SkBlender> {
2315*c8dee2aaSAndroid Build Coastguard Worker void* uniformData = reinterpret_cast<void*>(fPtr);
2316*c8dee2aaSAndroid Build Coastguard Worker castUniforms(uniformData, fLen, self);
2317*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> uniforms;
2318*c8dee2aaSAndroid Build Coastguard Worker if (shouldOwnUniforms) {
2319*c8dee2aaSAndroid Build Coastguard Worker uniforms = SkData::MakeFromMalloc(uniformData, fLen);
2320*c8dee2aaSAndroid Build Coastguard Worker } else {
2321*c8dee2aaSAndroid Build Coastguard Worker uniforms = SkData::MakeWithoutCopy(uniformData, fLen);
2322*c8dee2aaSAndroid Build Coastguard Worker }
2323*c8dee2aaSAndroid Build Coastguard Worker
2324*c8dee2aaSAndroid Build Coastguard Worker return self.makeBlender(uniforms, {});
2325*c8dee2aaSAndroid Build Coastguard Worker }))
2326*c8dee2aaSAndroid Build Coastguard Worker .function("getUniformCount", optional_override([](SkRuntimeEffect& self)->int {
2327*c8dee2aaSAndroid Build Coastguard Worker return self.uniforms().size();
2328*c8dee2aaSAndroid Build Coastguard Worker }))
2329*c8dee2aaSAndroid Build Coastguard Worker .function("getUniformFloatCount", optional_override([](SkRuntimeEffect& self)->int {
2330*c8dee2aaSAndroid Build Coastguard Worker return self.uniformSize() / sizeof(float);
2331*c8dee2aaSAndroid Build Coastguard Worker }))
2332*c8dee2aaSAndroid Build Coastguard Worker .function("getUniformName", optional_override([](SkRuntimeEffect& self, int i)->JSString {
2333*c8dee2aaSAndroid Build Coastguard Worker auto it = self.uniforms().begin() + i;
2334*c8dee2aaSAndroid Build Coastguard Worker return emscripten::val(std::string(it->name).c_str());
2335*c8dee2aaSAndroid Build Coastguard Worker }))
2336*c8dee2aaSAndroid Build Coastguard Worker .function("getUniform", optional_override([](SkRuntimeEffect& self, int i)->RuntimeEffectUniform {
2337*c8dee2aaSAndroid Build Coastguard Worker auto it = self.uniforms().begin() + i;
2338*c8dee2aaSAndroid Build Coastguard Worker RuntimeEffectUniform su = fromUniform(*it);
2339*c8dee2aaSAndroid Build Coastguard Worker return su;
2340*c8dee2aaSAndroid Build Coastguard Worker }));
2341*c8dee2aaSAndroid Build Coastguard Worker
2342*c8dee2aaSAndroid Build Coastguard Worker value_object<RuntimeEffectUniform>("RuntimeEffectUniform")
2343*c8dee2aaSAndroid Build Coastguard Worker .field("columns", &RuntimeEffectUniform::columns)
2344*c8dee2aaSAndroid Build Coastguard Worker .field("rows", &RuntimeEffectUniform::rows)
2345*c8dee2aaSAndroid Build Coastguard Worker .field("slot", &RuntimeEffectUniform::slot)
2346*c8dee2aaSAndroid Build Coastguard Worker .field("isInteger", &RuntimeEffectUniform::isInteger);
2347*c8dee2aaSAndroid Build Coastguard Worker
2348*c8dee2aaSAndroid Build Coastguard Worker constant("rt_effect", true);
2349*c8dee2aaSAndroid Build Coastguard Worker #endif
2350*c8dee2aaSAndroid Build Coastguard Worker
2351*c8dee2aaSAndroid Build Coastguard Worker class_<SkSurface>("Surface")
2352*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkSurface>>("sk_sp<Surface>")
2353*c8dee2aaSAndroid Build Coastguard Worker .class_function("_makeRasterDirect", optional_override([](const SimpleImageInfo ii,
2354*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU8 pPtr,
2355*c8dee2aaSAndroid Build Coastguard Worker size_t rowBytes)->sk_sp<SkSurface> {
2356*c8dee2aaSAndroid Build Coastguard Worker uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
2357*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo imageInfo = toSkImageInfo(ii);
2358*c8dee2aaSAndroid Build Coastguard Worker return SkSurfaces::WrapPixels(imageInfo, pixels, rowBytes, nullptr);
2359*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2360*c8dee2aaSAndroid Build Coastguard Worker .function("_flush", optional_override([](SkSurface& self) {
2361*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
2362*c8dee2aaSAndroid Build Coastguard Worker skgpu::ganesh::FlushAndSubmit(&self);
2363*c8dee2aaSAndroid Build Coastguard Worker #endif
2364*c8dee2aaSAndroid Build Coastguard Worker }))
2365*c8dee2aaSAndroid Build Coastguard Worker .function("_getCanvas", &SkSurface::getCanvas, allow_raw_pointers())
2366*c8dee2aaSAndroid Build Coastguard Worker .function("imageInfo", optional_override([](SkSurface& self)->SimpleImageInfo {
2367*c8dee2aaSAndroid Build Coastguard Worker const auto& ii = self.imageInfo();
2368*c8dee2aaSAndroid Build Coastguard Worker return {ii.width(), ii.height(), ii.colorType(), ii.alphaType(), ii.refColorSpace()};
2369*c8dee2aaSAndroid Build Coastguard Worker }))
2370*c8dee2aaSAndroid Build Coastguard Worker .function("height", &SkSurface::height)
2371*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGL
2372*c8dee2aaSAndroid Build Coastguard Worker .function("_makeImageFromTexture", optional_override([](SkSurface& self,
2373*c8dee2aaSAndroid Build Coastguard Worker uint32_t webglHandle, uint32_t texHandle,
2374*c8dee2aaSAndroid Build Coastguard Worker SimpleImageInfo ii)->sk_sp<SkImage> {
2375*c8dee2aaSAndroid Build Coastguard Worker auto releaseCtx = new TextureReleaseContext{webglHandle, texHandle};
2376*c8dee2aaSAndroid Build Coastguard Worker GrGLTextureInfo gti = {GR_GL_TEXTURE_2D, texHandle,
2377*c8dee2aaSAndroid Build Coastguard Worker GR_GL_RGBA8}; // TODO(kjlubick) look at ii for this
2378*c8dee2aaSAndroid Build Coastguard Worker auto gbt = GrBackendTextures::MakeGL(ii.width, ii.height, skgpu::Mipmapped::kNo, gti);
2379*c8dee2aaSAndroid Build Coastguard Worker auto dContext = GrAsDirectContext(self.getCanvas()->recordingContext());
2380*c8dee2aaSAndroid Build Coastguard Worker
2381*c8dee2aaSAndroid Build Coastguard Worker return SkImages::BorrowTextureFrom(dContext,
2382*c8dee2aaSAndroid Build Coastguard Worker gbt,
2383*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
2384*c8dee2aaSAndroid Build Coastguard Worker ii.colorType,
2385*c8dee2aaSAndroid Build Coastguard Worker ii.alphaType,
2386*c8dee2aaSAndroid Build Coastguard Worker ii.colorSpace,
2387*c8dee2aaSAndroid Build Coastguard Worker deleteJSTexture,
2388*c8dee2aaSAndroid Build Coastguard Worker releaseCtx);
2389*c8dee2aaSAndroid Build Coastguard Worker }))
2390*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGL
2391*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_ENABLE_WEBGPU
2392*c8dee2aaSAndroid Build Coastguard Worker .function("_replaceBackendTexture", optional_override([](SkSurface& self,
2393*c8dee2aaSAndroid Build Coastguard Worker uint32_t texHandle, uint32_t texFormat,
2394*c8dee2aaSAndroid Build Coastguard Worker int width, int height) {
2395*c8dee2aaSAndroid Build Coastguard Worker return ReplaceBackendTexture(self, texHandle, texFormat, width, height);
2396*c8dee2aaSAndroid Build Coastguard Worker }))
2397*c8dee2aaSAndroid Build Coastguard Worker #endif // CK_ENABLE_WEBGPU
2398*c8dee2aaSAndroid Build Coastguard Worker .function("_makeImageSnapshot", optional_override([](SkSurface& self, WASMPointerU32 iPtr)->sk_sp<SkImage> {
2399*c8dee2aaSAndroid Build Coastguard Worker SkIRect* bounds = reinterpret_cast<SkIRect*>(iPtr);
2400*c8dee2aaSAndroid Build Coastguard Worker if (!bounds) {
2401*c8dee2aaSAndroid Build Coastguard Worker return self.makeImageSnapshot();
2402*c8dee2aaSAndroid Build Coastguard Worker }
2403*c8dee2aaSAndroid Build Coastguard Worker return self.makeImageSnapshot(*bounds);
2404*c8dee2aaSAndroid Build Coastguard Worker }))
2405*c8dee2aaSAndroid Build Coastguard Worker .function("_makeSurface", optional_override([](SkSurface& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
2406*c8dee2aaSAndroid Build Coastguard Worker return self.makeSurface(toSkImageInfo(sii));
2407*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2408*c8dee2aaSAndroid Build Coastguard Worker #ifdef ENABLE_GPU
2409*c8dee2aaSAndroid Build Coastguard Worker .function("reportBackendTypeIsGPU", optional_override([](SkSurface& self) -> bool {
2410*c8dee2aaSAndroid Build Coastguard Worker return self.getCanvas()->recordingContext() != nullptr;
2411*c8dee2aaSAndroid Build Coastguard Worker }))
2412*c8dee2aaSAndroid Build Coastguard Worker .function("sampleCnt", optional_override([](SkSurface& self)->int {
2413*c8dee2aaSAndroid Build Coastguard Worker auto backendRT = SkSurfaces::GetBackendRenderTarget(
2414*c8dee2aaSAndroid Build Coastguard Worker &self, SkSurfaces::BackendHandleAccess::kFlushRead);
2415*c8dee2aaSAndroid Build Coastguard Worker return (backendRT.isValid()) ? backendRT.sampleCnt() : 0;
2416*c8dee2aaSAndroid Build Coastguard Worker }))
2417*c8dee2aaSAndroid Build Coastguard Worker .function("_resetContext",optional_override([](SkSurface& self)->void {
2418*c8dee2aaSAndroid Build Coastguard Worker GrAsDirectContext(self.recordingContext())->resetContext(kTextureBinding_GrGLBackendState);
2419*c8dee2aaSAndroid Build Coastguard Worker }))
2420*c8dee2aaSAndroid Build Coastguard Worker #else
2421*c8dee2aaSAndroid Build Coastguard Worker .function("reportBackendTypeIsGPU", optional_override([](SkSurface& self) -> bool {
2422*c8dee2aaSAndroid Build Coastguard Worker return false;
2423*c8dee2aaSAndroid Build Coastguard Worker }))
2424*c8dee2aaSAndroid Build Coastguard Worker #endif
2425*c8dee2aaSAndroid Build Coastguard Worker .function("width", &SkSurface::width);
2426*c8dee2aaSAndroid Build Coastguard Worker
2427*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
2428*c8dee2aaSAndroid Build Coastguard Worker class_<SkTextBlob>("TextBlob")
2429*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkTextBlob>>("sk_sp<TextBlob>")
2430*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeFromRSXform", optional_override([](WASMPointerU8 sptr,
2431*c8dee2aaSAndroid Build Coastguard Worker size_t strBtyes,
2432*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 xptr,
2433*c8dee2aaSAndroid Build Coastguard Worker const SkFont& font)->sk_sp<SkTextBlob> {
2434*c8dee2aaSAndroid Build Coastguard Worker const char* str = reinterpret_cast<const char*>(sptr);
2435*c8dee2aaSAndroid Build Coastguard Worker const SkRSXform* xforms = reinterpret_cast<const SkRSXform*>(xptr);
2436*c8dee2aaSAndroid Build Coastguard Worker
2437*c8dee2aaSAndroid Build Coastguard Worker return SkTextBlob::MakeFromRSXform(str, strBtyes, xforms, font, SkTextEncoding::kUTF8);
2438*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2439*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeFromRSXformGlyphs", optional_override([](WASMPointerU16 gPtr,
2440*c8dee2aaSAndroid Build Coastguard Worker size_t byteLen,
2441*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 xptr,
2442*c8dee2aaSAndroid Build Coastguard Worker const SkFont& font)->sk_sp<SkTextBlob> {
2443*c8dee2aaSAndroid Build Coastguard Worker const SkGlyphID* glyphs = reinterpret_cast<const SkGlyphID*>(gPtr);
2444*c8dee2aaSAndroid Build Coastguard Worker const SkRSXform* xforms = reinterpret_cast<const SkRSXform*>(xptr);
2445*c8dee2aaSAndroid Build Coastguard Worker
2446*c8dee2aaSAndroid Build Coastguard Worker return SkTextBlob::MakeFromRSXform(glyphs, byteLen, xforms, font, SkTextEncoding::kGlyphID);
2447*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2448*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeFromText", optional_override([](WASMPointerU8 sptr,
2449*c8dee2aaSAndroid Build Coastguard Worker size_t len, const SkFont& font)->sk_sp<SkTextBlob> {
2450*c8dee2aaSAndroid Build Coastguard Worker const char* str = reinterpret_cast<const char*>(sptr);
2451*c8dee2aaSAndroid Build Coastguard Worker return SkTextBlob::MakeFromText(str, len, font, SkTextEncoding::kUTF8);
2452*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2453*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeFromGlyphs", optional_override([](WASMPointerU16 gPtr,
2454*c8dee2aaSAndroid Build Coastguard Worker size_t byteLen, const SkFont& font)->sk_sp<SkTextBlob> {
2455*c8dee2aaSAndroid Build Coastguard Worker const SkGlyphID* glyphs = reinterpret_cast<const SkGlyphID*>(gPtr);
2456*c8dee2aaSAndroid Build Coastguard Worker return SkTextBlob::MakeFromText(glyphs, byteLen, font, SkTextEncoding::kGlyphID);
2457*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers());
2458*c8dee2aaSAndroid Build Coastguard Worker
2459*c8dee2aaSAndroid Build Coastguard Worker class_<SkTypeface>("Typeface")
2460*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkTypeface>>("sk_sp<Typeface>")
2461*c8dee2aaSAndroid Build Coastguard Worker .class_function("GetDefault", optional_override([]()->sk_sp<SkTypeface> {
2462*c8dee2aaSAndroid Build Coastguard Worker #if defined(CK_EMBED_FONT)
2463*c8dee2aaSAndroid Build Coastguard Worker if (SK_EMBEDDED_FONTS.count == 0) {
2464*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2465*c8dee2aaSAndroid Build Coastguard Worker }
2466*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkTypeface> default_face;
2467*c8dee2aaSAndroid Build Coastguard Worker static SkOnce once;
2468*c8dee2aaSAndroid Build Coastguard Worker once([] {
2469*c8dee2aaSAndroid Build Coastguard Worker const SkEmbeddedResource& fontEntry = SK_EMBEDDED_FONTS.entries[0];
2470*c8dee2aaSAndroid Build Coastguard Worker auto stream = std::make_unique<SkMemoryStream>(fontEntry.data, fontEntry.size, false);
2471*c8dee2aaSAndroid Build Coastguard Worker default_face = SkTypeface_FreeType::MakeFromStream(std::move(stream), SkFontArguments());
2472*c8dee2aaSAndroid Build Coastguard Worker });
2473*c8dee2aaSAndroid Build Coastguard Worker return default_face;
2474*c8dee2aaSAndroid Build Coastguard Worker #else
2475*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
2476*c8dee2aaSAndroid Build Coastguard Worker #endif
2477*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2478*c8dee2aaSAndroid Build Coastguard Worker .class_function("_MakeTypefaceFromData", optional_override([](
2479*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU8 fPtr, int flen)->sk_sp<SkTypeface> {
2480*c8dee2aaSAndroid Build Coastguard Worker uint8_t* font = reinterpret_cast<uint8_t*>(fPtr);
2481*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkMemoryStream> stream(new SkMemoryStream());
2482*c8dee2aaSAndroid Build Coastguard Worker stream->setMemoryOwned(font, flen);
2483*c8dee2aaSAndroid Build Coastguard Worker return SkTypeface_FreeType::MakeFromStream(std::move(stream), SkFontArguments());
2484*c8dee2aaSAndroid Build Coastguard Worker }), allow_raw_pointers())
2485*c8dee2aaSAndroid Build Coastguard Worker .function("_getGlyphIDs", optional_override([](SkTypeface& self, WASMPointerU8 sptr,
2486*c8dee2aaSAndroid Build Coastguard Worker size_t strLen, size_t expectedCodePoints,
2487*c8dee2aaSAndroid Build Coastguard Worker WASMPointerU16 iPtr) -> int {
2488*c8dee2aaSAndroid Build Coastguard Worker char* str = reinterpret_cast<char*>(sptr);
2489*c8dee2aaSAndroid Build Coastguard Worker SkGlyphID* glyphIDs = reinterpret_cast<SkGlyphID*>(iPtr);
2490*c8dee2aaSAndroid Build Coastguard Worker
2491*c8dee2aaSAndroid Build Coastguard Worker int actualCodePoints = self.textToGlyphs(str, strLen, SkTextEncoding::kUTF8,
2492*c8dee2aaSAndroid Build Coastguard Worker glyphIDs, expectedCodePoints);
2493*c8dee2aaSAndroid Build Coastguard Worker return actualCodePoints;
2494*c8dee2aaSAndroid Build Coastguard Worker }));
2495*c8dee2aaSAndroid Build Coastguard Worker #endif
2496*c8dee2aaSAndroid Build Coastguard Worker
2497*c8dee2aaSAndroid Build Coastguard Worker class_<SkVertices>("Vertices")
2498*c8dee2aaSAndroid Build Coastguard Worker .smart_ptr<sk_sp<SkVertices>>("sk_sp<Vertices>")
2499*c8dee2aaSAndroid Build Coastguard Worker .function("_bounds", optional_override([](SkVertices& self,
2500*c8dee2aaSAndroid Build Coastguard Worker WASMPointerF32 fPtr)->void {
2501*c8dee2aaSAndroid Build Coastguard Worker SkRect* output = reinterpret_cast<SkRect*>(fPtr);
2502*c8dee2aaSAndroid Build Coastguard Worker output[0] = self.bounds();
2503*c8dee2aaSAndroid Build Coastguard Worker }))
2504*c8dee2aaSAndroid Build Coastguard Worker .function("uniqueID", &SkVertices::uniqueID);
2505*c8dee2aaSAndroid Build Coastguard Worker
2506*c8dee2aaSAndroid Build Coastguard Worker // Not intended to be called directly by clients
2507*c8dee2aaSAndroid Build Coastguard Worker class_<SkVertices::Builder>("_VerticesBuilder")
2508*c8dee2aaSAndroid Build Coastguard Worker .constructor<SkVertices::VertexMode, int, int, uint32_t>()
2509*c8dee2aaSAndroid Build Coastguard Worker .function("colors", optional_override([](SkVertices::Builder& self)->WASMPointerF32{
2510*c8dee2aaSAndroid Build Coastguard Worker // Emscripten won't let us return bare pointers, but we can return ints just fine.
2511*c8dee2aaSAndroid Build Coastguard Worker return reinterpret_cast<WASMPointerF32>(self.colors());
2512*c8dee2aaSAndroid Build Coastguard Worker }))
2513*c8dee2aaSAndroid Build Coastguard Worker .function("detach", &SkVertices::Builder::detach)
2514*c8dee2aaSAndroid Build Coastguard Worker .function("indices", optional_override([](SkVertices::Builder& self)->WASMPointerU16{
2515*c8dee2aaSAndroid Build Coastguard Worker // Emscripten won't let us return bare pointers, but we can return ints just fine.
2516*c8dee2aaSAndroid Build Coastguard Worker return reinterpret_cast<WASMPointerU16>(self.indices());
2517*c8dee2aaSAndroid Build Coastguard Worker }))
2518*c8dee2aaSAndroid Build Coastguard Worker .function("positions", optional_override([](SkVertices::Builder& self)->WASMPointerF32{
2519*c8dee2aaSAndroid Build Coastguard Worker // Emscripten won't let us return bare pointers, but we can return ints just fine.
2520*c8dee2aaSAndroid Build Coastguard Worker return reinterpret_cast<WASMPointerF32>(self.positions());
2521*c8dee2aaSAndroid Build Coastguard Worker }))
2522*c8dee2aaSAndroid Build Coastguard Worker .function("texCoords", optional_override([](SkVertices::Builder& self)->WASMPointerF32{
2523*c8dee2aaSAndroid Build Coastguard Worker // Emscripten won't let us return bare pointers, but we can return ints just fine.
2524*c8dee2aaSAndroid Build Coastguard Worker return reinterpret_cast<WASMPointerF32>(self.texCoords());
2525*c8dee2aaSAndroid Build Coastguard Worker }));
2526*c8dee2aaSAndroid Build Coastguard Worker
2527*c8dee2aaSAndroid Build Coastguard Worker enum_<SkAlphaType>("AlphaType")
2528*c8dee2aaSAndroid Build Coastguard Worker .value("Opaque", SkAlphaType::kOpaque_SkAlphaType)
2529*c8dee2aaSAndroid Build Coastguard Worker .value("Premul", SkAlphaType::kPremul_SkAlphaType)
2530*c8dee2aaSAndroid Build Coastguard Worker .value("Unpremul", SkAlphaType::kUnpremul_SkAlphaType);
2531*c8dee2aaSAndroid Build Coastguard Worker
2532*c8dee2aaSAndroid Build Coastguard Worker enum_<SkBlendMode>("BlendMode")
2533*c8dee2aaSAndroid Build Coastguard Worker .value("Clear", SkBlendMode::kClear)
2534*c8dee2aaSAndroid Build Coastguard Worker .value("Src", SkBlendMode::kSrc)
2535*c8dee2aaSAndroid Build Coastguard Worker .value("Dst", SkBlendMode::kDst)
2536*c8dee2aaSAndroid Build Coastguard Worker .value("SrcOver", SkBlendMode::kSrcOver)
2537*c8dee2aaSAndroid Build Coastguard Worker .value("DstOver", SkBlendMode::kDstOver)
2538*c8dee2aaSAndroid Build Coastguard Worker .value("SrcIn", SkBlendMode::kSrcIn)
2539*c8dee2aaSAndroid Build Coastguard Worker .value("DstIn", SkBlendMode::kDstIn)
2540*c8dee2aaSAndroid Build Coastguard Worker .value("SrcOut", SkBlendMode::kSrcOut)
2541*c8dee2aaSAndroid Build Coastguard Worker .value("DstOut", SkBlendMode::kDstOut)
2542*c8dee2aaSAndroid Build Coastguard Worker .value("SrcATop", SkBlendMode::kSrcATop)
2543*c8dee2aaSAndroid Build Coastguard Worker .value("DstATop", SkBlendMode::kDstATop)
2544*c8dee2aaSAndroid Build Coastguard Worker .value("Xor", SkBlendMode::kXor)
2545*c8dee2aaSAndroid Build Coastguard Worker .value("Plus", SkBlendMode::kPlus)
2546*c8dee2aaSAndroid Build Coastguard Worker .value("Modulate", SkBlendMode::kModulate)
2547*c8dee2aaSAndroid Build Coastguard Worker .value("Screen", SkBlendMode::kScreen)
2548*c8dee2aaSAndroid Build Coastguard Worker .value("Overlay", SkBlendMode::kOverlay)
2549*c8dee2aaSAndroid Build Coastguard Worker .value("Darken", SkBlendMode::kDarken)
2550*c8dee2aaSAndroid Build Coastguard Worker .value("Lighten", SkBlendMode::kLighten)
2551*c8dee2aaSAndroid Build Coastguard Worker .value("ColorDodge", SkBlendMode::kColorDodge)
2552*c8dee2aaSAndroid Build Coastguard Worker .value("ColorBurn", SkBlendMode::kColorBurn)
2553*c8dee2aaSAndroid Build Coastguard Worker .value("HardLight", SkBlendMode::kHardLight)
2554*c8dee2aaSAndroid Build Coastguard Worker .value("SoftLight", SkBlendMode::kSoftLight)
2555*c8dee2aaSAndroid Build Coastguard Worker .value("Difference", SkBlendMode::kDifference)
2556*c8dee2aaSAndroid Build Coastguard Worker .value("Exclusion", SkBlendMode::kExclusion)
2557*c8dee2aaSAndroid Build Coastguard Worker .value("Multiply", SkBlendMode::kMultiply)
2558*c8dee2aaSAndroid Build Coastguard Worker .value("Hue", SkBlendMode::kHue)
2559*c8dee2aaSAndroid Build Coastguard Worker .value("Saturation", SkBlendMode::kSaturation)
2560*c8dee2aaSAndroid Build Coastguard Worker .value("Color", SkBlendMode::kColor)
2561*c8dee2aaSAndroid Build Coastguard Worker .value("Luminosity", SkBlendMode::kLuminosity);
2562*c8dee2aaSAndroid Build Coastguard Worker
2563*c8dee2aaSAndroid Build Coastguard Worker enum_<SkBlurStyle>("BlurStyle")
2564*c8dee2aaSAndroid Build Coastguard Worker .value("Normal", SkBlurStyle::kNormal_SkBlurStyle)
2565*c8dee2aaSAndroid Build Coastguard Worker .value("Solid", SkBlurStyle::kSolid_SkBlurStyle)
2566*c8dee2aaSAndroid Build Coastguard Worker .value("Outer", SkBlurStyle::kOuter_SkBlurStyle)
2567*c8dee2aaSAndroid Build Coastguard Worker .value("Inner", SkBlurStyle::kInner_SkBlurStyle);
2568*c8dee2aaSAndroid Build Coastguard Worker
2569*c8dee2aaSAndroid Build Coastguard Worker enum_<SkClipOp>("ClipOp")
2570*c8dee2aaSAndroid Build Coastguard Worker .value("Difference", SkClipOp::kDifference)
2571*c8dee2aaSAndroid Build Coastguard Worker .value("Intersect", SkClipOp::kIntersect);
2572*c8dee2aaSAndroid Build Coastguard Worker
2573*c8dee2aaSAndroid Build Coastguard Worker enum_<SkColorChannel>("ColorChannel")
2574*c8dee2aaSAndroid Build Coastguard Worker .value("Red", SkColorChannel::kR)
2575*c8dee2aaSAndroid Build Coastguard Worker .value("Green", SkColorChannel::kG)
2576*c8dee2aaSAndroid Build Coastguard Worker .value("Blue", SkColorChannel::kB)
2577*c8dee2aaSAndroid Build Coastguard Worker .value("Alpha", SkColorChannel::kA);
2578*c8dee2aaSAndroid Build Coastguard Worker
2579*c8dee2aaSAndroid Build Coastguard Worker enum_<SkColorType>("ColorType")
2580*c8dee2aaSAndroid Build Coastguard Worker .value("Alpha_8", SkColorType::kAlpha_8_SkColorType)
2581*c8dee2aaSAndroid Build Coastguard Worker .value("RGB_565", SkColorType::kRGB_565_SkColorType)
2582*c8dee2aaSAndroid Build Coastguard Worker .value("RGBA_8888", SkColorType::kRGBA_8888_SkColorType)
2583*c8dee2aaSAndroid Build Coastguard Worker .value("BGRA_8888", SkColorType::kBGRA_8888_SkColorType)
2584*c8dee2aaSAndroid Build Coastguard Worker .value("RGBA_1010102", SkColorType::kRGBA_1010102_SkColorType)
2585*c8dee2aaSAndroid Build Coastguard Worker .value("RGB_101010x", SkColorType::kRGB_101010x_SkColorType)
2586*c8dee2aaSAndroid Build Coastguard Worker .value("Gray_8", SkColorType::kGray_8_SkColorType)
2587*c8dee2aaSAndroid Build Coastguard Worker .value("RGBA_F16", SkColorType::kRGBA_F16_SkColorType)
2588*c8dee2aaSAndroid Build Coastguard Worker .value("RGB_F16F16F16x", SkColorType::kRGB_F16F16F16x_SkColorType)
2589*c8dee2aaSAndroid Build Coastguard Worker .value("RGBA_F32", SkColorType::kRGBA_F32_SkColorType);
2590*c8dee2aaSAndroid Build Coastguard Worker
2591*c8dee2aaSAndroid Build Coastguard Worker enum_<SkPathFillType>("FillType")
2592*c8dee2aaSAndroid Build Coastguard Worker .value("Winding", SkPathFillType::kWinding)
2593*c8dee2aaSAndroid Build Coastguard Worker .value("EvenOdd", SkPathFillType::kEvenOdd);
2594*c8dee2aaSAndroid Build Coastguard Worker
2595*c8dee2aaSAndroid Build Coastguard Worker enum_<SkFilterMode>("FilterMode")
2596*c8dee2aaSAndroid Build Coastguard Worker .value("Nearest", SkFilterMode::kNearest)
2597*c8dee2aaSAndroid Build Coastguard Worker .value("Linear", SkFilterMode::kLinear);
2598*c8dee2aaSAndroid Build Coastguard Worker
2599*c8dee2aaSAndroid Build Coastguard Worker // Only used to control the encode function.
2600*c8dee2aaSAndroid Build Coastguard Worker // TODO(kjlubick): compile these out when the appropriate encoder is disabled.
2601*c8dee2aaSAndroid Build Coastguard Worker enum_<SkEncodedImageFormat>("ImageFormat")
2602*c8dee2aaSAndroid Build Coastguard Worker .value("PNG", SkEncodedImageFormat::kPNG)
2603*c8dee2aaSAndroid Build Coastguard Worker .value("JPEG", SkEncodedImageFormat::kJPEG)
2604*c8dee2aaSAndroid Build Coastguard Worker .value("WEBP", SkEncodedImageFormat::kWEBP);
2605*c8dee2aaSAndroid Build Coastguard Worker
2606*c8dee2aaSAndroid Build Coastguard Worker enum_<SkMipmapMode>("MipmapMode")
2607*c8dee2aaSAndroid Build Coastguard Worker .value("None", SkMipmapMode::kNone)
2608*c8dee2aaSAndroid Build Coastguard Worker .value("Nearest", SkMipmapMode::kNearest)
2609*c8dee2aaSAndroid Build Coastguard Worker .value("Linear", SkMipmapMode::kLinear);
2610*c8dee2aaSAndroid Build Coastguard Worker
2611*c8dee2aaSAndroid Build Coastguard Worker enum_<SkPaint::Style>("PaintStyle")
2612*c8dee2aaSAndroid Build Coastguard Worker .value("Fill", SkPaint::Style::kFill_Style)
2613*c8dee2aaSAndroid Build Coastguard Worker .value("Stroke", SkPaint::Style::kStroke_Style);
2614*c8dee2aaSAndroid Build Coastguard Worker
2615*c8dee2aaSAndroid Build Coastguard Worker enum_<SkPath1DPathEffect::Style>("Path1DEffect")
2616*c8dee2aaSAndroid Build Coastguard Worker .value("Translate", SkPath1DPathEffect::Style::kTranslate_Style)
2617*c8dee2aaSAndroid Build Coastguard Worker .value("Rotate", SkPath1DPathEffect::Style::kRotate_Style)
2618*c8dee2aaSAndroid Build Coastguard Worker .value("Morph", SkPath1DPathEffect::Style::kMorph_Style);
2619*c8dee2aaSAndroid Build Coastguard Worker
2620*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PATHOPS
2621*c8dee2aaSAndroid Build Coastguard Worker enum_<SkPathOp>("PathOp")
2622*c8dee2aaSAndroid Build Coastguard Worker .value("Difference", SkPathOp::kDifference_SkPathOp)
2623*c8dee2aaSAndroid Build Coastguard Worker .value("Intersect", SkPathOp::kIntersect_SkPathOp)
2624*c8dee2aaSAndroid Build Coastguard Worker .value("Union", SkPathOp::kUnion_SkPathOp)
2625*c8dee2aaSAndroid Build Coastguard Worker .value("XOR", SkPathOp::kXOR_SkPathOp)
2626*c8dee2aaSAndroid Build Coastguard Worker .value("ReverseDifference", SkPathOp::kReverseDifference_SkPathOp);
2627*c8dee2aaSAndroid Build Coastguard Worker #endif
2628*c8dee2aaSAndroid Build Coastguard Worker
2629*c8dee2aaSAndroid Build Coastguard Worker enum_<SkCanvas::PointMode>("PointMode")
2630*c8dee2aaSAndroid Build Coastguard Worker .value("Points", SkCanvas::PointMode::kPoints_PointMode)
2631*c8dee2aaSAndroid Build Coastguard Worker .value("Lines", SkCanvas::PointMode::kLines_PointMode)
2632*c8dee2aaSAndroid Build Coastguard Worker .value("Polygon", SkCanvas::PointMode::kPolygon_PointMode);
2633*c8dee2aaSAndroid Build Coastguard Worker
2634*c8dee2aaSAndroid Build Coastguard Worker enum_<SkPaint::Cap>("StrokeCap")
2635*c8dee2aaSAndroid Build Coastguard Worker .value("Butt", SkPaint::Cap::kButt_Cap)
2636*c8dee2aaSAndroid Build Coastguard Worker .value("Round", SkPaint::Cap::kRound_Cap)
2637*c8dee2aaSAndroid Build Coastguard Worker .value("Square", SkPaint::Cap::kSquare_Cap);
2638*c8dee2aaSAndroid Build Coastguard Worker
2639*c8dee2aaSAndroid Build Coastguard Worker enum_<SkPaint::Join>("StrokeJoin")
2640*c8dee2aaSAndroid Build Coastguard Worker .value("Miter", SkPaint::Join::kMiter_Join)
2641*c8dee2aaSAndroid Build Coastguard Worker .value("Round", SkPaint::Join::kRound_Join)
2642*c8dee2aaSAndroid Build Coastguard Worker .value("Bevel", SkPaint::Join::kBevel_Join);
2643*c8dee2aaSAndroid Build Coastguard Worker
2644*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_FONTS
2645*c8dee2aaSAndroid Build Coastguard Worker enum_<SkFontHinting>("FontHinting")
2646*c8dee2aaSAndroid Build Coastguard Worker .value("None", SkFontHinting::kNone)
2647*c8dee2aaSAndroid Build Coastguard Worker .value("Slight", SkFontHinting::kSlight)
2648*c8dee2aaSAndroid Build Coastguard Worker .value("Normal", SkFontHinting::kNormal)
2649*c8dee2aaSAndroid Build Coastguard Worker .value("Full", SkFontHinting::kFull);
2650*c8dee2aaSAndroid Build Coastguard Worker
2651*c8dee2aaSAndroid Build Coastguard Worker enum_<SkFont::Edging>("FontEdging")
2652*c8dee2aaSAndroid Build Coastguard Worker #ifndef CK_NO_ALIAS_FONT
2653*c8dee2aaSAndroid Build Coastguard Worker .value("Alias", SkFont::Edging::kAlias)
2654*c8dee2aaSAndroid Build Coastguard Worker #endif
2655*c8dee2aaSAndroid Build Coastguard Worker .value("AntiAlias", SkFont::Edging::kAntiAlias)
2656*c8dee2aaSAndroid Build Coastguard Worker .value("SubpixelAntiAlias", SkFont::Edging::kSubpixelAntiAlias);
2657*c8dee2aaSAndroid Build Coastguard Worker #endif
2658*c8dee2aaSAndroid Build Coastguard Worker
2659*c8dee2aaSAndroid Build Coastguard Worker enum_<SkTileMode>("TileMode")
2660*c8dee2aaSAndroid Build Coastguard Worker .value("Clamp", SkTileMode::kClamp)
2661*c8dee2aaSAndroid Build Coastguard Worker .value("Repeat", SkTileMode::kRepeat)
2662*c8dee2aaSAndroid Build Coastguard Worker .value("Mirror", SkTileMode::kMirror)
2663*c8dee2aaSAndroid Build Coastguard Worker .value("Decal", SkTileMode::kDecal);
2664*c8dee2aaSAndroid Build Coastguard Worker
2665*c8dee2aaSAndroid Build Coastguard Worker enum_<SkVertices::VertexMode>("VertexMode")
2666*c8dee2aaSAndroid Build Coastguard Worker .value("Triangles", SkVertices::VertexMode::kTriangles_VertexMode)
2667*c8dee2aaSAndroid Build Coastguard Worker .value("TrianglesStrip", SkVertices::VertexMode::kTriangleStrip_VertexMode)
2668*c8dee2aaSAndroid Build Coastguard Worker .value("TriangleFan", SkVertices::VertexMode::kTriangleFan_VertexMode);
2669*c8dee2aaSAndroid Build Coastguard Worker
2670*c8dee2aaSAndroid Build Coastguard Worker // A value object is much simpler than a class - it is returned as a JS
2671*c8dee2aaSAndroid Build Coastguard Worker // object and does not require delete().
2672*c8dee2aaSAndroid Build Coastguard Worker // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#value-types
2673*c8dee2aaSAndroid Build Coastguard Worker
2674*c8dee2aaSAndroid Build Coastguard Worker value_object<SimpleImageInfo>("ImageInfo")
2675*c8dee2aaSAndroid Build Coastguard Worker .field("width", &SimpleImageInfo::width)
2676*c8dee2aaSAndroid Build Coastguard Worker .field("height", &SimpleImageInfo::height)
2677*c8dee2aaSAndroid Build Coastguard Worker .field("colorType", &SimpleImageInfo::colorType)
2678*c8dee2aaSAndroid Build Coastguard Worker .field("alphaType", &SimpleImageInfo::alphaType)
2679*c8dee2aaSAndroid Build Coastguard Worker .field("colorSpace", &SimpleImageInfo::colorSpace);
2680*c8dee2aaSAndroid Build Coastguard Worker
2681*c8dee2aaSAndroid Build Coastguard Worker value_object<StrokeOpts>("StrokeOpts")
2682*c8dee2aaSAndroid Build Coastguard Worker .field("width", &StrokeOpts::width)
2683*c8dee2aaSAndroid Build Coastguard Worker .field("miter_limit", &StrokeOpts::miter_limit)
2684*c8dee2aaSAndroid Build Coastguard Worker .field("join", &StrokeOpts::join)
2685*c8dee2aaSAndroid Build Coastguard Worker .field("cap", &StrokeOpts::cap)
2686*c8dee2aaSAndroid Build Coastguard Worker .field("precision", &StrokeOpts::precision);
2687*c8dee2aaSAndroid Build Coastguard Worker
2688*c8dee2aaSAndroid Build Coastguard Worker constant("MOVE_VERB", MOVE);
2689*c8dee2aaSAndroid Build Coastguard Worker constant("LINE_VERB", LINE);
2690*c8dee2aaSAndroid Build Coastguard Worker constant("QUAD_VERB", QUAD);
2691*c8dee2aaSAndroid Build Coastguard Worker constant("CONIC_VERB", CONIC);
2692*c8dee2aaSAndroid Build Coastguard Worker constant("CUBIC_VERB", CUBIC);
2693*c8dee2aaSAndroid Build Coastguard Worker constant("CLOSE_VERB", CLOSE);
2694*c8dee2aaSAndroid Build Coastguard Worker
2695*c8dee2aaSAndroid Build Coastguard Worker constant("SaveLayerInitWithPrevious", (int)SkCanvas::SaveLayerFlagsSet::kInitWithPrevious_SaveLayerFlag);
2696*c8dee2aaSAndroid Build Coastguard Worker constant("SaveLayerF16ColorType", (int)SkCanvas::SaveLayerFlagsSet::kF16ColorType);
2697*c8dee2aaSAndroid Build Coastguard Worker
2698*c8dee2aaSAndroid Build Coastguard Worker constant("ShadowTransparentOccluder", (int)SkShadowFlags::kTransparentOccluder_ShadowFlag);
2699*c8dee2aaSAndroid Build Coastguard Worker constant("ShadowGeometricOnly", (int)SkShadowFlags::kGeometricOnly_ShadowFlag);
2700*c8dee2aaSAndroid Build Coastguard Worker constant("ShadowDirectionalLight", (int)SkShadowFlags::kDirectionalLight_ShadowFlag);
2701*c8dee2aaSAndroid Build Coastguard Worker
2702*c8dee2aaSAndroid Build Coastguard Worker #ifdef CK_INCLUDE_PARAGRAPH
2703*c8dee2aaSAndroid Build Coastguard Worker constant("_GlyphRunFlags_isWhiteSpace", (int)skia::textlayout::Paragraph::kWhiteSpace_VisitorFlag);
2704*c8dee2aaSAndroid Build Coastguard Worker #endif
2705*c8dee2aaSAndroid Build Coastguard Worker }
2706