1 /*
2  * Copyright 2020 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 "experimental/skrive/include/SkRive.h"
9 
10 #include "experimental/skrive/src/reader/StreamReader.h"
11 #include "include/core/SkCanvas.h"
12 
13 namespace skrive {
14 namespace internal {
15 
16 template <typename T>
17 size_t parse_node(StreamReader*, T*);
18 
19 template <>
parse_node(StreamReader * sr,Component * node)20 size_t parse_node<Component>(StreamReader* sr, Component* node) {
21     node->setName(sr->readString("name"));
22 
23     const auto parent_id = sr->readId("parent");
24 
25     SkDebugf(".. %s -> %d\n", node->getName().c_str(), parent_id);
26 
27     return parent_id;
28 }
29 
30 template <>
parse_node(StreamReader * sr,TransformableComponent * node)31 size_t parse_node<TransformableComponent>(StreamReader* sr, TransformableComponent* node) {
32     const auto parent_index = parse_node<Component>(sr, node);
33 
34     node->setTranslation(sr->readV2("translation"));
35     node->setRotation(sr->readFloat("rotation"));
36     node->setScale(sr->readV2("scale"));
37     node->setOpacity(sr->readFloat("opacity"));
38 
39     return parent_index;
40 }
41 
42 } // namespace internal
43 
invalidate()44 void Component::invalidate() {
45     auto* node = this;
46 
47     do {
48         node->fDirty = true;
49         node = node->fParent;
50     } while (node && !node->hasInval());
51 }
52 
revalidate()53 void Component::revalidate() {
54     if (this->hasInval()) {
55         this->onRevalidate();
56         fDirty = false;
57     }
58 }
59 
onRender(SkCanvas *) const60 void Component::onRender(SkCanvas*) const {}
61 
62 TransformableComponent::ScopedTransformContext::
ScopedTransformContext(const TransformableComponent * node,SkCanvas * canvas)63 ScopedTransformContext(const TransformableComponent* node, SkCanvas* canvas)
64     : fCanvas(canvas)
65     , fRestoreCount(canvas->getSaveCount()) {
66     const auto lm = SkMatrix::Translate(node->getTranslation().x, node->getTranslation().y) *
67                     SkMatrix::RotateDeg(node->getRotation()                               ) *
68                     SkMatrix::Scale    (node->getScale().x      , node->getScale().y      );
69 
70     if (node->getOpacity() < 1) {
71         SkPaint layer_paint;
72         layer_paint.setAlphaf(node->getOpacity());
73         canvas->saveLayer(nullptr, &layer_paint);
74     } else if (!lm.isIdentity()) {
75         canvas->save();
76     }
77     canvas->concat(lm);
78 }
79 
~ScopedTransformContext()80 TransformableComponent::ScopedTransformContext::~ScopedTransformContext() {
81     fCanvas->restoreToCount(this->fRestoreCount);
82 }
83 
84 } // namespace skrive
85