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 "SkSGTransform.h"
9 
10 #include "SkCanvas.h"
11 
12 namespace sksg {
13 // Matrix nodes don't generate damage on their own, but via aggregation ancestor Transform nodes.
Matrix(const SkMatrix & m,sk_sp<Matrix> parent)14 Matrix::Matrix(const SkMatrix& m, sk_sp<Matrix> parent)
15     : INHERITED(kBubbleDamage_Trait)
16     , fParent(std::move(parent))
17     , fLocalMatrix(m) {
18     if (fParent) {
19         this->observeInval(fParent);
20     }
21 }
22 
~Matrix()23 Matrix::~Matrix() {
24     if (fParent) {
25         this->unobserveInval(fParent);
26     }
27 }
28 
onRevalidate(InvalidationController * ic,const SkMatrix & ctm)29 SkRect Matrix::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
30     fTotalMatrix = fLocalMatrix;
31 
32     if (fParent) {
33         fParent->revalidate(ic, ctm);
34         fTotalMatrix.postConcat(fParent->getTotalMatrix());
35     }
36 
37     return SkRect::MakeEmpty();
38 }
39 
Transform(sk_sp<RenderNode> child,sk_sp<Matrix> matrix)40 Transform::Transform(sk_sp<RenderNode> child, sk_sp<Matrix> matrix)
41     : INHERITED(std::move(child))
42     , fMatrix(std::move(matrix)) {
43     this->observeInval(fMatrix);
44 }
45 
~Transform()46 Transform::~Transform() {
47     this->unobserveInval(fMatrix);
48 }
49 
onRender(SkCanvas * canvas) const50 void Transform::onRender(SkCanvas* canvas) const {
51     const auto& m = fMatrix->getTotalMatrix();
52     SkAutoCanvasRestore acr(canvas, !m.isIdentity());
53     canvas->concat(m);
54     this->INHERITED::onRender(canvas);
55 }
56 
onRevalidate(InvalidationController * ic,const SkMatrix & ctm)57 SkRect Transform::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
58     SkASSERT(this->hasInval());
59 
60     // We don't care about matrix reval results.
61     fMatrix->revalidate(ic, ctm);
62 
63     const auto& m = fMatrix->getTotalMatrix();
64     auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
65     m.mapRect(&bounds);
66 
67     return bounds;
68 }
69 
70 } // namespace sksg
71