• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// This file is type-checked by the Typescript definitions. It is not actually executed.
2// Test it by running `npm run dtslint` in the parent directory.
3import {
4    CanvasKitInit,
5    AnimatedImage,
6    Canvas,
7    CanvasKit,
8    ColorFilter,
9    Font,
10    FontMgr,
11    Image,
12    ImageFilter,
13    ImageInfo,
14    MaskFilter,
15    Paint,
16    Paragraph,
17    Path,
18    PathEffect,
19    Shader,
20    SkPicture,
21    TextBlob,
22    Typeface,
23    Vertices,
24} from "canvaskit-wasm";
25
26CanvasKitInit({locateFile: (file: string) => '/node_modules/canvaskit/bin/' + file}).then((CK: CanvasKit) => {
27    animatedImageTests(CK);
28    canvasTests(CK);
29    canvas2DTests(CK);
30    colorFilterTests(CK);
31    colorTests(CK);
32    contourMeasureTests(CK);
33    imageFilterTests(CK);
34    imageTests(CK);
35    fontTests(CK);
36    fontMgrTests(CK);
37    globalTests(CK);
38    mallocTests(CK);
39    maskFilterTests(CK);
40    matrixTests(CK);
41    paintTests(CK);
42    paragraphTests(CK);
43    paragraphBuilderTests(CK);
44    particlesTests(CK);
45    pathEffectTests(CK);
46    pathTests(CK);
47    pictureTests(CK);
48    rectangleTests(CK);
49    runtimeEffectTests(CK);
50    skottieTests(CK);
51    shaderTests(CK);
52    surfaceTests(CK);
53    textBlobTests(CK);
54    typefaceTests(CK);
55    vectorTests(CK);
56    verticesTests(CK);
57});
58
59function animatedImageTests(CK: CanvasKit) {
60    const buff = new ArrayBuffer(10);
61    const img = CK.MakeAnimatedImageFromEncoded(buff); // $ExpectType AnimatedImage | null
62    if (!img) return;
63    const n = img.decodeNextFrame(); // $ExpectType number
64    const f = img.getFrameCount(); // $ExpectType number
65    const r = img.getRepetitionCount(); // $ExpectType number
66    const h = img.height(); // $ExpectType number
67    const still = img.makeImageAtCurrentFrame(); // $ExpectType Image | null
68    img.reset();
69    const w = img.width(); // $ExpectType number
70}
71
72// In an effort to keep these type-checking tests easy to read and understand, we can "inject"
73// types instead of actually having to create them from scratch. To inject them, we define them
74// as an optional parameter and then have a null check to make sure that optional-ness does not
75// cause errors.
76function canvasTests(CK: CanvasKit, canvas?: Canvas, paint?: Paint, path?: Path,
77                     img?: Image, aImg?: AnimatedImage, para?: Paragraph,
78                     skp?: SkPicture, font?: Font, textBlob?: TextBlob, verts?: Vertices,
79                     imageInfo?: ImageInfo, imgFilter?: ImageFilter) {
80    if (!canvas || !paint || !path || !img || !aImg || !para || !skp || !font ||
81        !textBlob || !verts || !imageInfo || !imgFilter) {
82        return;
83    }
84    const someColor = [0.9, 0.8, 0.7, 0.6]; // Making sure arrays are accepted as colors.
85    const someRect = [4, 3, 2, 1]; // Making sure arrays are accepted as rects.
86    // Making sure arrays are accepted as rrects.
87    const someRRect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
88    const someMatrix = CK.Malloc(Float32Array, 16); // Make sure matrixes can be malloc'd.
89
90    canvas.clear(CK.RED);
91    canvas.clipPath(path, CK.ClipOp.Intersect, false);
92    canvas.clipRect(someRect, CK.ClipOp.Intersect, true);
93    canvas.clipRRect(CK.RRectXY(someRect, 10, 20), CK.ClipOp.Difference, true);
94    canvas.concat([1, 0, 0, 0, 1, 0, 0, 0, 1]);
95    canvas.concat(someMatrix);
96    canvas.drawArc(someRect, 0, 90, true, paint);
97    canvas.drawAtlas(img, [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 6, 5, 4, 3, 2, 1], paint);
98    canvas.drawAtlas(img, [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 6, 5, 4, 3, 2, 1], paint,
99                     CK.BlendMode.Darken,
100                     [CK.ColorAsInt(100, 110, 120), CK.ColorAsInt(130, 140, 150)]);
101    canvas.drawAtlas(img, [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 6, 5, 4, 3, 2, 1], paint,
102                     null, null, {B: 0, C: 0.5});
103    canvas.drawAtlas(img, [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 6, 5, 4, 3, 2, 1], paint,
104                     null, null, {filter: CK.FilterMode.Linear, mipmap: CK.MipmapMode.Nearest});
105       canvas.drawCircle(20, 20, 20, paint);
106    canvas.drawColor(someColor);
107    canvas.drawColor(someColor, CK.BlendMode.ColorDodge);
108    canvas.drawColorComponents(0.2, 1.0, -0.02, 0.5);
109    canvas.drawColorComponents(0.2, 1.0, -0.02, 0.5, CK.BlendMode.ColorDodge);
110    canvas.drawColorInt(CK.ColorAsInt(100, 110, 120));
111    canvas.drawColorInt(CK.ColorAsInt(100, 110, 120), CK.BlendMode.ColorDodge);
112    canvas.drawDRRect(someRRect, CK.RRectXY(someRect, 10, 20), paint);
113    canvas.drawImage(img, 0, -43);
114    canvas.drawImage(img, 0, -43, paint);
115    canvas.drawImageCubic(img, 0, -43, 1 / 3, 1 / 4, null);
116    canvas.drawImageOptions(img, 0, -43, CK.FilterMode.Nearest, CK.MipmapMode.Nearest, paint);
117    canvas.drawImageNine(img, someRect, someRect, CK.FilterMode.Nearest);
118    canvas.drawImageNine(img, CK.XYWHiRect(10, 20, 40, 40), someRect, CK.FilterMode.Linear, paint);
119    canvas.drawImageRect(img, someRect, someRect, paint);
120    canvas.drawImageRect(img, CK.XYWHRect(90, 90, 40, 40), someRect, paint);
121    canvas.drawImageRect(img, someRect, someRect, paint, true);
122    canvas.drawImageRectCubic(img, someRect, someRect, 1 / 5, 1 / 6);
123    canvas.drawImageRectCubic(img, someRect, someRect, 1 / 5, 1 / 6, paint);
124    canvas.drawImageRectOptions(img, someRect, someRect, CK.FilterMode.Linear, CK.MipmapMode.None);
125    canvas.drawImageRectOptions(img, someRect, someRect, CK.FilterMode.Linear, CK.MipmapMode.None, paint);
126    canvas.drawLine(1, 2, 3, 4, paint);
127    canvas.drawOval(someRect, paint);
128    canvas.drawPaint(paint);
129    canvas.drawParagraph(para, 10, 7);
130    const cubics = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
131        7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12];
132    const colors = [CK.RED, CK.BLUE, CK.GREEN, CK.WHITE];
133    const texs = [1, 1, 2, 2, 3, 3, 4, 4];
134    canvas.drawPatch(cubics, null, null, null, paint);
135    canvas.drawPatch(cubics, colors, null, CK.BlendMode.Clear, paint);
136    canvas.drawPatch(cubics, null, texs, null, paint);
137    canvas.drawPatch(cubics, colors, texs, CK.BlendMode.SrcOver, paint);
138    canvas.drawPath(path, paint);
139    canvas.drawPicture(skp);
140    canvas.drawPoints(CK.PointMode.Lines, [1, 2, 3, 4, 5, 6], paint);
141    canvas.drawRect(someRect, paint);
142    canvas.drawRect4f(5, 6, 7, 8, paint);
143    canvas.drawRRect(someRRect, paint);
144    canvas.drawShadow(path, [1, 2, 3], [4, 5, 6], 7, someColor, CK.BLUE, 0);
145    const mallocedVector3 = CK.Malloc(Float32Array, 3);
146    canvas.drawShadow(path, mallocedVector3, mallocedVector3, 7, someColor, CK.BLUE, 0);
147    canvas.drawText('foo', 1, 2, paint, font);
148    canvas.drawTextBlob(textBlob, 10, 20, paint);
149    canvas.drawVertices(verts, CK.BlendMode.DstOut, paint);
150    const matrOne = canvas.findMarkedCTM('thing'); // $ExpectType Float32Array | null
151    const matrTwo = canvas.getLocalToDevice(); // $ExpectType Float32Array
152    const sc = canvas.getSaveCount(); // $ExpectType number
153    const matrThree = canvas.getTotalMatrix(); // $ExpectType number[]
154    const surface = canvas.makeSurface(imageInfo); // $ExpectType Surface | null
155    canvas.markCTM('more ctm');
156    const pixels = canvas.readPixels(85, 1000, {// $Uint8Array | Float32Array | null
157        width: 79,
158        height: 205,
159        colorType: CK.ColorType.RGBA_8888,
160        alphaType: CK.AlphaType.Unpremul,
161        colorSpace: CK.ColorSpace.SRGB,
162    });
163    const m = CK.Malloc(Uint8Array, 10);
164    img.readPixels(85, 1000, {
165        width: 79,
166        height: 205,
167        colorType: CK.ColorType.RGBA_8888,
168        alphaType: CK.AlphaType.Unpremul,
169        colorSpace: CK.ColorSpace.SRGB,
170    }, m, 4 * 85);
171    canvas.restore();
172    canvas.restoreToCount(2);
173    canvas.rotate(1, 2, 3);
174    const height = canvas.save(); // $ExpectType number
175    const h2 = canvas.saveLayer(); // $ExpectType number
176    const h3 = canvas.saveLayer(paint); // $ExpectType number
177    const h4 = canvas.saveLayer(paint, someRect);
178    const h5 = canvas.saveLayer(paint, someRect, imgFilter, CK.SaveLayerF16ColorType);
179    const h6 = canvas.saveLayer(paint, someRect, null, CK.SaveLayerInitWithPrevious);
180    canvas.scale(5, 10);
181    canvas.skew(10, 5);
182    canvas.translate(20, 30);
183    const ok = canvas.writePixels([1, 2, 3, 4], 1, 1, 10, 20); // $ExpectType boolean
184    const ok2 = canvas.writePixels([1, 2, 3, 4], 1, 1, 10, 20, CK.AlphaType.Premul,
185                                   CK.ColorType.Alpha_8, CK.ColorSpace.DISPLAY_P3);
186}
187
188function canvas2DTests(CK: CanvasKit) {
189    const bytes = new ArrayBuffer(10);
190
191    const canvas = CK.MakeCanvas(100, 200);
192    const img = canvas.decodeImage(bytes);
193    const ctx = canvas.getContext('2d');
194    ctx!.lineTo(2, 4);
195    canvas.loadFont(bytes, {
196        family: 'BungeeNonSystem',
197        style: 'normal',
198        weight: '400',
199    });
200    const p2d = canvas.makePath2D();
201    p2d.quadraticCurveTo(1, 2, 3, 4);
202    const iData = new CK.ImageData(40, 50);
203    const imgStr = canvas.toDataURL();
204}
205
206function colorTests(CK: CanvasKit) {
207    const colorOne = CK.Color(200, 200, 200, 0.8); // $ExpectType Float32Array
208    const colorTwo = CK.Color4f(0.8, 0.8, 0.8, 0.7); // $ExpectType Float32Array
209    const colorThree = CK.ColorAsInt(240, 230, 220); // $ExpectType number
210    const colorFour = CK.parseColorString('#887766'); // $ExpectType Float32Array
211    const colors = CK.computeTonalColors({ // $ExpectType TonalColorsOutput
212        ambient: colorOne,
213        spot: [0.2, 0.4, 0.6, 0.8],
214    });
215
216    // Deprecated Color functions
217    const [r, g, b, a] = CK.getColorComponents(colorTwo);
218    const alphaChanged = CK.multiplyByAlpha(colorOne, 0.1);
219}
220
221function colorFilterTests(CK: CanvasKit) {
222    const cf = CK.ColorFilter; // less typing
223    const filterOne = cf.MakeBlend(CK.CYAN, CK.BlendMode.ColorBurn); // $ExpectType ColorFilter
224    const filterTwo = cf.MakeLinearToSRGBGamma(); // $ExpectType ColorFilter
225    const filterThree = cf.MakeSRGBToLinearGamma(); // $ExpectType ColorFilter
226    const filterFour = cf.MakeCompose(filterOne, filterTwo); // $ExpectType ColorFilter
227    const filterFive = cf.MakeLerp(0.7, filterThree, filterFour); // $ExpectType ColorFilter
228
229    const r = CK.ColorMatrix.rotated(0, .707, -.707);  // $ExpectType Float32Array
230    const b = CK.ColorMatrix.rotated(2, .5, .866);
231    const s = CK.ColorMatrix.scaled(0.9, 1.5, 0.8, 0.8);
232    let cm = CK.ColorMatrix.concat(r, s);
233    cm = CK.ColorMatrix.concat(cm, b);
234    CK.ColorMatrix.postTranslate(cm, 20, 0, -10, 0);
235
236    const filterSix = CK.ColorFilter.MakeMatrix(cm); // $ExpectType ColorFilter
237}
238
239function contourMeasureTests(CK: CanvasKit, path?: Path) {
240    if (!path) return;
241    const iter = new CK.ContourMeasureIter(path, true, 2); // $ExpectType ContourMeasureIter
242    const contour = iter.next(); // $ExpectType ContourMeasure | null
243    if (!contour) return;
244    const pt = contour.getPosTan(2); // $ExpectType Float32Array
245    contour.getPosTan(2, pt);
246    const segment = contour.getSegment(0, 20, true); // $ExpectType Path
247    const closed = contour.isClosed(); // $ExpectType boolean
248    const length = contour.length(); // $ExpectType number
249}
250
251function imageTests(CK: CanvasKit, imgElement?: HTMLImageElement) {
252    if (!imgElement) return;
253    const buff = new ArrayBuffer(10);
254    const img = CK.MakeImageFromEncoded(buff); // $ExpectType Image | null
255    const img2 = CK.MakeImageFromCanvasImageSource(imgElement); // $ExpectType Image
256    const img3 = CK.MakeImage({ // $ExpectType Image | null
257      width: 1,
258      height: 1,
259      alphaType: CK.AlphaType.Premul,
260      colorType: CK.ColorType.RGBA_8888,
261      colorSpace: CK.ColorSpace.SRGB
262    }, Uint8Array.of(255, 0, 0, 250), 4);
263    const img4 = CK.MakeLazyImageFromTextureSource(imgElement); // $ExpectType Image
264    const img5 = CK.MakeLazyImageFromTextureSource(imgElement, {
265      width: 1,
266      height: 1,
267      alphaType: CK.AlphaType.Premul,
268      colorType: CK.ColorType.RGBA_8888,
269    });
270    if (!img) return;
271    const dOne = img.encodeToBytes(); // $ExpectType Uint8Array | null
272    const dTwo = img.encodeToBytes(CK.ImageFormat.JPEG, 97);
273    const h = img.height();
274    const w = img.width();
275    const s1 = img.makeShaderCubic(CK.TileMode.Decal, CK.TileMode.Repeat, 1 / 3, 1 / 3); // $ExpectType Shader
276    const mm = img.makeCopyWithDefaultMipmaps(); // $ExpectType Image
277    const s2 = mm.makeShaderOptions(CK.TileMode.Decal, CK.TileMode.Repeat, // $ExpectType Shader
278        CK.FilterMode.Nearest, CK.MipmapMode.Linear,
279        CK.Matrix.identity());
280    const pixels = img.readPixels(85, 1000, { // $ExpectType Float32Array | Uint8Array | null
281        width: 79,
282        height: 205,
283        colorType: CK.ColorType.RGBA_8888,
284        alphaType: CK.AlphaType.Unpremul,
285        colorSpace: CK.ColorSpace.SRGB,
286    });
287    const m = CK.Malloc(Uint8Array, 10);
288    img.readPixels(85, 1000, {
289        width: 79,
290        height: 205,
291        colorType: CK.ColorType.RGBA_8888,
292        alphaType: CK.AlphaType.Unpremul,
293        colorSpace: CK.ColorSpace.SRGB,
294    }, m, 4 * 85);
295    const ii = img.getImageInfo(); // $ExpectType PartialImageInfo
296    const cs = img.getColorSpace(); // $ExpectType ColorSpace
297    cs.delete();
298    img.delete();
299}
300
301function imageFilterTests(CK: CanvasKit, colorFilter?: ColorFilter) {
302    if (!colorFilter) return;
303    const imgf = CK.ImageFilter; // less typing
304    const filter = imgf.MakeBlur(2, 4, CK.TileMode.Mirror, null); // $ExpectType ImageFilter
305    const filter1 = imgf.MakeBlur(2, 4, CK.TileMode.Decal, filter); // $ExpectType ImageFilter
306    const filter2 = imgf.MakeColorFilter(colorFilter, null); // $ExpectType ImageFilter
307    const filter3 = imgf.MakeColorFilter(colorFilter, filter); // $ExpectType ImageFilter
308    const filter4 = imgf.MakeCompose(null, filter2); // $ExpectType ImageFilter
309    const filter5 = imgf.MakeCompose(filter3, null); // $ExpectType ImageFilter
310    const filter6 = imgf.MakeCompose(filter4, filter2); // $ExpectType ImageFilter
311    const filter7 = imgf.MakeMatrixTransform(CK.Matrix.scaled(2, 3, 10, 10),
312                                             { B: 0, C: 0.5 }, null);
313    const filter8 = imgf.MakeMatrixTransform(CK.M44.identity(),
314                                             { filter: CK.FilterMode.Linear, mipmap: CK.MipmapMode.Nearest },
315                                             filter6);
316    const filter9 = imgf.MakeMatrixTransform(CK.M44.identity(),
317                                             { filter: CK.FilterMode.Nearest },
318                                             filter6);
319}
320
321function fontTests(CK: CanvasKit, face?: Typeface, paint?: Paint) {
322    if (!face || !paint) return;
323    const font = new CK.Font(); // $ExpectType Font
324    const f2 = new CK.Font(face); // $ExpectType Font
325    const f3 = new CK.Font(null); // $ExpectType Font
326    const f4 = new CK.Font(face, 20); // $ExpectType Font
327    const f5 = new CK.Font(null, 20); // $ExpectType Font
328    const f6 = new CK.Font(null, 20, 2, 3); // $ExpectType Font
329    const f7 = new CK.Font(face, 20, 4, 5); // $ExpectType Font
330
331    const glyphMalloc = CK.MallocGlyphIDs(20);
332    const someGlyphs = [1, 2, 3, 4, 5];
333
334    const glyphBounds = font.getGlyphBounds(glyphMalloc, paint); // $ExpectType Float32Array
335    font.getGlyphBounds(someGlyphs, null, glyphBounds);
336
337    const ids = font.getGlyphIDs('abcd');
338    font.getGlyphIDs('efgh', 4, ids);
339
340    const widths = font.getGlyphWidths(glyphMalloc, paint);
341    font.getGlyphWidths(someGlyphs, null, widths);
342
343    const sects = font.getGlyphIntercepts(ids, [10, 20], -60, -40);
344
345    font.getScaleX();
346    font.getSize();
347    font.getSkewX();
348    font.getTypeface();
349    font.setEdging(CK.FontEdging.Alias);
350    font.setEmbeddedBitmaps(true);
351    font.setHinting(CK.FontHinting.Slight);
352    font.setLinearMetrics(true);
353    font.setScaleX(5);
354    font.setSize(15);
355    font.setSkewX(2);
356    font.setSubpixel(true);
357    font.setTypeface(null);
358    font.setTypeface(face);
359}
360
361function fontMgrTests(CK: CanvasKit) {
362    const buff1 = new ArrayBuffer(10);
363    const buff2 = new ArrayBuffer(20);
364
365    const fm = CK.FontMgr.FromData(buff1, buff2)!;
366    fm.countFamilies();
367    fm.getFamilyName(0);
368}
369
370function globalTests(CK: CanvasKit, path?: Path) {
371    if (!path) {
372        return;
373    }
374    const n = CK.getDecodeCacheLimitBytes();
375    const u = CK.getDecodeCacheUsedBytes();
376    CK.setDecodeCacheLimitBytes(1000);
377    const matr = CK.Matrix.rotated(Math.PI / 6);
378    const p = CK.getShadowLocalBounds(matr, path, [0, 0, 1], [500, 500, 20], 20,
379        CK.ShadowDirectionalLight | CK.ShadowGeometricOnly | CK.ShadowDirectionalLight);
380    const mallocedVector3 = CK.Malloc(Float32Array, 3);
381    const q = CK.getShadowLocalBounds(matr, path, mallocedVector3, mallocedVector3, 20,
382    CK.ShadowDirectionalLight | CK.ShadowGeometricOnly | CK.ShadowDirectionalLight);
383}
384
385function paintTests(CK: CanvasKit, colorFilter?: ColorFilter, imageFilter?: ImageFilter,
386                    maskFilter?: MaskFilter, pathEffect?: PathEffect, shader?: Shader) {
387    if (!colorFilter || !colorFilter || !imageFilter || !maskFilter || !pathEffect || !shader) {
388        return;
389    }
390    const paint = new CK.Paint(); // $ExpectType Paint
391    const newPaint = paint.copy(); // $ExpectType Paint
392    const color = paint.getColor(); // $ExpectType Float32Array
393    const sc = paint.getStrokeCap();
394    const sj = paint.getStrokeJoin();
395    const limit = paint.getStrokeMiter(); // $ExpectType number
396    const width = paint.getStrokeWidth(); // $ExpectType number
397    paint.setAlphaf(0.8);
398    paint.setAntiAlias(true);
399    paint.setBlendMode(CK.BlendMode.DstOut);
400    paint.setColor(CK.RED);
401    paint.setColor([0, 0, 1.2, 0.5], CK.ColorSpace.DISPLAY_P3);
402    paint.setColorComponents(0, 0, 0.9, 1.0);
403    paint.setColorComponents(0, 0, 1.2, 0.5, CK.ColorSpace.DISPLAY_P3);
404    paint.setColorFilter(colorFilter);
405    paint.setColorInt(CK.ColorAsInt(20, 30, 40));
406    paint.setColorInt(CK.ColorAsInt(20, 30, 40), CK.ColorSpace.SRGB);
407    paint.setImageFilter(imageFilter);
408    paint.setMaskFilter(maskFilter);
409    paint.setPathEffect(pathEffect);
410    paint.setShader(shader);
411    paint.setStrokeCap(CK.StrokeCap.Round);
412    paint.setStrokeJoin(CK.StrokeJoin.Miter);
413    paint.setStrokeMiter(10);
414    paint.setStrokeWidth(20);
415    paint.setStyle(CK.PaintStyle.Fill);
416    paint.delete();
417}
418
419function pathTests(CK: CanvasKit) {
420    const path = new CK.Path();  // $ExpectType Path
421    const p2 = CK.Path.MakeFromCmds([ // $ExpectType Path | null
422        CK.MOVE_VERB, 0, 10,
423        CK.LINE_VERB, 30, 40,
424        CK.QUAD_VERB, 20, 50, 45, 60,
425    ]);
426    const verbs = CK.Malloc(Uint8Array, 10);
427    const points = CK.Malloc(Float32Array, 10);
428    const p3 = CK.Path.MakeFromVerbsPointsWeights(verbs, [1, 2, 3, 4]); // $ExpectType Path
429    const p4 = CK.Path.MakeFromVerbsPointsWeights([CK.CONIC_VERB], points, [2.3]);
430    const p5 = CK.Path.MakeFromOp(p4, p2!, CK.PathOp.ReverseDifference); // $ExpectType Path | null
431    const p6 = CK.Path.MakeFromSVGString('M 205,5 L 795,5 z'); // $ExpectType Path | null
432    const p7 = p3.makeAsWinding(); // $ExpectType Path | null
433
434    const someRect = CK.LTRBRect(10, 20, 30, 40);
435    // Making sure arrays are accepted as rrects.
436    const someRRect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
437
438    path.addArc(someRect, 0, 270);
439    path.addOval(someRect);
440    path.addOval(someRect, true, 3);
441    path.addPath(p2);
442    path.addPoly([20, 20,  40, 40,  20, 40], true);
443    path.addRect(someRect);
444    path.addRect(someRect, true);
445    path.addRRect(someRRect);
446    path.addRRect(someRRect, true);
447    path.addVerbsPointsWeights(verbs, [1, 2, 3, 4]);
448    path.addVerbsPointsWeights([CK.CONIC_VERB], points, [2.3]);
449    path.arc(0, 0, 10, 0, Math.PI / 2);
450    path.arc(0, 0, 10, 0, Math.PI / 2, true);
451    path.arcToOval(someRect, 15, 60, true);
452    path.arcToRotated(2, 4, 90, false, true, 0, 20);
453    path.arcToTangent(20, 20, 40, 50, 2);
454    path.close();
455    let bounds = path.computeTightBounds(); // $ExpectType Float32Array
456    path.computeTightBounds(bounds);
457    path.conicTo(1, 2, 3, 4, 5);
458    let ok = path.contains(10, 20); // $ExpectType boolean
459    const pCopy = path.copy(); // $ExpectType Path
460    const count = path.countPoints(); // $ExpectType number
461    path.cubicTo(10, 10, 10, 10, 10, 10);
462    ok = path.dash(8, 4, 1);
463    ok = path.equals(pCopy);
464    bounds = path.getBounds(); // $ExpectType Float32Array
465    path.getBounds(bounds);
466    const ft = path.getFillType();
467    const pt = path.getPoint(7); // $ExpectType Float32Array
468    path.getPoint(8, pt);
469    ok = path.isEmpty();
470    ok = path.isVolatile();
471    path.lineTo(10, -20);
472    path.moveTo(-20, -30);
473    path.offset(100, 100);
474    ok = path.op(p2!, CK.PathOp.Difference);
475    path.quadTo(10, 20, 30, 40);
476    path.rArcTo(10, 10, 90, false, true, 2, 4);
477    path.rConicTo(-1, 2, 4, 9, 3);
478    path.rCubicTo(20, 30, 40, 50, 2, 1);
479    path.reset();
480    path.rewind();
481    path.rLineTo(20, 30);
482    path.rMoveTo(40, 80);
483    path.rQuadTo(1, 2, 3, 4);
484    path.setFillType(CK.FillType.EvenOdd);
485    path.setIsVolatile(true);
486    ok = path.simplify();
487    path.stroke();
488    path.stroke({});
489    path.stroke({
490        width: 20,
491        miter_limit: 9,
492        precision: 0.5,
493        cap: CK.StrokeCap.Butt,
494        join: CK.StrokeJoin.Miter,
495    });
496    const cmds = path.toCmds(); // $ExpectType Float32Array
497    const str = path.toSVGString(); // $ExpectType string
498    path.transform(CK.Matrix.identity());
499    path.transform(1, 0, 0, 0, 1, 0, 0, 0, 1);
500    path.trim(0.1, 0.7, false);
501}
502
503function paragraphTests(CK: CanvasKit, p?: Paragraph) {
504    if (!p) return;
505    const a = p.didExceedMaxLines(); // $ExpectType boolean
506    const b = p.getAlphabeticBaseline(); // $ExpectType number
507    const c = p.getGlyphPositionAtCoordinate(10, 3); // $ExpectType PositionWithAffinity
508    const d = p.getHeight(); // $ExpectType number
509    const e = p.getIdeographicBaseline(); // $ExpectType number
510    const f = p.getLongestLine(); // $ExpectType number
511    const g = p.getMaxIntrinsicWidth(); // $ExpectType number
512    const h = p.getMaxWidth(); // $ExpectType number
513    const i = p.getMinIntrinsicWidth(); // $ExpectType number
514    const j = p.getRectsForPlaceholders(); // $ExpectType Float32Array
515    const k = p.getRectsForRange(2, 10, CK.RectHeightStyle.Max,  // $ExpectType Float32Array
516        CK.RectWidthStyle.Tight);
517    const l = p.getWordBoundary(10); // $ExpectType URange
518    p.layout(300);
519    const m = p.getLineMetrics(); // $ExpectType LineMetrics[]
520    const n = CK.GlyphRunFlags.IsWhiteSpace === 1;
521}
522
523function paragraphBuilderTests(CK: CanvasKit, fontMgr?: FontMgr, paint?: Paint) {
524    if (!fontMgr || !paint) return;
525    const paraStyle = new CK.ParagraphStyle({ // $ExpectType ParagraphStyle
526        textStyle: {
527            color: CK.BLACK,
528            fontFamilies: ['Noto Serif'],
529            fontSize: 20,
530        },
531        textAlign: CK.TextAlign.Center,
532        maxLines: 8,
533        ellipsis: '.._.',
534        strutStyle: {
535            strutEnabled: true,
536            fontFamilies: ['Roboto'],
537            fontSize: 28,
538            heightMultiplier: 1.5,
539            forceStrutHeight: true,
540        },
541        disableHinting: true,
542        heightMultiplier: 2.5,
543        textDirection: CK.TextDirection.LTR,
544        textHeightBehavior: CK.TextHeightBehavior.DisableFirstAscent
545    });
546    const blueText = new CK.TextStyle({ // $ExpectType TextStyle
547        backgroundColor: CK.Color(234, 208, 232), // light pink
548        color: CK.Color(48, 37, 199),
549        fontFamilies: ['Noto Serif'],
550        decoration: CK.LineThroughDecoration,
551        decorationStyle: CK.DecorationStyle.Dashed,
552        decorationThickness: 1.5, // multiplier based on font size
553        fontSize: 24,
554        fontFeatures: [{name: 'smcp', value: 1}],
555        shadows: [{color: CK.BLACK, blurRadius: 15},
556                  {color: CK.RED, blurRadius: 5, offset: [10, 10]}],
557    });
558
559    const builder = CK.ParagraphBuilder.Make(paraStyle, fontMgr); // $ExpectType ParagraphBuilder
560
561    builder.pushStyle(blueText);
562    builder.addText('VAVAVAVAVAVAVA\nVAVA\n');
563    builder.pop();
564    const paragraph = builder.build(); // $ExpectType Paragraph
565
566    const buf = new ArrayBuffer(10);
567    const fontSrc = CK.TypefaceFontProvider.Make(); // $ExpectType TypefaceFontProvider
568    fontSrc.registerFont(buf, 'sans-serif');
569    const builder2 = CK.ParagraphBuilder.MakeFromFontProvider(// $ExpectType ParagraphBuilder
570                                paraStyle, fontSrc);
571    builder2.pushPaintStyle(blueText, paint, paint);
572    builder2.addPlaceholder();
573    builder2.addPlaceholder(10, 20, CK.PlaceholderAlignment.Top, CK.TextBaseline.Ideographic, 3);
574}
575
576function particlesTests(CK: CanvasKit, canvas?: Canvas) {
577    if (!canvas) return;
578
579    const par = CK.MakeParticles('some json'); // $ExpectType Particles
580    par.draw(canvas);
581    par.uniforms()[0] = 1.2;
582    const a = par.getUniform(1); // $ExpectType SkSLUniform
583    const b = par.getUniformCount(); // $ExpectType number
584    const c = par.getUniformFloatCount(); // $ExpectType number
585    const d = par.getUniformName(3); // $ExpectType string
586    par.uniforms()[2] = 4.5;
587    par.setPosition([3, 5]);
588    par.setRate(3);
589    par.start(0, true);
590    par.update(2);
591
592    const buff = new ArrayBuffer(10);
593    const par2 = CK.MakeParticles('other json', { // $ExpectType Particles
594        'flightAnim.gif': buff,
595    });
596}
597
598function pathEffectTests(CK: CanvasKit) {
599    const pe1 = CK.PathEffect.MakeCorner(2); // $ExpectType PathEffect | null
600    const pe2 = CK.PathEffect.MakeDash([2, 4]); // $ExpectType PathEffect
601    const pe3 = CK.PathEffect.MakeDash([2, 4, 6, 8], 10); // $ExpectType PathEffect
602    const pe4 = CK.PathEffect.MakeDiscrete(10, 2, 0); // $ExpectType PathEffect
603}
604
605function mallocTests(CK: CanvasKit) {
606    const mFoo = CK.Malloc(Float32Array, 5);
607    const mArray = mFoo.toTypedArray(); // $ExpectType TypedArray
608    mArray[3] = 1.7;
609    const mSubArray = mFoo.subarray(0, 2); // $ExpectType TypedArray
610    mSubArray[0] = 2;
611    CK.Free(mFoo);
612}
613
614function maskFilterTests(CK: CanvasKit) {
615    const mf = CK.MaskFilter.MakeBlur(CK.BlurStyle.Solid, 8, false); // $ExpectType MaskFilter
616}
617
618function matrixTests(CK: CanvasKit) {
619    const m33 = CK.Matrix; // less typing
620    const matrA = m33.identity(); // $ExpectType number[]
621    const matrB = m33.rotated(0.1); // $ExpectType number[]
622    const matrC = m33.rotated(0.1, 15, 20); // $ExpectType number[]
623    const matrD = m33.multiply(matrA, matrB); // $ExpectType number[]
624    const matrE = m33.multiply(matrA, matrB, matrC, matrB, matrA); // $ExpectType number[]
625    const matrF = m33.scaled(1, 2); // $ExpectType number[]
626    const matrG = m33.scaled(1, 2, 3, 4); // $ExpectType number[]
627    const matrH = m33.skewed(1, 2); // $ExpectType number[]
628    const matrI = m33.skewed(1, 2, 3, 4); // $ExpectType number[]
629    const matrJ = m33.translated(1, 2); // $ExpectType number[]
630    const matrK = m33.invert(matrJ);
631
632    const m44 = CK.M44;
633    const matr1 = m44.identity(); // $ExpectType number[]
634    const matr2 = m44.invert(matr1);
635    const matr3 = m44.lookat([1, 2, 3], [4, 5, 6], [7, 8, 9]); // $ExpectType number[]
636    const matr4 = m44.multiply(matr1, matr3); // $ExpectType number[]
637    const matr5 = m44.mustInvert(matr1); // $ExpectType number[]
638    const matr6 = m44.perspective(1, 8, 0.4); // $ExpectType number[]
639    const matr7 = m44.rc(matr6, 0, 3); // $ExpectType number
640    const matr8 = m44.rotated([2, 3, 4], -0.4); // $ExpectType number[]
641    const matr9 = m44.rotatedUnitSinCos([4, 3, 2], 0.9, 0.1); // $ExpectType number[]
642    const matr10 = m44.scaled([5, 5, 5]); // $ExpectType number[]
643    const matr11 = m44.setupCamera(CK.LTRBRect(1, 2, 3, 4), 0.4, {
644        eye: [0, 0, 1],
645        coa: [0, 0, 0],
646        up:  [0, 1, 0],
647        near: 0.2,
648        far: 4,
649        angle: Math.PI / 12,
650    });
651    const matr12 = m44.translated([3, 2, 1]); // $ExpectType number[]
652    const matr13 = m44.transpose([4, 5, 8]); // $ExpectType number[]
653}
654
655function pictureTests(CK: CanvasKit) {
656    const recorder = new CK.PictureRecorder(); // $ExpectType PictureRecorder
657    const canvas = recorder.beginRecording(CK.LTRBRect(0, 0, 100, 100));  // $ExpectType Canvas
658    const pic = recorder.finishRecordingAsPicture(); // $ExpectType SkPicture
659    const bytes = pic.serialize(); // $ExpectType Uint8Array | null
660    const pic2 = CK.MakePicture(bytes!);
661}
662
663function rectangleTests(CK: CanvasKit) {
664    const rectOne = CK.LTRBRect(5, 10, 20, 30); // $ExpectType Float32Array
665    const rectTwo = CK.XYWHRect(5, 10, 15, 20); // $ExpectType Float32Array
666    const iRectOne = CK.LTRBiRect(105, 110, 120, 130); // $ExpectType Int32Array
667    const iRectTwo = CK.XYWHiRect(105, 110, 15, 20); // $ExpectType Int32Array
668    const rrectOne = CK.RRectXY(rectOne, 3, 7);  // $ExpectType Float32Array
669}
670
671function runtimeEffectTests(CK: CanvasKit) {
672    const rt = CK.RuntimeEffect.Make('not real sksl code'); // $ExpectType RuntimeEffect | null
673    if (!rt) return;
674    const rt2 = CK.RuntimeEffect.Make('not real sksl code', (err) => {
675        console.log(err);
676    });
677    const someMatr = CK.Matrix.translated(2, 60);
678    const s1 = rt.makeShader([0, 1]); // $ExpectType Shader
679    const s2 = rt.makeShader([0, 1], true, someMatr); // $ExpectType Shader
680    const s3 = rt.makeShaderWithChildren([4, 5], true, [s1, s2]); // $ExpectType Shader
681    const s4 = rt.makeShaderWithChildren([4, 5], true, [s1, s2], someMatr); // $ExpectType Shader
682    const a = rt.getUniform(1); // $ExpectType SkSLUniform
683    const b = rt.getUniformCount(); // $ExpectType number
684    const c = rt.getUniformFloatCount(); // $ExpectType number
685    const d = rt.getUniformName(3); // $ExpectType string
686}
687
688function skottieTests(CK: CanvasKit, canvas?: Canvas) {
689    if (!canvas) return;
690
691    const anim = CK.MakeAnimation('some json'); // $ExpectType SkottieAnimation
692    const a = anim.duration(); // $ExpectType number
693    const b = anim.fps(); // $ExpectType number
694    const c = anim.version(); // $ExpectType string
695    const d = anim.size(); // $ExpectType Float32Array
696    anim.size(d);
697    const rect = anim.seek(0.5);
698    anim.seek(0.6, rect);
699    const rect2 = anim.seekFrame(12.3);
700    anim.seekFrame(12.3, rect2);
701    anim.render(canvas);
702    anim.render(canvas, rect);
703
704    const buff = new ArrayBuffer(10);
705    const mAnim = CK.MakeManagedAnimation('other json', { // $ExpectType ManagedSkottieAnimation
706        'flightAnim.gif': buff,
707    });
708    mAnim.setColor('slider', CK.WHITE);
709    mAnim.setOpacity('slider', 0.8);
710    const e = mAnim.getMarkers();  // $ExpectType AnimationMarker[]
711    const f = mAnim.getColorProps();  // $ExpectType ColorProperty[]
712    const g = mAnim.getOpacityProps();  // $ExpectType OpacityProperty[]
713    const h = mAnim.getTextProps();  // $ExpectType TextProperty[]
714
715    const i = mAnim.setColor('foo', CK.RED);  // $ExpectType boolean
716    const j = mAnim.setOpacity('foo', 0.5);  // $ExpectType boolean
717    const k = mAnim.setText('foo', 'bar', 12);  // $ExpectType boolean
718}
719
720function shaderTests(CK: CanvasKit) {
721    const s1 = CK.Shader.MakeColor([0.8, 0.2, 0.5, 0.9], // $ExpectType Shader
722                                 CK.ColorSpace.SRGB);
723    const s2 = CK.Shader.MakeBlend(CK.BlendMode.Src, s1, s1); // $ExpectType Shader
724    const s4 = CK.Shader.MakeLinearGradient(// $ExpectType Shader
725        [0, 0], [50, 100],
726        Float32Array.of(
727            0, 1, 0, 0.8,
728            1, 0, 0, 1,
729            0, 0, 1, 0.5,
730        ),
731        [0, 0.65, 1.0],
732        CK.TileMode.Mirror
733    );
734    const s5 = CK.Shader.MakeLinearGradient(// $ExpectType Shader
735        [0, 0], [50, 100],
736        Float32Array.of(
737            0, 1, 0, 0.8,
738            1, 0, 0, 1,
739            0, 0, 1, 0.5,
740        ),
741        null,
742        CK.TileMode.Clamp,
743        CK.Matrix.rotated(Math.PI / 4, 0, 100),
744        1,
745        CK.ColorSpace.SRGB,
746    );
747    const s6 = CK.Shader.MakeRadialGradient(// $ExpectType Shader
748        [0, 0], 50,
749        Float32Array.of(
750            0, 1, 0, 0.8,
751            1, 0, 0, 1,
752            0, 0, 1, 0.5,
753        ),
754        [0, 0.65, 1.0],
755        CK.TileMode.Decal,
756    );
757    const s7 = CK.Shader.MakeRadialGradient(// $ExpectType Shader
758        [0, 0], 50,
759        Float32Array.of(
760            0, 1, 0, 0.8,
761            1, 0, 0, 1,
762            0, 0, 1, 0.5,
763        ),
764        null,
765        CK.TileMode.Clamp,
766        CK.Matrix.skewed(3, -3),
767        1,
768        CK.ColorSpace.SRGB,
769    );
770    const s8 = CK.Shader.MakeTwoPointConicalGradient(// $ExpectType Shader
771        [0, 0], 20,
772        [50, 100], 60,
773        Float32Array.of(
774            0, 1, 0, 0.8,
775            1, 0, 0, 1,
776            0, 0, 1, 0.5,
777        ),
778        [0, 0.65, 1.0],
779        CK.TileMode.Mirror
780    );
781    const s9 = CK.Shader.MakeTwoPointConicalGradient(// $ExpectType Shader
782        [0, 0], 20,
783        [50, 100], 60,
784        Float32Array.of(
785            0, 1, 0, 0.8,
786            1, 0, 0, 1,
787            0, 0, 1, 0.5,
788        ),
789        [0, 0.65, 1.0],
790        CK.TileMode.Mirror,
791        CK.Matrix.rotated(Math.PI / 4, 0, 100),
792        1,
793        CK.ColorSpace.SRGB,
794    );
795    const s10 = CK.Shader.MakeSweepGradient(// $ExpectType Shader
796        0, 20,
797        Float32Array.of(
798            0, 1, 0, 0.8,
799            1, 0, 0, 1,
800            0, 0, 1, 0.5,
801        ),
802        [0, 0.65, 1.0],
803        CK.TileMode.Mirror
804    );
805    const s11 = CK.Shader.MakeSweepGradient(// $ExpectType Shader
806        0, 20,
807        Float32Array.of(
808            0, 1, 0, 0.8,
809            1, 0, 0, 1,
810            0, 0, 1, 0.5,
811        ),
812        null,
813        CK.TileMode.Mirror,
814        CK.Matrix.rotated(Math.PI / 4, 0, 100),
815        1,
816        15, 275, // start, end angle in degrees.
817        CK.ColorSpace.SRGB,
818    );
819    const s12 = CK.Shader.MakeFractalNoise(0.1, 0.05, 2, 0, 80, 80); // $ExpectType Shader
820    const s13 = CK.Shader.MakeTurbulence(0.1, 0.05, 2, 0, 80, 80); // $ExpectType Shader
821}
822
823function surfaceTests(CK: CanvasKit, gl?: WebGLRenderingContext) {
824    if (!gl) {
825        return;
826    }
827    const canvasEl = document.querySelector('canvas') as HTMLCanvasElement;
828    const surfaceOne = CK.MakeCanvasSurface(canvasEl)!; // $ExpectType Surface
829    const surfaceTwo = CK.MakeCanvasSurface('my_canvas')!;
830    const surfaceThree = CK.MakeSWCanvasSurface(canvasEl)!; // $ExpectType Surface
831    const surfaceFour = CK.MakeSWCanvasSurface('my_canvas')!;
832    const surfaceFive = CK.MakeWebGLCanvasSurface(canvasEl, // $ExpectType Surface
833        CK.ColorSpace.SRGB, {
834        majorVersion: 2,
835        preferLowPowerToHighPerformance: 1,
836    })!;
837    const surfaceSix = CK.MakeWebGLCanvasSurface('my_canvas', CK.ColorSpace.DISPLAY_P3, {
838        enableExtensionsByDefault: 2,
839    })!;
840    const surfaceSeven = CK.MakeSurface(200, 200)!; // $ExpectType Surface
841    const m = CK.Malloc(Uint8Array, 5 * 5 * 4);
842    const surfaceEight = CK.MakeRasterDirectSurface({
843        width: 5,
844        height: 5,
845        colorType: CK.ColorType.RGBA_8888,
846        alphaType: CK.AlphaType.Premul,
847        colorSpace: CK.ColorSpace.SRGB,
848    }, m, 20);
849
850    surfaceOne.flush();
851    const canvas = surfaceTwo.getCanvas(); // $ExpectType Canvas
852    const ii = surfaceThree.imageInfo(); // $ExpectType ImageInfo
853    const h = surfaceFour.height(); // $ExpectType number
854    const w = surfaceFive.width(); // $ExpectType number
855    const subsurface = surfaceOne.makeSurface(ii); // $ExpectType Surface
856    const isGPU = subsurface.reportBackendTypeIsGPU(); // $ExpectType boolean
857    const count = surfaceThree.sampleCnt(); // $ExpectType number
858    const img = surfaceFour.makeImageSnapshot([0, 3, 2, 5]); // $ExpectType Image
859    const img2 = surfaceSix.makeImageSnapshot(); // $ExpectType Image
860    const img3 = surfaceFour.makeImageFromTexture(gl.createTexture()!, {
861      height: 40,
862      width: 80,
863      colorType: CK.ColorType.RGBA_8888,
864      alphaType: CK.AlphaType.Unpremul,
865      colorSpace: CK.ColorSpace.SRGB,
866    });
867    const img4 = surfaceFour.makeImageFromTextureSource(new Image()); // $ExpectType Image | null
868    const videoEle = document.createElement('video');
869    const img5 = surfaceFour.makeImageFromTextureSource(videoEle, {
870      height: 40,
871      width: 80,
872      colorType: CK.ColorType.RGBA_8888,
873      alphaType: CK.AlphaType.Unpremul,
874    });
875    const img6 = surfaceFour.makeImageFromTextureSource(new ImageData(40, 80)); // $ExpectType Image | null
876
877    surfaceSeven.delete();
878
879    const ctx = CK.GetWebGLContext(canvasEl); // $ExpectType number
880    CK.deleteContext(ctx);
881    const grCtx = CK.MakeGrContext(ctx);
882    const surfaceNine = CK.MakeOnScreenGLSurface(grCtx!, 100, 400, // $ExpectType Surface
883        CK.ColorSpace.ADOBE_RGB)!;
884
885    const rt = CK.MakeRenderTarget(grCtx!, 100, 200); // $ExpectType Surface | null
886    const rt2 = CK.MakeRenderTarget(grCtx!, { // $ExpectType Surface | null
887        width: 79,
888        height: 205,
889        colorType: CK.ColorType.RGBA_8888,
890        alphaType: CK.AlphaType.Premul,
891        colorSpace: CK.ColorSpace.SRGB,
892    });
893
894    const drawFrame = (canvas: Canvas) => {
895        canvas.clear([0, 0, 0, 0]);
896    };
897    surfaceFour.requestAnimationFrame(drawFrame);
898    surfaceFour.drawOnce(drawFrame);
899}
900
901function textBlobTests(CK: CanvasKit, font?: Font, path?: Path) {
902    if (!font || !path) return;
903    const tb = CK.TextBlob; // less typing
904    const ids = font.getGlyphIDs('abc');
905    const mXforms = CK.Malloc(Float32Array, ids.length * 4);
906
907    const blob = tb.MakeFromGlyphs([5, 6, 7, 8], font); // $ExpectType TextBlob
908    const blob1 = tb.MakeFromGlyphs(ids, font); // $ExpectType TextBlob
909    const blob2 = tb.MakeFromRSXform('cdf', mXforms, font); // $ExpectType TextBlob
910    const blob3 = tb.MakeFromRSXform('c', [-1, 0, 2, 3], font); // $ExpectType TextBlob
911    const blob4 = tb.MakeFromRSXformGlyphs([3, 6], mXforms, font); // $ExpectType TextBlob
912    const blob5 = tb.MakeFromRSXformGlyphs(ids, [-1, 0, 2, 3], font); // $ExpectType TextBlob
913    const blob6 = tb.MakeFromText('xyz', font); // $ExpectType TextBlob
914    const blob7 = tb.MakeOnPath('tuv', path, font); // $ExpectType TextBlob
915    const blob8 = tb.MakeOnPath('tuv', path, font, 10); // $ExpectType TextBlob
916}
917
918function typefaceTests(CK: CanvasKit) {
919    const face = CK.Typeface.MakeFreeTypeFaceFromData(new ArrayBuffer(10));
920
921    const ids = face!.getGlyphIDs('abcd');
922    face!.getGlyphIDs('efgh', 4, ids);
923}
924
925function vectorTests(CK: CanvasKit) {
926    const a = [1, 2, 3];
927    const b = [4, 5, 6];
928
929    const vec = CK.Vector; // less typing
930    const v1 = vec.add(a, b); // $ExpectType VectorN
931    const v2 = vec.cross(a, b); // $ExpectType Vector3
932    const n1 = vec.dist(a, b); // $ExpectType number
933    const n2 = vec.dot(a, b); // $ExpectType number
934    const n3 = vec.length(a); // $ExpectType number
935    const n4 = vec.lengthSquared(a); // $ExpectType number
936    const v3 = vec.mulScalar(a, 10); // $ExpectType VectorN
937    const v4 = vec.normalize(a); // $ExpectType VectorN
938    const v5 = vec.sub(a, b); // $ExpectType VectorN
939}
940
941function verticesTests(CK: CanvasKit) {
942    const points = [
943         70, 170,   40, 90,  130, 150,  100, 50,
944        225, 150,  225, 60,  310, 180,  330, 100,
945    ];
946    const textureCoordinates = [
947          0, 240,    0, 0,   80, 240,   80, 0,
948        160, 240,  160, 0,  240, 240,  240, 0,
949    ];
950    const vertices = CK.MakeVertices(CK.VertexMode.TrianglesStrip, // $ExpectType Vertices
951        points, textureCoordinates);
952
953    const points2 = new Float32Array(points);
954    // 1d float color array
955    const colors = Float32Array.of(
956        1, 0, 0, 1, // red
957        0, 1, 0, 1, // green
958        0, 0, 1, 1, // blue
959        1, 0, 1, 1); // purple
960    const vertices2 = CK.MakeVertices(CK.VertexMode.TriangleFan,
961        points2, null, colors, null, true);
962
963    const rect = vertices.bounds(); // $ExpectType Float32Array
964    vertices.bounds(rect);
965    const id = vertices.uniqueID(); // $ExpectType number
966}
967