blob: 9a8da8ad06b6ecf12d6cf16389ca30331c992dc6 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "export.h"
#include "helpers.h"
#include "wrappers.h"
#include "third_party/skia/include/core/SkPoint3.h"
#include "third_party/skia/include/core/SkVertices.h"
#include "third_party/skia/include/utils/SkShadowUtils.h"
#include "third_party/skia/modules/skparagraph/include/Paragraph.h"
using namespace skia::textlayout;
using namespace Skwasm;
namespace {
// These numbers have been chosen empirically to give a result closest to the
// material spec.
// These values are also used by the CanvasKit renderer and the native engine.
// See:
// flutter/display_list/skia/dl_sk_dispatcher.cc
// flutter/lib/web_ui/lib/src/engine/canvaskit/util.dart
constexpr SkScalar kShadowAmbientAlpha = 0.039;
constexpr SkScalar kShadowSpotAlpha = 0.25;
constexpr SkScalar kShadowLightRadius = 1.1;
constexpr SkScalar kShadowLightHeight = 600.0;
constexpr SkScalar kShadowLightXOffset = 0;
constexpr SkScalar kShadowLightYOffset = -450;
} // namespace
SKWASM_EXPORT void canvas_saveLayer(SkCanvas* canvas,
SkRect* rect,
SkPaint* paint,
SkImageFilter* backdrop) {
canvas->saveLayer(SkCanvas::SaveLayerRec(rect, paint, backdrop, 0));
}
SKWASM_EXPORT void canvas_save(SkCanvas* canvas) {
canvas->save();
}
SKWASM_EXPORT void canvas_restore(SkCanvas* canvas) {
canvas->restore();
}
SKWASM_EXPORT void canvas_restoreToCount(SkCanvas* canvas, int count) {
canvas->restoreToCount(count);
}
SKWASM_EXPORT int canvas_getSaveCount(SkCanvas* canvas) {
return canvas->getSaveCount();
}
SKWASM_EXPORT void canvas_translate(SkCanvas* canvas,
SkScalar dx,
SkScalar dy) {
canvas->translate(dx, dy);
}
SKWASM_EXPORT void canvas_scale(SkCanvas* canvas, SkScalar sx, SkScalar sy) {
canvas->scale(sx, sy);
}
SKWASM_EXPORT void canvas_rotate(SkCanvas* canvas, SkScalar degrees) {
canvas->rotate(degrees);
}
SKWASM_EXPORT void canvas_skew(SkCanvas* canvas, SkScalar sx, SkScalar sy) {
canvas->skew(sx, sy);
}
SKWASM_EXPORT void canvas_transform(SkCanvas* canvas, const SkM44* matrix44) {
canvas->concat(*matrix44);
}
SKWASM_EXPORT void canvas_clipRect(SkCanvas* canvas,
const SkRect* rect,
SkClipOp op,
bool antialias) {
canvas->clipRect(*rect, op, antialias);
}
SKWASM_EXPORT void canvas_clipRRect(SkCanvas* canvas,
const SkScalar* rrectValues,
bool antialias) {
canvas->clipRRect(createRRect(rrectValues), antialias);
}
SKWASM_EXPORT void canvas_clipPath(SkCanvas* canvas,
SkPath* path,
bool antialias) {
canvas->clipPath(*path, antialias);
}
SKWASM_EXPORT void canvas_drawColor(SkCanvas* canvas,
SkColor color,
SkBlendMode blendMode) {
canvas->drawColor(color, blendMode);
}
SKWASM_EXPORT void canvas_drawLine(SkCanvas* canvas,
SkScalar x1,
SkScalar y1,
SkScalar x2,
SkScalar y2,
SkPaint* paint) {
canvas->drawLine(x1, y1, x2, y2, *paint);
}
SKWASM_EXPORT void canvas_drawPaint(SkCanvas* canvas, SkPaint* paint) {
canvas->drawPaint(*paint);
}
SKWASM_EXPORT void canvas_drawRect(SkCanvas* canvas,
SkRect* rect,
SkPaint* paint) {
canvas->drawRect(*rect, *paint);
}
SKWASM_EXPORT void canvas_drawRRect(SkCanvas* canvas,
const SkScalar* rrectValues,
SkPaint* paint) {
canvas->drawRRect(createRRect(rrectValues), *paint);
}
SKWASM_EXPORT void canvas_drawDRRect(SkCanvas* canvas,
const SkScalar* outerRrectValues,
const SkScalar* innerRrectValues,
SkPaint* paint) {
canvas->drawDRRect(createRRect(outerRrectValues),
createRRect(innerRrectValues), *paint);
}
SKWASM_EXPORT void canvas_drawOval(SkCanvas* canvas,
const SkRect* rect,
SkPaint* paint) {
canvas->drawOval(*rect, *paint);
}
SKWASM_EXPORT void canvas_drawCircle(SkCanvas* canvas,
SkScalar x,
SkScalar y,
SkScalar radius,
SkPaint* paint) {
canvas->drawCircle(x, y, radius, *paint);
}
SKWASM_EXPORT void canvas_drawArc(SkCanvas* canvas,
const SkRect* rect,
SkScalar startAngleDegrees,
SkScalar sweepAngleDegrees,
bool useCenter,
SkPaint* paint) {
canvas->drawArc(*rect, startAngleDegrees, sweepAngleDegrees, useCenter,
*paint);
}
SKWASM_EXPORT void canvas_drawPath(SkCanvas* canvas,
SkPath* path,
SkPaint* paint) {
canvas->drawPath(*path, *paint);
}
SKWASM_EXPORT void canvas_drawShadow(SkCanvas* canvas,
SkPath* path,
SkScalar elevation,
SkScalar devicePixelRatio,
SkColor color,
bool transparentOccluder) {
SkColor inAmbient =
SkColorSetA(color, kShadowAmbientAlpha * SkColorGetA(color));
SkColor inSpot = SkColorSetA(color, kShadowSpotAlpha * SkColorGetA(color));
SkColor outAmbient;
SkColor outSpot;
SkShadowUtils::ComputeTonalColors(inAmbient, inSpot, &outAmbient, &outSpot);
uint32_t flags = transparentOccluder
? SkShadowFlags::kTransparentOccluder_ShadowFlag
: SkShadowFlags::kNone_ShadowFlag;
flags |= SkShadowFlags::kDirectionalLight_ShadowFlag;
SkShadowUtils::DrawShadow(
canvas, *path, SkPoint3::Make(0.0f, 0.0f, elevation * devicePixelRatio),
SkPoint3::Make(kShadowLightXOffset, kShadowLightYOffset,
kShadowLightHeight * devicePixelRatio),
devicePixelRatio * kShadowLightRadius, outAmbient, outSpot, flags);
}
SKWASM_EXPORT void canvas_drawParagraph(SkCanvas* canvas,
Paragraph* paragraph,
SkScalar x,
SkScalar y) {
paragraph->paint(canvas, x, y);
}
SKWASM_EXPORT void canvas_drawPicture(SkCanvas* canvas, SkPicture* picture) {
canvas->drawPicture(picture);
}
SKWASM_EXPORT void canvas_drawImage(SkCanvas* canvas,
SkImage* image,
SkScalar offsetX,
SkScalar offsetY,
SkPaint* paint,
FilterQuality quality) {
canvas->drawImage(image, offsetX, offsetY, samplingOptionsForQuality(quality),
paint);
}
SKWASM_EXPORT void canvas_drawImageRect(SkCanvas* canvas,
SkImage* image,
SkRect* sourceRect,
SkRect* destRect,
SkPaint* paint,
FilterQuality quality) {
canvas->drawImageRect(image, *sourceRect, *destRect,
samplingOptionsForQuality(quality), paint,
SkCanvas::kStrict_SrcRectConstraint);
}
SKWASM_EXPORT void canvas_drawImageNine(SkCanvas* canvas,
SkImage* image,
SkIRect* centerRect,
SkRect* destinationRect,
SkPaint* paint,
FilterQuality quality) {
canvas->drawImageNine(image, *centerRect, *destinationRect,
filterModeForQuality(quality), paint);
}
SKWASM_EXPORT void canvas_drawVertices(SkCanvas* canvas,
SkVertices* vertices,
SkBlendMode mode,
SkPaint* paint) {
canvas->drawVertices(sk_ref_sp<SkVertices>(vertices), mode, *paint);
}
SKWASM_EXPORT void canvas_drawPoints(SkCanvas* canvas,
SkCanvas::PointMode mode,
SkPoint* points,
int pointCount,
SkPaint* paint) {
canvas->drawPoints(mode, pointCount, points, *paint);
}
SKWASM_EXPORT void canvas_drawAtlas(SkCanvas* canvas,
SkImage* atlas,
SkRSXform* transforms,
SkRect* rects,
SkColor* colors,
int spriteCount,
SkBlendMode mode,
SkRect* cullRect,
SkPaint* paint) {
canvas->drawAtlas(
atlas, transforms, rects, colors, spriteCount, mode,
SkSamplingOptions{SkFilterMode::kLinear, SkMipmapMode::kNone}, cullRect,
paint);
}
SKWASM_EXPORT void canvas_getTransform(SkCanvas* canvas, SkM44* outTransform) {
*outTransform = canvas->getLocalToDevice();
}
SKWASM_EXPORT void canvas_getLocalClipBounds(SkCanvas* canvas,
SkRect* outRect) {
*outRect = canvas->getLocalClipBounds();
}
SKWASM_EXPORT void canvas_getDeviceClipBounds(SkCanvas* canvas,
SkIRect* outRect) {
*outRect = canvas->getDeviceClipBounds();
}