1 // Copyright 2021 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
5 #include "flutter/flow/layers/mask_layer.h"
6
7 #include "third_party/skia/include/core/SkMaskFilter.h"
8 #include "third_party/skia/include/effects/SkLumaColorFilter.h"
9
10 namespace flutter {
11
Paint(PaintContext & context) const12 void MaskLayer::Paint(PaintContext& context) const {
13 TRACE_EVENT0("flutter", "MaskLayer::Paint");
14 FML_DCHECK(needs_painting());
15
16 if (isSvgMask_ && !svgDom_) {
17 return;
18 }
19
20 auto& skCanvas = context.internal_nodes_canvas;
21 SkAutoCanvasRestore save(skCanvas, true);
22 SkRect maskBounds = paint_bounds();
23
24 skCanvas->saveLayer(maskBounds, nullptr);
25 int tmpLayer = skCanvas->getSaveCount();
26
27 SkPaint mask_filter;
28 #ifdef USE_SYSTEM_SKIA
29 auto filter = SkColorFilter::MakeComposeFilter(SkLumaColorFilter::Make(),
30 SkColorFilter::MakeSRGBToLinearGamma());
31 #else
32 auto filter = SkColorFilters::Compose(SkLumaColorFilter::Make(),
33 SkColorFilters::SRGBToLinearGamma());
34 #endif
35 mask_filter.setColorFilter(filter);
36 skCanvas->saveLayer(maskBounds, &mask_filter);
37 if (isSvgMask_) {
38 SkAutoCanvasRestore maskSave(skCanvas, true);
39 skCanvas->translate(maskBounds.fLeft + svgX_, maskBounds.fTop + svgY_);
40 skCanvas->scale(scaleX_, scaleY_);
41 svgDom_->render(skCanvas);
42 } else if (isGradientMask_) {
43 SkAutoCanvasRestore maskSave(skCanvas, true);
44 skCanvas->translate(maskBounds.fLeft, maskBounds.fTop);
45 SkRect skRect = SkRect::MakeIWH(maskBounds.fRight - maskBounds.fLeft, maskBounds.fBottom - maskBounds.fTop);
46 skCanvas->drawRect(skRect, maskPaint_);
47 } else if (isPathMask_) {
48 SkAutoCanvasRestore maskSave(skCanvas, true);
49 skCanvas->translate(maskBounds.fLeft, maskBounds.fTop);
50 skCanvas->drawPath(maskPath_, maskPaint_);
51 }
52
53 // back to mask layer
54 skCanvas->restoreToCount(tmpLayer);
55 // create content layer
56 SkPaint maskPaint;
57 maskPaint.setBlendMode(SkBlendMode::kSrcIn);
58 skCanvas->saveLayer(maskBounds, &maskPaint);
59 skCanvas->clipRect(maskBounds, true);
60 PaintChildren(context);
61 }
62
63 } // namespace flutter
64