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 "modules/sksg/include/SkSGDraw.h" 9 10#include "include/core/SkCanvas.h" 11#include "include/core/SkPath.h" 12#include "modules/sksg/include/SkSGGeometryNode.h" 13#include "modules/sksg/include/SkSGInvalidationController.h" 14#include "modules/sksg/include/SkSGPaint.h" 15#include "src/core/SkTLazy.h" 16 17namespace sksg { 18 19Draw::Draw(sk_sp<GeometryNode> geometry, sk_sp<PaintNode> paint) 20 : fGeometry(std::move(geometry)) 21 , fPaint(std::move(paint)) { 22 this->observeInval(fGeometry); 23 this->observeInval(fPaint); 24} 25 26Draw::~Draw() { 27 this->unobserveInval(fGeometry); 28 this->unobserveInval(fPaint); 29} 30 31void Draw::onRender(SkCanvas* canvas, const RenderContext* ctx) const { 32 auto paint = fPaint->makePaint(); 33 if (ctx) { 34 ctx->modulatePaint(canvas->getTotalMatrix(), &paint); 35 } 36 37 const auto skipDraw = paint.nothingToDraw() || 38 (paint.getStyle() == SkPaint::kStroke_Style && paint.getStrokeWidth() <= 0); 39 40 if (!skipDraw) { 41 fGeometry->draw(canvas, paint); 42 } 43} 44 45const RenderNode* Draw::onNodeAt(const SkPoint& p) const { 46 const auto paint = fPaint->makePaint(); 47 48 if (!paint.getAlpha()) { 49 return nullptr; 50 } 51 52 if (paint.getStyle() == SkPaint::Style::kFill_Style && fGeometry->contains(p)) { 53 return this; 54 } 55 56 SkPath stroke_path; 57 if (!paint.getFillPath(fGeometry->asPath(), &stroke_path)) { 58 return nullptr; 59 } 60 61 return stroke_path.contains(p.x(), p.y()) ? this : nullptr; 62} 63 64SkRect Draw::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) { 65 SkASSERT(this->hasInval()); 66 67 auto bounds = fGeometry->revalidate(ic, ctm); 68 fPaint->revalidate(ic, ctm); 69 70 const auto paint = fPaint->makePaint(); 71 SkASSERT(paint.canComputeFastBounds()); 72 73 return paint.computeFastBounds(bounds, &bounds); 74} 75 76} // namespace sksg 77