| // 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. |
| |
| // @dart = 2.6 |
| part of engine; |
| |
| /// The implementation of [ui.Paint] used by the CanvasKit backend. |
| /// |
| /// This class is backed by a Skia object that must be explicitly |
| /// deleted to avoid a memory leak. This is done by extending [SkiaObject]. |
| class SkPaint extends SkiaObject implements ui.Paint { |
| SkPaint(); |
| |
| static const ui.Color _defaultPaintColor = ui.Color(0xFF000000); |
| static final js.JsObject _skPaintStyleStroke = canvasKit['PaintStyle']['Stroke']; |
| static final js.JsObject _skPaintStyleFill = canvasKit['PaintStyle']['Fill']; |
| |
| @override |
| ui.BlendMode get blendMode => _blendMode; |
| @override |
| set blendMode(ui.BlendMode value) { |
| _blendMode = value; |
| _syncBlendMode(skiaObject); |
| } |
| void _syncBlendMode(js.JsObject object) { |
| final js.JsObject skBlendMode = makeSkBlendMode(_blendMode); |
| object.callMethod('setBlendMode', <js.JsObject>[skBlendMode]); |
| } |
| ui.BlendMode _blendMode = ui.BlendMode.srcOver; |
| |
| @override |
| ui.PaintingStyle get style => _style; |
| |
| @override |
| set style(ui.PaintingStyle value) { |
| _style = value; |
| _syncStyle(skiaObject); |
| } |
| void _syncStyle(js.JsObject object) { |
| js.JsObject skPaintStyle; |
| switch (_style) { |
| case ui.PaintingStyle.stroke: |
| skPaintStyle = _skPaintStyleStroke; |
| break; |
| case ui.PaintingStyle.fill: |
| skPaintStyle = _skPaintStyleFill; |
| break; |
| } |
| object.callMethod('setStyle', <js.JsObject>[skPaintStyle]); |
| } |
| ui.PaintingStyle _style = ui.PaintingStyle.fill; |
| |
| @override |
| double get strokeWidth => _strokeWidth; |
| @override |
| set strokeWidth(double value) { |
| _strokeWidth = value; |
| _syncStrokeWidth(skiaObject); |
| } |
| void _syncStrokeWidth(js.JsObject object) { |
| object.callMethod('setStrokeWidth', <double>[strokeWidth]); |
| } |
| double _strokeWidth = 0.0; |
| |
| // TODO(yjbanov): implement |
| @override |
| ui.StrokeCap get strokeCap => _strokeCap; |
| @override |
| set strokeCap(ui.StrokeCap value) { |
| _strokeCap = value; |
| } |
| ui.StrokeCap _strokeCap = ui.StrokeCap.butt; |
| |
| // TODO(yjbanov): implement |
| @override |
| ui.StrokeJoin get strokeJoin => _strokeJoin; |
| @override |
| set strokeJoin(ui.StrokeJoin value) { |
| _strokeJoin = value; |
| } |
| ui.StrokeJoin _strokeJoin = ui.StrokeJoin.miter; |
| |
| @override |
| bool get isAntiAlias => _isAntiAlias; |
| @override |
| set isAntiAlias(bool value) { |
| _isAntiAlias = value; |
| _syncAntiAlias(skiaObject); |
| } |
| void _syncAntiAlias(js.JsObject object) { |
| object.callMethod('setAntiAlias', <bool>[_isAntiAlias]); |
| } |
| bool _isAntiAlias = true; |
| |
| @override |
| ui.Color get color => _color; |
| @override |
| set color(ui.Color value) { |
| _color = value; |
| _syncColor(skiaObject); |
| } |
| void _syncColor(js.JsObject object) { |
| int colorValue = _defaultPaintColor.value; |
| if (_color != null) { |
| colorValue = _color.value; |
| } |
| object.callMethod('setColor', <int>[colorValue]); |
| } |
| ui.Color _color = _defaultPaintColor; |
| |
| // TODO(yjbanov): implement |
| @override |
| bool get invertColors => _invertColors; |
| @override |
| set invertColors(bool value) { |
| _invertColors = value; |
| } |
| bool _invertColors = false; |
| |
| @override |
| ui.Shader get shader => _shader as ui.Shader; |
| @override |
| set shader(ui.Shader value) { |
| _shader = value as EngineShader; |
| _syncShader(skiaObject); |
| } |
| void _syncShader(js.JsObject object) { |
| js.JsObject skShader; |
| if (_shader != null) { |
| skShader = _shader.createSkiaShader(); |
| } |
| object.callMethod('setShader', <js.JsObject>[skShader]); |
| } |
| EngineShader _shader; |
| |
| @override |
| ui.MaskFilter get maskFilter => _maskFilter; |
| @override |
| set maskFilter(ui.MaskFilter value) { |
| _maskFilter = value; |
| _syncMaskFilter(skiaObject); |
| } |
| void _syncMaskFilter(js.JsObject object) { |
| js.JsObject skMaskFilter; |
| if (_maskFilter != null) { |
| final ui.BlurStyle blurStyle = _maskFilter.webOnlyBlurStyle; |
| final double sigma = _maskFilter.webOnlySigma; |
| |
| js.JsObject skBlurStyle; |
| switch (blurStyle) { |
| case ui.BlurStyle.normal: |
| skBlurStyle = canvasKit['BlurStyle']['Normal']; |
| break; |
| case ui.BlurStyle.solid: |
| skBlurStyle = canvasKit['BlurStyle']['Solid']; |
| break; |
| case ui.BlurStyle.outer: |
| skBlurStyle = canvasKit['BlurStyle']['Outer']; |
| break; |
| case ui.BlurStyle.inner: |
| skBlurStyle = canvasKit['BlurStyle']['Inner']; |
| break; |
| } |
| |
| skMaskFilter = canvasKit |
| .callMethod('MakeBlurMaskFilter', <dynamic>[skBlurStyle, sigma, true]); |
| } |
| object.callMethod('setMaskFilter', <js.JsObject>[skMaskFilter]); |
| } |
| ui.MaskFilter _maskFilter; |
| |
| // TODO(yjbanov): implement |
| @override |
| ui.FilterQuality get filterQuality => _filterQuality; |
| @override |
| set filterQuality(ui.FilterQuality value) { |
| _filterQuality = value; |
| } |
| ui.FilterQuality _filterQuality = ui.FilterQuality.none; |
| |
| @override |
| ui.ColorFilter get colorFilter => _colorFilter; |
| @override |
| set colorFilter(ui.ColorFilter value) { |
| _colorFilter = value; |
| _syncColorFilter(skiaObject); |
| } |
| void _syncColorFilter(js.JsObject object) { |
| js.JsObject skColorFilterJs; |
| if (_colorFilter != null) { |
| SkColorFilter skFilter = _colorFilter._toSkColorFilter(); |
| skColorFilterJs = skFilter.skColorFilter; |
| } |
| object.callMethod('setColorFilter', <js.JsObject>[skColorFilterJs]); |
| } |
| EngineColorFilter _colorFilter; |
| |
| // TODO(yjbanov): implement |
| @override |
| double get strokeMiterLimit => _strokeMiterLimit; |
| @override |
| set strokeMiterLimit(double value) { |
| _strokeMiterLimit = value; |
| } |
| double _strokeMiterLimit = 0.0; |
| |
| @override |
| ui.ImageFilter get imageFilter => _imageFilter; |
| @override |
| set imageFilter(ui.ImageFilter value) { |
| _imageFilter = value; |
| _syncImageFilter(skiaObject); |
| } |
| void _syncImageFilter(js.JsObject object) { |
| js.JsObject imageFilterJs; |
| if (_imageFilter != null) { |
| imageFilterJs = _imageFilter.skImageFilter; |
| } |
| object.callMethod('setImageFilter', <js.JsObject>[imageFilterJs]); |
| } |
| SkImageFilter _imageFilter; |
| |
| @override |
| js.JsObject createDefault() { |
| final obj = js.JsObject(canvasKit['SkPaint']); |
| // Sync fields whose Skia defaults are different from Flutter's. |
| _syncAntiAlias(obj); |
| _syncColor(obj); |
| return obj; |
| } |
| |
| @override |
| js.JsObject resurrect() { |
| final obj = js.JsObject(canvasKit['SkPaint']); |
| _syncBlendMode(obj); |
| _syncStyle(obj); |
| _syncStrokeWidth(obj); |
| _syncAntiAlias(obj); |
| _syncColor(obj); |
| _syncShader(obj); |
| _syncMaskFilter(obj); |
| _syncColorFilter(obj); |
| _syncImageFilter(obj); |
| return obj; |
| } |
| } |