1// Copyright 2013 The Flutter Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5part of engine; 6 7/// An actual [SkCanvas] which can receive raw drawing commands. 8/// 9/// In order for the drawing commands to be flushed to the associated HTML 10/// canvas, you must call `flush()` on the canvas's `SkSurface`. 11/// 12/// Although this class is backed by an `SkCanvas` and can in theory perform 13/// arbitrary drawing operations, this class is only used in the final 14/// compositing by the layers, and arbitrary drawings are done in a 15/// [ui.Picture] which uses a Skia recording canvas. This class receives 16/// drawing calls from the various `Layer` classes, e.g. [ClipRectLayer] and 17/// so only exposes a subset of the drawing operations that can be performed 18/// on a canvas. 19class SkCanvas { 20 final js.JsObject skCanvas; 21 final html.CanvasElement htmlCanvas; 22 final js.JsObject skSurface; 23 final ui.Size size; 24 25 SkCanvas(this.skCanvas, this.htmlCanvas, this.skSurface, this.size); 26 27 int save() { 28 return skCanvas.callMethod('save'); 29 } 30 31 int saveLayer(ui.Rect bounds, ui.Paint paint) { 32 return skCanvas.callMethod( 33 'saveLayer', <js.JsObject>[_makeSkRect(bounds), _makeSkPaint(paint)]); 34 } 35 36 void restore() { 37 skCanvas.callMethod('restore'); 38 } 39 40 void restoreToCount(int count) { 41 skCanvas.callMethod('restoreToCount', <int>[count]); 42 } 43 44 void clear() { 45 skCanvas.callMethod('clear', <int>[0xffffffff]); 46 } 47 48 void translate(double dx, double dy) { 49 skCanvas.callMethod('translate', <double>[dx, dy]); 50 } 51 52 void transform(Float64List matrix) { 53 skCanvas.callMethod('concat', <js.JsArray<double>>[toSkMatrix(matrix)]); 54 } 55 56 void clipPath(ui.Path path) { 57 final SkPath skPath = path; 58 skCanvas.callMethod('clipPath', <js.JsObject>[skPath._skPath]); 59 } 60 61 void clipRect(ui.Rect rect) { 62 skCanvas.callMethod('clipRect', <js.JsObject>[_makeSkRect(rect)]); 63 } 64 65 void clipRRect(ui.RRect rrect) { 66 final SkPath skPath = SkPath(); 67 skPath.addRRect(rrect); 68 clipPath(skPath); 69 } 70 71 void drawPicture(ui.Picture picture) { 72 final SkPicture skPicture = picture; 73 skCanvas.callMethod('drawPicture', <js.JsObject>[skPicture.skPicture]); 74 } 75 76 void drawPath(ui.Path path, ui.Paint paint) { 77 final SkPath skPath = path; 78 skCanvas.callMethod( 79 'drawPath', <js.JsObject>[skPath._skPath, _makeSkPaint(paint)]); 80 } 81 82 void drawPaint(ui.Paint paint) { 83 skCanvas.callMethod('drawPaint', <js.JsObject>[_makeSkPaint(paint)]); 84 } 85 86 void drawShadow(ui.Path path, ui.Color color, double elevation, 87 bool transparentOccluder) { 88 throw 'drawShadow'; 89 } 90 91 Matrix4 get currentTransform => throw 'currentTransform'; 92 93 js.JsObject _makeSkRect(ui.Rect rect) { 94 return js.JsObject(canvasKit['LTRBRect'], 95 <double>[rect.left, rect.top, rect.right, rect.bottom]); 96 } 97 98 js.JsObject _makeSkPaint(ui.Paint paint) { 99 final js.JsObject skPaint = js.JsObject(canvasKit['SkPaint']); 100 if (paint.color != null) { 101 skPaint.callMethod('setColor', <int>[paint.color.value]); 102 } 103 return skPaint; 104 } 105} 106