1 /*
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
10 #include "SkCanvas.h"
11 #include "SkPaint.h"
12
13 namespace sksg {
14
RenderNode()15 RenderNode::RenderNode() : INHERITED(0) {}
16
render(SkCanvas * canvas,const RenderContext * ctx) const17 void RenderNode::render(SkCanvas* canvas, const RenderContext* ctx) const {
18 SkASSERT(!this->hasInval());
19 this->onRender(canvas, ctx);
20 }
21
modulatePaint(SkPaint * paint) const22 bool RenderNode::RenderContext::modulatePaint(SkPaint* paint) const {
23 const auto initial_alpha = paint->getAlpha(),
24 alpha = SkToU8(sk_float_round2int(initial_alpha * fOpacity));
25
26 if (alpha != initial_alpha || fColorFilter) {
27 paint->setAlpha(alpha);
28 paint->setColorFilter(SkColorFilter::MakeComposeFilter(fColorFilter,
29 paint->refColorFilter()));
30 return true;
31 }
32
33 return false;
34 }
35
ScopedRenderContext(SkCanvas * canvas,const RenderContext * ctx)36 RenderNode::ScopedRenderContext::ScopedRenderContext(SkCanvas* canvas, const RenderContext* ctx)
37 : fCanvas(canvas)
38 , fCtx(ctx ? *ctx : RenderContext())
39 , fRestoreCount(canvas->getSaveCount()) {}
40
~ScopedRenderContext()41 RenderNode::ScopedRenderContext::~ScopedRenderContext() {
42 if (fRestoreCount >= 0) {
43 fCanvas->restoreToCount(fRestoreCount);
44 }
45 }
46
47 RenderNode::ScopedRenderContext&&
modulateOpacity(float opacity)48 RenderNode::ScopedRenderContext::modulateOpacity(float opacity) {
49 SkASSERT(opacity >= 0 && opacity <= 1);
50 fCtx.fOpacity *= opacity;
51 return std::move(*this);
52 }
53
54 RenderNode::ScopedRenderContext&&
modulateColorFilter(sk_sp<SkColorFilter> cf)55 RenderNode::ScopedRenderContext::modulateColorFilter(sk_sp<SkColorFilter> cf) {
56 fCtx.fColorFilter = SkColorFilter::MakeComposeFilter(std::move(fCtx.fColorFilter),
57 std::move(cf));
58 return std::move(*this);
59 }
60
61 RenderNode::ScopedRenderContext&&
setIsolation(const SkRect & bounds,bool isolation)62 RenderNode::ScopedRenderContext::setIsolation(const SkRect& bounds, bool isolation) {
63 if (isolation) {
64 SkPaint layer_paint;
65 if (fCtx.modulatePaint(&layer_paint)) {
66 fCanvas->saveLayer(bounds, &layer_paint);
67 fCtx = RenderContext();
68 }
69 }
70 return std::move(*this);
71 }
72
73 } // namespace sksg
74