From 2ea18a5e7675a96c318b3d3a9048e9d6682fbbc8 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Fri, 25 Oct 2019 14:30:38 -0700 Subject: [PATCH] Expand on CanvasKit backend more (#13361) - add Path.addPath - add Path.conicTo - add Path.transform - use Skia's computeTonalColors to compute shadow colors --- .../lib/src/engine/compositor/path.dart | 62 +++++++++++++++---- .../engine/compositor/recording_canvas.dart | 4 +- .../lib/src/engine/compositor/util.dart | 42 ++++--------- 3 files changed, 65 insertions(+), 43 deletions(-) diff --git a/lib/web_ui/lib/src/engine/compositor/path.dart b/lib/web_ui/lib/src/engine/compositor/path.dart index 72418fd2a..43932a0fd 100644 --- a/lib/web_ui/lib/src/engine/compositor/path.dart +++ b/lib/web_ui/lib/src/engine/compositor/path.dart @@ -41,17 +41,43 @@ class SkPath implements ui.Path { @override void addArc(ui.Rect oval, double startAngle, double sweepAngle) { - throw 'addArc'; + _skPath.callMethod('addArc', [ + makeSkRect(oval), + startAngle, + sweepAngle, + ]); } @override void addOval(ui.Rect oval) { - _skPath.callMethod('addOval', [makeSkRect(oval)]); + _skPath.callMethod('addOval', [makeSkRect(oval), true, 0]); } @override void addPath(ui.Path path, ui.Offset offset, {Float64List matrix4}) { - throw 'addPath'; + List skMatrix; + if (matrix4 == null) { + skMatrix = makeSkMatrix( + Matrix4.translationValues(offset.dx, offset.dy, 0.0).storage); + } else { + skMatrix = makeSkMatrix(matrix4); + skMatrix[2] += offset.dx; + skMatrix[5] += offset.dy; + } + final SkPath otherPath = path; + _skPath.callMethod('addPath', [ + otherPath._skPath, + skMatrix[0], + skMatrix[1], + skMatrix[2], + skMatrix[3], + skMatrix[4], + skMatrix[5], + skMatrix[6], + skMatrix[7], + skMatrix[8], + false, + ]); } @override @@ -135,7 +161,7 @@ class SkPath implements ui.Path { @override void conicTo(double x1, double y1, double x2, double y2, double w) { - throw 'conicTo'; + _skPath.callMethod('conicTo', [x1, y1, x2, y2, w]); } @override @@ -249,25 +275,39 @@ class SkPath implements ui.Path { } @override - List get subpaths => throw 'subpaths'; + List get subpaths { + throw UnimplementedError( + 'Path.subpaths is not supported in the CanvasKit backend.'); + } @override ui.Path transform(Float64List matrix4) { - throw 'transform'; + final js.JsObject newPath = _skPath.callMethod('copy'); + newPath.callMethod('transform', [makeSkMatrix(matrix4)]); + return SkPath._fromSkPath(newPath); } - // TODO(het): Remove these. @override - Ellipse get webOnlyPathAsCircle => null; + Ellipse get webOnlyPathAsCircle { + throw new UnimplementedError( + 'webOnlyPathAsCircle is not used in the CanvasKit backend.'); + } @override - ui.Rect get webOnlyPathAsRect => null; + ui.Rect get webOnlyPathAsRect { + throw new UnimplementedError( + 'webOnlyPathAsRect is not used in the CanvasKit backend.'); + } @override - ui.RRect get webOnlyPathAsRoundedRect => null; + ui.RRect get webOnlyPathAsRoundedRect { + throw new UnimplementedError( + 'webOnlyPathAsRoundedRect is not used in the CanvasKit backend.'); + } @override List webOnlySerializeToCssPaint() { - return null; + throw new UnimplementedError( + 'webOnlySerializeToCssPaint is not used in the CanvasKit backend.'); } } diff --git a/lib/web_ui/lib/src/engine/compositor/recording_canvas.dart b/lib/web_ui/lib/src/engine/compositor/recording_canvas.dart index 53698b527..e6ab69361 100644 --- a/lib/web_ui/lib/src/engine/compositor/recording_canvas.dart +++ b/lib/web_ui/lib/src/engine/compositor/recording_canvas.dart @@ -184,8 +184,8 @@ class SkRecordingCanvas implements RecordingCanvas { // ShapedText. final EngineParagraph engineParagraph = paragraph; final ParagraphGeometricStyle style = engineParagraph.geometricStyle; - final js.JsObject skFont = - skiaFontCollection.getFont(style.effectiveFontFamily, style.fontSize); + final js.JsObject skFont = skiaFontCollection.getFont( + style.effectiveFontFamily, style.fontSize ?? 12.0); final js.JsObject skShapedTextOpts = js.JsObject.jsify({ 'font': skFont, 'leftToRight': true, diff --git a/lib/web_ui/lib/src/engine/compositor/util.dart b/lib/web_ui/lib/src/engine/compositor/util.dart index 079a824a1..157e3b9ff 100644 --- a/lib/web_ui/lib/src/engine/compositor/util.dart +++ b/lib/web_ui/lib/src/engine/compositor/util.dart @@ -203,42 +203,24 @@ void drawSkShadow( final double shadowX = (bounds.left + bounds.right) / 2.0; final double shadowY = bounds.top - 600.0; - final ui.Color ambientColor = - ui.Color.fromARGB((color.alpha * ambientAlpha).round(), 0, 0, 0); - - // This is a port of SkShadowUtils::ComputeTonalColors - final int minSpot = math.min(color.red, math.min(color.green, color.blue)); - final int maxSpot = math.max(color.red, math.max(color.green, color.blue)); - final double luminance = 0.5 * (maxSpot + minSpot) / 255.0; - final double originalAlpha = (color.alpha * spotAlpha) / 255.0; - final double alphaAdjust = - (2.6 + (-2.66667 + 1.06667 * originalAlpha) * originalAlpha) * - originalAlpha; - double colorAlpha = - (3.544762 + (-4.891428 + 2.3466 * luminance) * luminance) * luminance; - colorAlpha = (colorAlpha * alphaAdjust).clamp(0.0, 1.0); - - final double greyscaleAlpha = - (originalAlpha * (1.0 - 0.4 * luminance)).clamp(0.0, 1.0); - - final double colorScale = colorAlpha * (1.0 - greyscaleAlpha); - final double tonalAlpha = colorScale + greyscaleAlpha; - final double unPremulScale = colorScale / tonalAlpha; - - final ui.Color spotColor = ui.Color.fromARGB( - (tonalAlpha * 255.999).round(), - (unPremulScale * color.red).round(), - (unPremulScale * color.green).round(), - (unPremulScale * color.blue).round(), - ); + ui.Color inAmbient = color.withAlpha((color.alpha * ambientAlpha).round()); + ui.Color inSpot = color.withAlpha((color.alpha * spotAlpha).round()); + + final js.JsObject inTonalColors = js.JsObject.jsify({ + 'ambient': inAmbient.value, + 'spot': inSpot.value, + }); + + final js.JsObject tonalColors = + canvasKit.callMethod('computeTonalColors', [inTonalColors]); skCanvas.callMethod('drawShadow', [ path._skPath, js.JsArray.from([0, 0, elevation]), js.JsArray.from([shadowX, shadowY, 600]), 800, - ambientColor.value, - spotColor.value, + tonalColors['ambient'], + tonalColors['spot'], flags, ]); } -- GitLab