[canvaskit] Add docs/types for Canvas.

This is the object with the most APIs by far.

Some APIs are stubbed out temporarily and will be given more
detail in a follow-up CL.

Bug: skia:10717
Change-Id: Iff5d4269303e7102ad79de90f20640918f403ff4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/320770
Reviewed-by: Nathaniel Nifong <nifong@google.com>
This commit is contained in:
Kevin Lubick 2020-09-29 17:58:21 -04:00
parent 43865d38f0
commit 97440de4b9
6 changed files with 824 additions and 50 deletions

View File

@ -82,6 +82,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
follows the establishing naming convention). follows the establishing naming convention).
- `SkSurface.captureFrameAsSkPicture` will be removed in a future release. Callers can simply - `SkSurface.captureFrameAsSkPicture` will be removed in a future release. Callers can simply
use `SkPictureRecorder` directly. use `SkPictureRecorder` directly.
- `CanvasKit.FourFloatArrayHelper` and related helpers (mostly helping with drawAtlas).
`CanvasKit.Malloc` is the better tool and will replace these soon.
### Fixed ### Fixed
- Addressed Memory leak in `SkCanvas.drawText`. - Addressed Memory leak in `SkCanvas.drawText`.

View File

@ -3,21 +3,112 @@
import CanvasKitInit from "canvaskit-wasm/bin/canvaskit"; import CanvasKitInit from "canvaskit-wasm/bin/canvaskit";
import { import {
CanvasKit, CanvasKit,
Paragraph,
ShapedText,
SkAnimatedImage,
SkCanvas, SkCanvas,
SkImage, SkImage,
SkImageInfo, SkImageInfo,
SkFont,
SkSurface, SkSurface,
SkPaint,
SkPath,
SkPicture, SkPicture,
SkTextBlob,
SkVertices,
TypedArray, TypedArray,
} from "canvaskit-wasm"; } from "canvaskit-wasm";
CanvasKitInit({locateFile: (file: string) => '/node_modules/canvaskit/bin/' + file}).then((CK: CanvasKit) => { CanvasKitInit({locateFile: (file: string) => '/node_modules/canvaskit/bin/' + file}).then((CK: CanvasKit) => {
canvasTests(CK);
colorTests(CK); colorTests(CK);
imageTests(CK);
mallocTests(CK); mallocTests(CK);
surfaceTests(CK); surfaceTests(CK);
rectangleTests(CK); rectangleTests(CK);
}); });
// In an effort to keep these type-checking tests easy to read and understand, we can "inject"
// types instead of actually having to create them from scratch. To inject them, we define them
// as an optional parameter and then have a null check to make sure that optional-ness does not
// cause errors.
function canvasTests(CK: CanvasKit, canvas?: SkCanvas, paint?: SkPaint, path?: SkPath,
img?: SkImage, aImg?: SkAnimatedImage, para?: Paragraph,
skp?: SkPicture, font?: SkFont, shapedText?: ShapedText,
textBlob?: SkTextBlob, verts?: SkVertices, imageInfo?: SkImageInfo) {
if (!canvas || !paint || !path || !img || !aImg || !para || !skp || !font ||
!shapedText || !textBlob || !verts || !imageInfo) return;
const someColor = [0.9, 0.8, 0.7, 0.6]; // Making sure arrays are accepted as colors.
const someRect = [4, 3, 2, 1]; // Making sure arrays are accepted as rects.
// Making sure arrays are accepted as rrects.
const someRRect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
const someMatrix = CK.Malloc(Float32Array, 16); // Make sure matrixes can be malloc'd.
canvas.clear(CK.RED);
canvas.clipPath(path, CK.ClipOp.Intersect, false);
canvas.clipRect(someRect, CK.ClipOp.Intersect, true);
canvas.clipRRect(CK.RRectXY(someRect, 10, 20), CK.ClipOp.Difference, true);
canvas.concat([1, 0, 0, 0, 1, 0, 0, 0, 1]);
canvas.concat(someMatrix);
canvas.drawArc(someRect, 0, 90, true, paint);
canvas.drawAtlas(img, [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 6, 5, 4, 3, 2, 1], paint);
canvas.drawAtlas(img, [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 6, 5, 4, 3, 2, 1], paint,
CK.BlendMode.Darken,
[CK.ColorAsInt(100, 110, 120), CK.ColorAsInt(130, 140, 150)]);
canvas.drawCircle(20, 20, 20, paint);
canvas.drawColor(someColor);
canvas.drawColor(someColor, CK.BlendMode.ColorDodge);
canvas.drawColorComponents(0.2, 1.0, -0.02, 0.5);
canvas.drawColorComponents(0.2, 1.0, -0.02, 0.5, CK.BlendMode.ColorDodge);
canvas.drawColorInt(CK.ColorAsInt(100, 110, 120));
canvas.drawColorInt(CK.ColorAsInt(100, 110, 120), CK.BlendMode.ColorDodge);
canvas.drawDRRect(someRRect, CK.RRectXY(someRect, 10, 20), paint);
canvas.drawImage(img, 0, -43);
canvas.drawImage(img, 0, -43, paint);
canvas.drawImageAtCurrentFrame(aImg, 0, -43);
canvas.drawImageAtCurrentFrame(aImg, 0, -43, paint);
canvas.drawImageNine(img, someRect, someRect, paint);
canvas.drawImageRect(img, someRect, someRect, paint);
canvas.drawImageRect(img, someRect, someRect, paint, true);
canvas.drawLine(1, 2, 3, 4, paint);
canvas.drawOval(someRect, paint);
canvas.drawPaint(paint);
canvas.drawParagraph(para, 10, 7);
canvas.drawPath(path, paint);
canvas.drawPicture(skp);
canvas.drawPoints(CK.PointMode.Lines, [1, 2, 3, 4, 5, 6], paint);
canvas.drawRect(someRect, paint);
canvas.drawRect4f(5, 6, 7, 8, paint);
canvas.drawRRect(someRRect, paint);
canvas.drawShadow(path, [1, 2, 3], [4, 5, 6], 7, someColor, CK.BLUE, 0);
canvas.drawText('foo', 1, 2, paint, font);
canvas.drawText(shapedText, 1, 2, paint, font);
canvas.drawTextBlob(textBlob, 10, 20, paint);
canvas.drawVertices(verts, CK.BlendMode.DstOut, paint);
const matrOne = canvas.findMarkedCTM('thing'); // $ExpectType Float32Array | null
const matrTwo = canvas.getLocalToDevice(); // $ExpectType Float32Array
const sc = canvas.getSaveCount(); // $ExpectType number
const matrThree = canvas.getTotalMatrix(); // $ExpectType Float32Array
const surface = canvas.makeSurface(imageInfo); // $ExpectType SkSurface | null
canvas.markCTM('more ctm');
const pixels = canvas.readPixels(0, 1, 2, 3); // $ExpectType Uint8Array
const pixelsTwo = canvas.readPixels(4, 5, 6, 7, CK.AlphaType.Opaque, CK.ColorType.RGBA_1010102,
CK.SkColorSpace.DISPLAY_P3, 16);
canvas.restore();
canvas.restoreToCount(2);
canvas.rotate(1, 2, 3);
const height = canvas.save(); // $ExpectType number
const h2 = canvas.saveLayer(); // $ExpectType number
const h3 = canvas.saveLayer(paint); // $ExpectType number
const h4 = canvas.saveLayer(paint, someRect); // $ExpectType number
canvas.scale(5, 10);
canvas.skew(10, 5);
canvas.translate(20, 30);
const ok = canvas.writePixels([1, 2, 3, 4], 1, 1, 10, 20); // $ExpectType boolean
const ok2 = canvas.writePixels([1, 2, 3, 4], 1, 1, 10, 20, CK.AlphaType.Premul,
CK.ColorType.Alpha_8, CK.SkColorSpace.DISPLAY_P3);
}
function colorTests(CK: CanvasKit) { function colorTests(CK: CanvasKit) {
const colorOne = CK.Color(200, 200, 200, 0.8); // $ExpectType Float32Array const colorOne = CK.Color(200, 200, 200, 0.8); // $ExpectType Float32Array
const colorTwo = CK.Color4f(0.8, 0.8, 0.8, 0.7); // $ExpectType Float32Array const colorTwo = CK.Color4f(0.8, 0.8, 0.8, 0.7); // $ExpectType Float32Array
@ -29,6 +120,23 @@ function colorTests(CK: CanvasKit) {
const alphaChanged = CK.multiplyByAlpha(colorOne, 0.1); const alphaChanged = CK.multiplyByAlpha(colorOne, 0.1);
} }
function imageTests(CK: CanvasKit, img?: SkImage) {
if (!img) return;
const dOne = img.encodeToData(); // $ExpectType SkData
const dTwo = img.encodeToDataWithFormat(CK.ImageFormat.JPEG, 97);
const bytes = CK.getSkDataBytes(dTwo); // $ExpectType Uint8Array
const h = img.height();
const w = img.width();
const shader = img.makeShader(CK.TileMode.Decal, CK.TileMode.Repeat); // $ExpectType SkShader
const pixels = img.readPixels({
width: 79,
height: 205,
colorType: CK.ColorType.RGBA_8888,
alphaType: CK.AlphaType.Unpremul,
colorSpace: CK.SkColorSpace.SRGB,
}, 85, 1000);
}
function mallocTests(CK: CanvasKit) { function mallocTests(CK: CanvasKit) {
const mFoo = CK.Malloc(Float32Array, 5); const mFoo = CK.Malloc(Float32Array, 5);
const mArray = mFoo.toTypedArray(); // $ExpectType TypedArray const mArray = mFoo.toTypedArray(); // $ExpectType TypedArray

View File

@ -104,7 +104,7 @@ export interface CanvasKit {
* @param rx - The radius of the corners in the x direction. * @param rx - The radius of the corners in the x direction.
* @param ry - The radius of the corners in the y direction. * @param ry - The radius of the corners in the y direction.
*/ */
RRectXY(rect: SkRect, rx: number, ry: number): SkRRect; RRectXY(rect: InputRect, rx: number, ry: number): SkRRect;
/** /**
* Malloc returns a TypedArray backed by the C++ memory of the * Malloc returns a TypedArray backed by the C++ memory of the
@ -134,11 +134,6 @@ export interface CanvasKit {
*/ */
Free(m: MallocObj): void; Free(m: MallocObj): void;
// TODO(kjlubick) in helper.js
// - SkRectBuilder
// - RSXFormBuilder
// - SkColorBuilder
// Surface related functions // Surface related functions
/** /**
* Creates a Surface on a given canvas. If both GPU and CPU modes have been compiled in, this * Creates a Surface on a given canvas. If both GPU and CPU modes have been compiled in, this
@ -161,7 +156,7 @@ export interface CanvasKit {
* @param colorSpace - One of the supported color spaces. Default is SRGB. * @param colorSpace - One of the supported color spaces. Default is SRGB.
* @param opts - Options that will get passed to the creation of the WebGL context. * @param opts - Options that will get passed to the creation of the WebGL context.
*/ */
MakeWebGLCanvasSurface(canvas: HTMLCanvasElement | string, colorSpace?: SkColorSpace, MakeWebGLCanvasSurface(canvas: HTMLCanvasElement | string, colorSpace?: ColorSpace,
opts?: WebGLOptions): SkSurface | null; opts?: WebGLOptions): SkSurface | null;
/** /**
@ -195,9 +190,32 @@ export interface CanvasKit {
* @param colorSpace * @param colorSpace
*/ */
MakeOnScreenGLSurface(ctx: GrContext, width: number, height: number, MakeOnScreenGLSurface(ctx: GrContext, width: number, height: number,
colorSpace: SkColorSpace): SkSurface | null; colorSpace: ColorSpace): SkSurface | null;
readonly SkColorSpace: SkColorSpaceFactory; /**
* Returns the underlying data from SkData as a Uint8Array.
* @param data
*/
getSkDataBytes(data: SkData): Uint8Array;
readonly AlphaType: AlphaTypeEnumValues;
readonly BlendMode: BlendModeEnumValues;
readonly ClipOp: ClipOpEnumValues;
readonly ColorType: ColorTypeEnumValues;
readonly ImageFormat: ImageFormatEnumValues;
readonly PointMode: PointModeEnumValues;
readonly SkColorSpace: ColorSpaceEnumValues;
readonly TileMode: TileModeEnumValues;
readonly TRANSPARENT: SkColor;
readonly BLACK: SkColor;
readonly WHITE: SkColor;
readonly RED: SkColor;
readonly GREEN: SkColor;
readonly BLUE: SkColor;
readonly YELLOW: SkColor;
readonly CYAN: SkColor;
readonly MAGENTA: SkColor;
} }
/** /**
@ -270,28 +288,453 @@ export interface MallocObj {
toTypedArray: () => TypedArray; toTypedArray: () => TypedArray;
} }
/**
* See Paragraph.h for more information on this class. This is only available if Paragraph has
* been compiled in.
*/
export interface Paragraph extends EmbindObject<SkAnimatedImage> {
todo: number; // TODO(kjlubick)
}
/**
* A simple wrapper around SkTextBlob and the simple Text Shaper.
*/
export interface ShapedText extends EmbindObject<SkAnimatedImage> {
/**
* Return the bounding area for the given text.
* @param outputArray - if provided, the bounding box will be copied into this array instead of
* allocating a new one.
*/
getBounds(outputArray?: SkRect): SkRect;
}
/**
* See SkAnimatedImage.h for more information on this class.
*/
export interface SkAnimatedImage extends EmbindObject<SkAnimatedImage> {
todo: number; // TODO(kjlubick)
}
/** /**
* See SkCanvas.h for more information on this class. * See SkCanvas.h for more information on this class.
*/ */
export interface SkCanvas extends EmbindObject<SkCanvas> { export interface SkCanvas extends EmbindObject<SkCanvas> {
// TODO(kjlubick) Fill out the rest
/** /**
* Fills the current clip with the given color using Src BlendMode. * Fills the current clip with the given color using Src BlendMode.
* This has the effect of replacing all pixels contained by clip with color. * This has the effect of replacing all pixels contained by clip with color.
* @param color * @param color
*/ */
clear(color: SkColor): void; clear(color: InputColor): void;
}
export type SkColorSpace = EmbindSingleton; /**
* Replaces clip with the intersection or difference of the current clip and path,
* with an aliased or anti-aliased clip edge.
* @param path
* @param op
* @param doAntiAlias
*/
clipPath(path: SkPath, op: ClipOp, doAntiAlias: boolean): void;
/** /**
* The currently supported color spaces. These are all singleton values. * Replaces clip with the intersection or difference of the current clip and rect,
*/ * with an aliased or anti-aliased clip edge.
export interface SkColorSpaceFactory { * @param rect
readonly SRGB: SkColorSpace; * @param op
readonly DISPLAY_P3: SkColorSpace; * @param doAntiAlias
readonly ADOBE_RGB: SkColorSpace; */
clipRect(rect: InputRect, op: ClipOp, doAntiAlias: boolean): void;
/**
* Replaces clip with the intersection or difference of the current clip and rrect,
* with an aliased or anti-aliased clip edge.
* @param rrect
* @param op
* @param doAntiAlias
*/
clipRRect(rrect: InputRRect, op: ClipOp, doAntiAlias: boolean): void;
/**
* Replaces current matrix with m premultiplied with the existing matrix.
* @param m
*/
concat(m: InputMatrix): void;
/**
* Draws arc using clip, SkMatrix, and SkPaint paint.
*
* Arc is part of oval bounded by oval, sweeping from startAngle to startAngle plus
* sweepAngle. startAngle and sweepAngle are in degrees.
* @param oval - bounds of oval containing arc to draw
* @param startAngle - angle in degrees where arc begins
* @param sweepAngle - sweep angle in degrees; positive is clockwise
* @param useCenter - if true, include the center of the oval
* @param paint
*/
drawArc(oval: InputRect, startAngle: angleInDegrees, sweepAngle: angleInDegrees,
useCenter: boolean, paint: SkPaint): void;
/**
* Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
* @param atlas - SkImage containing sprites
* @param srcRects - SkRect locations of sprites in atlas
* @param dstXforms - SkRSXform mappings for sprites in atlas
* @param paint
* @param blendMode - BlendMode combining colors and sprites
* @param colors - If provided, will be blended with sprite using blendMode.
*/
drawAtlas(atlas: SkImage, srcRects: FlattenedRectangleArray,
dstXforms: FlattenedRSXFormArray, paint: SkPaint,
blendMode?: BlendMode, colors?: ColorIntArray): void;
/**
* Draws a circle at (cx, cy) with the given radius.
* @param cx
* @param cy
* @param radius
* @param paint
*/
drawCircle(cx: number, cy: number, radius: number, paint: SkPaint): void;
/**
* Fills clip with the given color.
* @param color
* @param blendMode - defaults to SrcOver.
*/
drawColor(color: InputColor, blendMode?: BlendMode): void;
/**
* Fills clip with the given color.
* @param r - red value (typically from 0 to 1.0).
* @param g - green value (typically from 0 to 1.0).
* @param b - blue value (typically from 0 to 1.0).
* @param a - alpha value, range 0 to 1.0 (1.0 is opaque).
* @param blendMode - defaults to SrcOver.
*/
drawColorComponents(r: number, g: number, b: number, a: number, blendMode?: BlendMode): void;
/**
* Fills clip with the given color.
* @param color
* @param blendMode - defaults to SrcOver.
*/
drawColorInt(color: SkColorInt, blendMode?: BlendMode): void;
/**
* Draws SkRRect outer and inner using clip, SkMatrix, and SkPaint paint.
* outer must contain inner or the drawing is undefined.
* @param outer
* @param inner
* @param paint
*/
drawDRRect(outer: InputRRect, inner: InputRRect, paint: SkPaint): void;
/**
* Draws the given image with its top-left corner at (left, top) using the current clip,
* the current matrix, and optionally-provided paint.
* @param img
* @param left
* @param top
* @param paint
*/
drawImage(img: SkImage, left: number, top: number, paint?: SkPaint): void;
/**
* Draws the current frame of the given animated image with its top-left corner at
* (left, top) using the current clip, the current matrix, and optionally-provided paint.
* @param aImg
* @param left
* @param top
* @param paint
*/
drawImageAtCurrentFrame(aImg: SkAnimatedImage, left: number, top: number,
paint?: SkPaint): void;
/**
* Draws the provided image stretched proportionally to fit into dst rectangle.
* The center rectangle divides the image into nine sections: four sides, four corners, and
* the center.
* @param img
* @param center
* @param dest
* @param paint
*/
drawImageNine(img: SkImage, center: InputIRect, dest: InputRect, paint: SkPaint): void;
/**
* Draws sub-rectangle src from provided image, scaled and translated to fill dst rectangle.
* @param img
* @param src
* @param dest
* @param paint
* @param fastSample - if false, will filter strictly within src.
*/
drawImageRect(img: SkImage, src: InputRect, dest: InputRect, paint: SkPaint,
fastSample?: boolean): void;
/**
* Draws line segment from (x0, y0) to (x1, y1) using the current clip, current matrix,
* and the provided paint.
* @param x0
* @param y0
* @param x1
* @param y1
* @param paint
*/
drawLine(x0: number, y0: number, x1: number, y1: number, paint: SkPaint): void;
/**
* Draws an oval bounded by the given rectangle using the current clip, current matrix,
* and the provided paint.
* @param oval
* @param paint
*/
drawOval(oval: InputRect, paint: SkPaint): void;
/**
* Fills clip with the given paint.
* @param paint
*/
drawPaint(paint: SkPaint): void;
/**
* Draws the given Paragraph at the provided coordinates.
* Requires the Paragraph code to be compiled in.
* @param p
* @param x
* @param y
*/
drawParagraph(p: Paragraph, x: number, y: number): void;
/**
* Draws the given path using the current clip, current matrix, and the provided paint.
* @param path
* @param paint
*/
drawPath(path: SkPath, paint: SkPaint): void;
/**
* Draws the given picture using the current clip, current matrix, and the provided paint.
* @param skp
*/
drawPicture(skp: SkPicture): void;
/**
* Draws the given points using the current clip, current matrix, and the provided paint.
*
* See SkCanvas.h for more on the mode and its interaction with paint.
* @param mode
* @param points
* @param paint
*/
drawPoints(mode: PointMode, points: FlattenedPointArray, paint: SkPaint): void;
/**
* Draws the given rectangle using the current clip, current matrix, and the provided paint.
* @param rect
* @param paint
*/
drawRect(rect: InputRect, paint: SkPaint): void;
/**
* Draws the given rectangle using the current clip, current matrix, and the provided paint.
* @param left
* @param top
* @param right
* @param bottom
* @param paint
*/
drawRect4f(left: number, top: number, right: number, bottom: number, paint: SkPaint): void;
/**
* Draws the given rectangle with rounded corners using the current clip, current matrix,
* and the provided paint.
* @param rrect
* @param paint
*/
drawRRect(rrect: InputRRect, paint: SkPaint): void;
/**
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
* light. See SkShadowUtils.h for more details
* @param path - The occluder used to generate the shadows.
* @param zPlaneParams - Values for the plane function which returns the Z offset of the
* occluder from the canvas based on local x and y values (the current
* matrix is not applied).
* @param lightPos - The 3D position of the light relative to the canvas plane. This is
* independent of the canvas's current matrix.
* @param lightRadius - The radius of the disc light.
* @param ambientColor - The color of the ambient shadow.
* @param spotColor - The color of the spot shadow.
* @param flags - See SkShadowFlags.h; 0 means use default options.
*/
drawShadow(path: SkPath, zPlaneParams: Point3, lightPos: Point3, lightRadius: number,
ambientColor: InputColor, spotColor: InputColor, flags: number): void;
/**
* Draw the given text at the location (x, y) using the provided paint and font. If non-shaped
* text is provided, the text will be drawn as is; no line-breaking, no ligatures, etc.
* @param str - either a string or pre-shaped text. Unicode text is supported.
* @param x
* @param y
* @param paint
* @param font
*/
drawText(str: string | ShapedText, x: number, y: number, paint: SkPaint, font: SkFont): void;
/**
* Draws the given TextBlob at (x, y) using the current clip, current matrix, and the
* provided paint. Reminder that the fonts used to draw TextBlob are part of the blob.
* @param blob
* @param x
* @param y
* @param paint
*/
drawTextBlob(blob: SkTextBlob, x: number, y: number, paint: SkPaint): void;
/**
* Draws the given vertices (a triangle mesh) using the current clip, current matrix, and the
* provided paint.
* If paint contains an SkShader and vertices does not contain texCoords, the shader
* is mapped using the vertices' positions.
* If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
* SkBlendMode mode combines vertices colors with SkShader.
* @param verts
* @param mode
* @param paint
*/
drawVertices(verts: SkVertices, mode: BlendMode, paint: SkPaint): void;
/**
* Returns the 4x4 matrix matching the given marker or null if there was none.
* See also markCTM.
* @param marker
*/
findMarkedCTM(marker: string): Matrix4x4 | null;
/**
* Returns the current transform from local coordinates to the 'device', which for most
* purposes means pixels.
*/
getLocalToDevice(): Matrix4x4;
/**
* Returns the number of saved states, each containing: SkMatrix and clip.
* Equals the number of save() calls less the number of restore() calls plus one.
* The save count of a new canvas is one.
*/
getSaveCount(): number;
/**
* Legacy version of getLocalToDevice(), which strips away any Z information, and
* just returns a 3x3 version.
*/
getTotalMatrix(): Matrix3x3;
/**
* Creates SkSurface matching info and props, and associates it with SkCanvas.
* Returns null if no match found.
* @param info
*/
makeSurface(info: SkImageInfo): SkSurface | null;
/**
* Record a marker (provided by caller) for the current CTM. This does not change anything
* about the ctm or clip, but does "name" this matrix value, so it can be referenced by
* custom effects (who access it by specifying the same name).
* See also findMarkedCTM.
* @param marker
*/
markCTM(marker: string): void;
/**
* Copies the given rectangle of pixels into a new Uint8Array and returns it. If alphaType,
* colorType, and colorSpace are provided, those will describe the output format.
* @param x
* @param y
* @param w
* @param h
* @param alphaType - defaults to Unpremul
* @param colorType - defaults to RGBA_8888
* @param colorSpace - defaults to SRGB
* @param dstRowBytes
*/
readPixels(x: number, y: number, w: number, h: number, alphaType?: AlphaType,
colorType?: ColorType, colorSpace?: ColorSpace, dstRowBytes?: number): Uint8Array;
/**
* Removes changes to the current matrix and clip since SkCanvas state was
* last saved. The state is removed from the stack.
* Does nothing if the stack is empty.
*/
restore(): void;
/**
* Restores state to a previous stack value.
* @param saveCount
*/
restoreToCount(saveCount: number): void;
/**
* Rotates the current matrix by the number of degrees.
* @param rot - angle of rotation in degrees.
* @param rx
* @param ry
*/
rotate(rot: angleInDegrees, rx: number, ry: number): void;
/**
* Saves the current matrix and clip and returns current height of the stack.
*/
save(): number;
/**
* Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
* Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.
* It returns the height of the stack.
* See SkCanvas.h for more.
* @param paint
* @param bounds
*/
saveLayer(paint?: SkPaint, bounds?: InputRect): number;
/**
* Scales the current matrix by sx on the x-axis and sy on the y-axis.
* @param sx
* @param sy
*/
scale(sx: number, sy: number): void;
/**
* Skews SkMatrix by sx on the x-axis and sy on the y-axis. A positive value of sx
* skews the drawing right as y-axis values increase; a positive value of sy skews
* the drawing down as x-axis values increase.
* @param sx
* @param sy
*/
skew(sx: number, sy: number): void;
/**
* Translates SkMatrix by dx along the x-axis and dy along the y-axis.
* @param dx
* @param dy
*/
translate(dx: number, dy: number): void;
/**
* Writes the given rectangle of pixels to the provided coordinates. The source pixels
* will be converted to the canvas's alphaType and colorType if they do not match.
* @param pixels
* @param srcWidth
* @param srcHeight
* @param destX
* @param destY
* @param alphaType - defaults to Unpremul
* @param colorType - defaults to RGBA_8888
* @param colorSpace - defaults to SRGB
*/
writePixels(pixels: Uint8Array | number[], srcWidth: number, srcHeight: number,
destX: number, destY: number, alphaType?: AlphaType, colorType?: ColorType,
colorSpace?: ColorSpace): boolean;
} }
/** /**
@ -303,27 +746,88 @@ export interface SkData extends EmbindObject<SkImage> {
*/ */
size(): number; size(): number;
} }
/**
* See SkFont.h for more on this class.
*/
export interface SkFont extends EmbindObject<SkImage> {
todo: number; // TODO(kjlubick)
}
/** /**
* See SkImage.h for more information on this class. * See SkImage.h for more information on this class.
*/ */
export interface SkImage extends EmbindObject<SkImage> { export interface SkImage extends EmbindObject<SkImage> {
// TODO(kjlubick) /**
* Encodes this image's pixels to PNG and returns them. Must be built with the PNG codec.
*/
encodeToData(): SkData;
/**
* Encodes this image's pixels to the specified format and returns them. Must be built with
* the specified codec.
* @param fmt
* @param quality - a value from 0 to 100; 100 is the least lossy. May be ignored.
*/
encodeToDataWithFormat(fmt: EncodedImageFormat, quality: number): SkData;
/** /**
* Return the height in pixels of the image. * Return the height in pixels of the image.
*/ */
height(): number; height(): number;
/**
* Returns this image as a shader with the specified tiling.
* @param tx - tile mode in the x direction.
* @param ty - tile mode in the y direction.
* @param localMatrix
*/
makeShader(tx: TileMode, ty: TileMode, localMatrix?: InputMatrix): SkShader;
/**
* Returns a TypedArray containing the pixels reading starting at (srcX, srcY) and does not
* exceed the size indicated by imageInfo. See SkImage.h for more on the caveats.
*
* @param imageInfo - describes the destination format of the pixels.
* @param srcX
* @param srcY
* @returns a Uint8Array if RGB_8888 was requested, Float32Array if RGBA_F32 was requested.
*/
readPixels(imageInfo: SkImageInfo, srcX: number, srcY: number): Uint8Array | Float32Array | null;
/**
* Return the width in pixels of the image.
*/
width(): number;
} }
export interface SkImageInfo { export interface SkImageInfo {
alphaType: SkAlphaType; alphaType: AlphaType;
colorSpace: SkColorSpace; colorSpace: ColorSpace;
colorType: SkColorType; colorType: ColorType;
height: number; height: number;
width: number; width: number;
} }
/**
* See SkPaint.h for more information on this class.
*/
export interface SkPaint extends EmbindObject<SkPaint> {
todo: number; // TODO(kjlubick)
}
/**
* See SkPath.h for more information on this class.
*/
export interface SkPath extends EmbindObject<SkPath> {
todo: number; // TODO(kjlubick)
}
/** /**
* See SkPicture.h for more information on this class. * See SkPicture.h for more information on this class.
*
* Of note, SkPicture is *not* what is colloquially thought of as a "picture" (what we
* call a bitmap). An SkPicture is a series of draw commands.
*/ */
export interface SkPicture extends EmbindObject<SkPicture> { export interface SkPicture extends EmbindObject<SkPicture> {
/** /**
@ -333,6 +837,10 @@ export interface SkPicture extends EmbindObject<SkPicture> {
serialize(): SkData; serialize(): SkData;
} }
export interface SkShader extends EmbindObject<SkShader> {
todo: number; // TODO(kjlubick)
}
export interface SkSurface extends EmbindObject<SkSurface> { export interface SkSurface extends EmbindObject<SkSurface> {
/** /**
* Call the given callback and save the result of that draw to a SkPicture with the * Call the given callback and save the result of that draw to a SkPicture with the
@ -399,6 +907,20 @@ export interface SkSurface extends EmbindObject<SkSurface> {
width(): number; width(): number;
} }
/**
* See SkTextBlob.h for more on this class.
*/
export interface SkTextBlob extends EmbindObject<SkImage> {
todo: number; // TODO(kjlubick)
}
/**
* See SkVertices.h for more on this class.
*/
export interface SkVertices extends EmbindObject<SkImage> {
todo: number; // TODO(kjlubick)
}
/** /**
* Options for configuring a WebGL context. If an option is omitted, a sensible default will * Options for configuring a WebGL context. If an option is omitted, a sensible default will
* be used. These are defined by the WebGL standards. * be used. These are defined by the WebGL standards.
@ -441,13 +963,151 @@ export type SkRect = Float32Array;
* upper-right, lower-right, lower-left. See SkRRect.h for more. * upper-right, lower-right, lower-left. See SkRRect.h for more.
*/ */
export type SkRRect = Float32Array; export type SkRRect = Float32Array;
export type WebGLContextHandle = number; export type WebGLContextHandle = number;
export type angleInDegrees = number;
export type TypedArrayConstructor = Float32ArrayConstructor | Int32ArrayConstructor | export type TypedArrayConstructor = Float32ArrayConstructor | Int32ArrayConstructor |
Int16ArrayConstructor | Int8ArrayConstructor | Uint32ArrayConstructor | Int16ArrayConstructor | Int8ArrayConstructor | Uint32ArrayConstructor |
Uint16ArrayConstructor | Uint8ArrayConstructor; Uint16ArrayConstructor | Uint8ArrayConstructor;
export type TypedArray = Float32Array | Int32Array | Int16Array | Int8Array | Uint32Array | export type TypedArray = Float32Array | Int32Array | Int16Array | Int8Array | Uint32Array |
Uint16Array | Uint8Array; Uint16Array | Uint8Array;
/**
* FlattenedPointArray represents n points by 2*n float values. In order, the values should
* be the x, y for each point.
*/
export type FlattenedPointArray = MallocObj | Float32Array | number[];
/**
* FlattenedRectangleArray represents n rectangles by 4*n float values. In order, the values should
* be the top, left, right, bottom point for each rectangle.
*/
export type FlattenedRectangleArray = MallocObj | Float32Array | number[];
/**
* FlattenedRSXFormArray represents n RSXforms by 4*n float values. In order, the values should
* be scos, ssin, tx, ty for each RSXForm. See RSXForm.h for more details.
*/
export type FlattenedRSXFormArray = MallocObj | Float32Array | number[];
export type ColorIntArray = MallocObj | Uint32Array | number[];
export type SkAlphaType = EmbindEnumEntity; export type Matrix4x4 = Float32Array;
export type SkColorType = EmbindEnumEntity; export type Matrix3x3 = Float32Array;
export type Matrix3x2 = Float32Array;
/**
* Point3 represents an x, y, coordinate.
*/
export type Point3 = number[]; // TODO(kjlubick) make this include typed array and malloc'd.
/**
* CanvasKit APIs accept normal arrays, typed arrays, or Malloc'd memory as colors.
*/
export type InputColor = MallocObj | SkColor | number[];
/**
* CanvasKit APIs accept all of these matrix types. Under the hood, we generally use 4x4 matrices.
*/
export type InputMatrix = MallocObj | Matrix4x4 | Matrix3x3 | Matrix3x2 | DOMMatrix | number[];
/**
* CanvasKit APIs accept normal arrays, typed arrays, or Malloc'd memory as rectangles.
*/
export type InputRect = MallocObj | SkRect | number[];
/**
* CanvasKit APIs accept normal arrays, typed arrays, or Malloc'd memory as rectangles.
*/
export type InputIRect = MallocObj | SkRect | number[];
/**
* CanvasKit APIs accept normal arrays, typed arrays, or Malloc'd memory as rectangles with
* rounded corners.
*/
export type InputRRect = MallocObj | SkRRect | number[];
export type AlphaType = EmbindEnumEntity;
export type BlendMode = EmbindEnumEntity;
export type ClipOp = EmbindEnumEntity;
export type ColorSpace = EmbindSingleton;
export type ColorType = EmbindEnumEntity;
export type EncodedImageFormat = EmbindEnumEntity;
export type PointMode = EmbindEnumEntity;
export type TileMode = EmbindEnumEntity;
export interface AlphaTypeEnumValues extends EmbindEnum {
Opaque: AlphaType;
Premul: AlphaType;
Unpremul: AlphaType;
}
export interface BlendModeEnumValues extends EmbindEnum {
Clear: BlendMode;
Src: BlendMode;
Dst: BlendMode;
SrcOver: BlendMode;
DstOver: BlendMode;
SrcIn: BlendMode;
DstIn: BlendMode;
SrcOut: BlendMode;
DstOut: BlendMode;
SrcATop: BlendMode;
DstATop: BlendMode;
Xor: BlendMode;
Plus: BlendMode;
Modulate: BlendMode;
Screen: BlendMode;
Overlay: BlendMode;
Darken: BlendMode;
Lighten: BlendMode;
ColorDodge: BlendMode;
ColorBurn: BlendMode;
HardLight: BlendMode;
SoftLight: BlendMode;
Difference: BlendMode;
Exclusion: BlendMode;
Multiply: BlendMode;
Hue: BlendMode;
Saturation: BlendMode;
Color: BlendMode;
Luminosity: BlendMode;
}
export interface ClipOpEnumValues extends EmbindEnum {
Difference: ClipOp;
Intersect: ClipOp;
}
/**
* The currently supported color spaces. These are all singleton values.
*/
export interface ColorSpaceEnumValues { // not a typical enum, but effectively like one.
readonly SRGB: ColorSpace;
readonly DISPLAY_P3: ColorSpace;
readonly ADOBE_RGB: ColorSpace;
}
export interface ColorTypeEnumValues extends EmbindEnum {
Alpha_8: ColorType;
RGB_565: ColorType;
RGBA_8888: ColorType;
BGRA_8888: ColorType;
RGBA_1010102: ColorType;
RGB_101010x: ColorType;
Gray_8: ColorType;
RGBA_F16: ColorType;
RGBA_F32: ColorType;
}
export interface ImageFormatEnumValues extends EmbindEnum {
// TODO(kjlubick) When these are compiled in depending on the availability of the codecs,
PNG: EncodedImageFormat;
JPEG: EncodedImageFormat;
WEBP: EncodedImageFormat;
}
export interface PointModeEnumValues extends EmbindEnum {
Points: PointMode;
Lines: PointMode;
Polygon: PointMode;
}
export interface TileModeEnumValues extends EmbindEnum {
Clamp: TileMode;
Decal: TileMode;
Mirror: TileMode;
Repeat: TileMode;
}

View File

@ -1085,7 +1085,30 @@ EMSCRIPTEN_BINDINGS(Skia) {
.function("drawTextBlob", select_overload<void (const sk_sp<SkTextBlob>&, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawTextBlob)) .function("drawTextBlob", select_overload<void (const sk_sp<SkTextBlob>&, SkScalar, SkScalar, const SkPaint&)>(&SkCanvas::drawTextBlob))
#endif #endif
.function("drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices)) .function("drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices))
.function("flush", &SkCanvas::flush) .function("_findMarkedCTM", optional_override([](SkCanvas& self, std::string marker, uintptr_t /* SkScalar* */ mPtr) -> bool {
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
if (!sixteenMatrixValues) {
return false; // matrix cannot be null
}
SkM44 m;
if (self.findMarkedCTM(marker.c_str(), &m)) {
m.getRowMajor(sixteenMatrixValues);
return true;
}
return false;
}))
.function("flush", &SkCanvas::flush) // Deprecated - will be removed
// 4x4 matrix functions
// Just like with getTotalMatrix, we allocate the buffer for the 16 floats to go in from
// interface.js, so it can also free them when its done.
.function("_getLocalToDevice", optional_override([](const SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
if (!sixteenMatrixValues) {
return; // matrix cannot be null
}
SkM44 m = self.getLocalToDevice();
m.getRowMajor(sixteenMatrixValues);
}))
.function("getSaveCount", &SkCanvas::getSaveCount) .function("getSaveCount", &SkCanvas::getSaveCount)
// We allocate room for the matrix from the JS side and free it there so as to not have // We allocate room for the matrix from the JS side and free it there so as to not have
// an awkward moment where we malloc something here and "just know" to free it on the // an awkward moment where we malloc something here and "just know" to free it on the
@ -1104,18 +1127,7 @@ EMSCRIPTEN_BINDINGS(Skia) {
.function("markCTM", optional_override([](SkCanvas& self, std::string marker) { .function("markCTM", optional_override([](SkCanvas& self, std::string marker) {
self.markCTM(marker.c_str()); self.markCTM(marker.c_str());
})) }))
.function("_findMarkedCTM", optional_override([](SkCanvas& self, std::string marker, uintptr_t /* SkScalar* */ mPtr) -> bool {
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
if (!sixteenMatrixValues) {
return false; // matrix cannot be null
}
SkM44 m;
if (self.findMarkedCTM(marker.c_str(), &m)) {
m.getRowMajor(sixteenMatrixValues);
return true;
}
return false;
}))
.function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di, .function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
uintptr_t /* uint8_t* */ pPtr, uintptr_t /* uint8_t* */ pPtr,
size_t dstRowBytes, int srcX, int srcY) { size_t dstRowBytes, int srcX, int srcY) {
@ -1143,17 +1155,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
SkImageInfo dstInfo = toSkImageInfo(di); SkImageInfo dstInfo = toSkImageInfo(di);
return self.writePixels(dstInfo, pixels, srcRowBytes, dstX, dstY); return self.writePixels(dstInfo, pixels, srcRowBytes, dstX, dstY);
}))
// 4x4 matrix functions
// Just like with getTotalMatrix, we allocate the buffer for the 16 floats to go in from
// interface.js, so it can also free them when its done.
.function("_getLocalToDevice", optional_override([](const SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
if (!sixteenMatrixValues) {
return; // matrix cannot be null
}
SkM44 m = self.getLocalToDevice();
m.getRowMajor(sixteenMatrixValues);
})); }));
class_<SkColorFilter>("SkColorFilter") class_<SkColorFilter>("SkColorFilter")

View File

@ -560,6 +560,8 @@ function saveBytesToFile(bytes, fileName) {
}); });
} }
} }
// TODO(kjlubick) remove Builders - no longer needed now that Malloc is a thing.
/** /**
* Generic helper for dealing with an array of four floats. * Generic helper for dealing with an array of four floats.
*/ */

View File

@ -998,6 +998,7 @@ CanvasKit.onRuntimeInitialized = function() {
// colors are optional and used to tint the drawn images using the optional blend mode // colors are optional and used to tint the drawn images using the optional blend mode
// Colors may be an SkColorBuilder, a Uint32Array of int colors, // Colors may be an SkColorBuilder, a Uint32Array of int colors,
// a Flat Float32Array of float colors or a 2d Array of Float32Array(4) (deprecated) // a Flat Float32Array of float colors or a 2d Array of Float32Array(4) (deprecated)
// TODO(kjlubick) remove Builders - no longer needed now that Malloc is a thing.
CanvasKit.SkCanvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint, CanvasKit.SkCanvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint,
/*optional*/ blendMode, colors) { /*optional*/ blendMode, colors) {
if (!atlas || !paint || !srcRects || !dstXforms) { if (!atlas || !paint || !srcRects || !dstXforms) {