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 | |
17 | namespace sksg { |
18 | |
19 | Draw::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 | |
26 | Draw::~Draw() { |
27 | this->unobserveInval(fGeometry); |
28 | this->unobserveInval(fPaint); |
29 | } |
30 | |
31 | void 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 | |
45 | const 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 | |
64 | SkRect 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 | |