Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2018 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkSGMaskEffect.h"
      9 
     10 #include "SkCanvas.h"
     11 
     12 namespace sksg {
     13 
     14 MaskEffect::MaskEffect(sk_sp<RenderNode> child, sk_sp<RenderNode> mask, Mode mode)
     15     : INHERITED(std::move(child))
     16     , fMaskNode(std::move(mask))
     17     , fMaskMode(mode) {
     18     this->observeInval(fMaskNode);
     19 }
     20 
     21 MaskEffect::~MaskEffect() {
     22     this->unobserveInval(fMaskNode);
     23 }
     24 
     25 void MaskEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
     26     if (this->bounds().isEmpty())
     27         return;
     28 
     29     SkAutoCanvasRestore acr(canvas, false);
     30 
     31     canvas->saveLayer(this->bounds(), nullptr);
     32     // Note: the paint overrides in ctx don't apply to the mask.
     33     fMaskNode->render(canvas);
     34 
     35 
     36     SkPaint p;
     37     p.setBlendMode(fMaskMode == Mode::kNormal ? SkBlendMode::kSrcIn : SkBlendMode::kSrcOut);
     38     canvas->saveLayer(this->bounds(), &p);
     39 
     40     this->INHERITED::onRender(canvas, ctx);
     41 }
     42 
     43 
     44 SkRect MaskEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
     45     SkASSERT(this->hasInval());
     46 
     47     const auto maskBounds = fMaskNode->revalidate(ic, ctm);
     48     auto childBounds = this->INHERITED::onRevalidate(ic, ctm);
     49 
     50     return (fMaskMode == Mode::kInvert || childBounds.intersect(maskBounds))
     51         ? childBounds
     52         : SkRect::MakeEmpty();
     53 }
     54 
     55 } // namespace sksg
     56