• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <tuple>
14 #include <vector>
15 
16 namespace skrive {
17 
18 namespace internal {
19 
20 template <typename T>
21 size_t parse_node(StreamReader*, T*);
22 
23 template <typename T, typename... Args>
make_from_stream(StreamReader * sr,Args &&...args)24 std::tuple<sk_sp<Component>, size_t> make_from_stream(StreamReader* sr, Args&&... args) {
25     auto node = sk_make_sp<T>(std::forward<Args>(args)...);
26 
27     const auto parent_id = parse_node<T>(sr, node.get());
28 
29     return std::make_tuple(std::move(node), parent_id);
30 }
31 
parse_component(StreamReader * sr)32 std::tuple<sk_sp<Component>, size_t> parse_component(StreamReader* sr) {
33     StreamReader::AutoBlock block(sr);
34     switch (block.type()) {
35         case StreamReader::BlockType::kActorNode:
36             return make_from_stream<Node >(sr);
37         case StreamReader::BlockType::kActorShape:
38             return make_from_stream<Shape>(sr);
39         case StreamReader::BlockType::kColorFill:
40             return make_from_stream<ColorPaint>(sr, SkPaint::kFill_Style);
41         case StreamReader::BlockType::kColorStroke:
42             return make_from_stream<ColorPaint>(sr, SkPaint::kStroke_Style);
43         case StreamReader::BlockType::kActorEllipse:
44             return make_from_stream<Ellipse>(sr);
45         case StreamReader::BlockType::kActorRectangle:
46             return make_from_stream<Rectangle>(sr);
47         default:
48             break;
49     }
50 
51     SkDebugf("!! unsupported node type: %d\n", block.type());
52     return {nullptr, 0};
53 }
54 
parse_components(StreamReader * sr)55 sk_sp<Node> parse_components(StreamReader* sr) {
56     const auto count = sr->readLength16();
57 
58     std::vector<sk_sp<Component>> components;
59     components.reserve(count);
60 
61     for (size_t i = 0; i < count; ++i) {
62         auto [ component, parent_id ] = parse_component(sr);
63 
64         // parent IDs are kinda-sorta one-based
65         if (parent_id > 0) {
66             parent_id -= 1;
67         }
68 
69         if (component && parent_id < i && components[parent_id]) {
70             if (Node* node = *components[parent_id]) {
71                 node->addChild(component);
72             }
73         }
74 
75         components.push_back(std::move(component));
76     }
77 
78     SkDebugf(".. parsed %zu components\n", components.size());
79 
80     // hmm...
81     for (const auto& comp : components) {
82         if (comp && comp->is<Node>()) {
83             return sk_ref_sp(static_cast<Node*>(*comp));
84         }
85     }
86 
87     return nullptr;
88 }
89 
parse_artboard(StreamReader * sr)90 sk_sp<Artboard> parse_artboard(StreamReader* sr) {
91     auto ab = sk_make_sp<Artboard>();
92 
93     ab->setName        (sr->readString("name"        ));
94     ab->setTranslation (sr->readV2    ("translation" ));
95     ab->setSize       ({sr->readFloat ("width"       ),
96                         sr->readFloat ("height"      )});
97     ab->setOrigin      (sr->readV2    ("origin"      ));
98     ab->setClipContents(sr->readBool  ("clipContents"));
99     ab->setColor       (sr->readColor ("color"       ));
100 
101     for (;;) {
102         StreamReader::AutoBlock block(sr);
103         if (block.type() == StreamReader::BlockType::kEoB) {
104             break;
105         }
106 
107         switch (block.type()) {
108         case StreamReader::BlockType::kComponents:
109             ab->setRoot(parse_components(sr));
110             break;
111         default:
112             SkDebugf("!! Unsupported block type: %d\n", block.type());
113             break;
114         }
115     }
116 
117     SkDebugf(".. parsed artboard \"%s\" [%f x %f]\n",
118              ab->getName().c_str(), ab->getSize().x, ab->getSize().y);
119 
120     return ab;
121 }
122 
123 } // namespace internal
124 
render(SkCanvas * canvas) const125 void Artboard::render(SkCanvas* canvas) const {
126     SkAutoCanvasRestore acr(canvas, true);
127     canvas->translate(fTranslation.x, fTranslation.y);
128 
129     SkPaint paint;
130     paint.setColor4f(fColor);
131 
132     canvas->drawRect(SkRect::MakeWH(fSize.x, fSize.y), paint);
133 
134     if (fRoot) {
135         fRoot->revalidate();
136         fRoot->render(canvas);
137     }
138 }
139 
140 } // namespace skrive
141