blob: fab310546588d80277bd51713f6bfdd45192acdd [file] [log] [blame]
Florin Malita4aa44412017-12-19 12:21:02 -05001/*
2 * Copyright 2017 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 "SkSGRenderNode.h"
9
Florin Malitac0132ff2018-08-09 07:40:01 -040010#include "SkCanvas.h"
Florin Malitadafd6522019-02-10 01:49:46 +000011#include "SkImageFilter.h"
Florin Malitac0132ff2018-08-09 07:40:01 -040012#include "SkPaint.h"
13
Florin Malita4aa44412017-12-19 12:21:02 -050014namespace sksg {
15
Florin Malitaef26fcb2019-02-10 12:54:20 -050016RenderNode::RenderNode(uint32_t inval_traits) : INHERITED(inval_traits) {}
Florin Malita4aa44412017-12-19 12:21:02 -050017
Florin Malitac0132ff2018-08-09 07:40:01 -040018void RenderNode::render(SkCanvas* canvas, const RenderContext* ctx) const {
Florin Malitac75e2402018-01-03 16:17:29 -050019 SkASSERT(!this->hasInval());
Florin Malitac0132ff2018-08-09 07:40:01 -040020 this->onRender(canvas, ctx);
21}
22
Florin Malitaeb46bd82019-02-12 09:33:21 -050023const RenderNode* RenderNode::nodeAt(const SkPoint& p) const {
24 return this->bounds().contains(p.x(), p.y()) ? this->onNodeAt(p) : nullptr;
25}
26
Florin Malitac0132ff2018-08-09 07:40:01 -040027bool RenderNode::RenderContext::modulatePaint(SkPaint* paint) const {
28 const auto initial_alpha = paint->getAlpha(),
29 alpha = SkToU8(sk_float_round2int(initial_alpha * fOpacity));
30
Florin Malitae1c9d3c2018-08-09 11:19:14 -040031 if (alpha != initial_alpha || fColorFilter) {
Florin Malitac0132ff2018-08-09 07:40:01 -040032 paint->setAlpha(alpha);
Florin Malitae1c9d3c2018-08-09 11:19:14 -040033 paint->setColorFilter(SkColorFilter::MakeComposeFilter(fColorFilter,
34 paint->refColorFilter()));
Florin Malitac0132ff2018-08-09 07:40:01 -040035 return true;
36 }
37
38 return false;
39}
40
41RenderNode::ScopedRenderContext::ScopedRenderContext(SkCanvas* canvas, const RenderContext* ctx)
42 : fCanvas(canvas)
Florin Malita679d05c2018-08-10 12:50:08 -040043 , fCtx(ctx ? *ctx : RenderContext())
Florin Malitac0132ff2018-08-09 07:40:01 -040044 , fRestoreCount(canvas->getSaveCount()) {}
45
46RenderNode::ScopedRenderContext::~ScopedRenderContext() {
47 if (fRestoreCount >= 0) {
48 fCanvas->restoreToCount(fRestoreCount);
49 }
50}
51
Florin Malitac0132ff2018-08-09 07:40:01 -040052RenderNode::ScopedRenderContext&&
53RenderNode::ScopedRenderContext::modulateOpacity(float opacity) {
54 SkASSERT(opacity >= 0 && opacity <= 1);
Florin Malita679d05c2018-08-10 12:50:08 -040055 fCtx.fOpacity *= opacity;
Florin Malitac0132ff2018-08-09 07:40:01 -040056 return std::move(*this);
57}
58
59RenderNode::ScopedRenderContext&&
Florin Malitae1c9d3c2018-08-09 11:19:14 -040060RenderNode::ScopedRenderContext::modulateColorFilter(sk_sp<SkColorFilter> cf) {
Florin Malita679d05c2018-08-10 12:50:08 -040061 fCtx.fColorFilter = SkColorFilter::MakeComposeFilter(std::move(fCtx.fColorFilter),
62 std::move(cf));
Florin Malitae1c9d3c2018-08-09 11:19:14 -040063 return std::move(*this);
64}
65
66RenderNode::ScopedRenderContext&&
Florin Malitac0132ff2018-08-09 07:40:01 -040067RenderNode::ScopedRenderContext::setIsolation(const SkRect& bounds, bool isolation) {
Florin Malita679d05c2018-08-10 12:50:08 -040068 if (isolation) {
Florin Malitac0132ff2018-08-09 07:40:01 -040069 SkPaint layer_paint;
Florin Malita679d05c2018-08-10 12:50:08 -040070 if (fCtx.modulatePaint(&layer_paint)) {
Florin Malitac0132ff2018-08-09 07:40:01 -040071 fCanvas->saveLayer(bounds, &layer_paint);
Florin Malita679d05c2018-08-10 12:50:08 -040072 fCtx = RenderContext();
Florin Malitac0132ff2018-08-09 07:40:01 -040073 }
74 }
75 return std::move(*this);
Florin Malita4aa44412017-12-19 12:21:02 -050076}
77
Florin Malitadafd6522019-02-10 01:49:46 +000078RenderNode::ScopedRenderContext&&
79RenderNode::ScopedRenderContext::setFilterIsolation(const SkRect& bounds,
80 sk_sp<SkImageFilter> filter) {
81 SkPaint layer_paint;
82 fCtx.modulatePaint(&layer_paint);
83
84 SkASSERT(!layer_paint.getImageFilter());
85 layer_paint.setImageFilter(std::move(filter));
86 fCanvas->saveLayer(bounds, &layer_paint);
87 fCtx = RenderContext();
88
89 return std::move(*this);
90}
91
Florin Malita4aa44412017-12-19 12:21:02 -050092} // namespace sksg