VectorDrawable.h revision 4bbc2931263b232fba61807fca00e127573eff42
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HWUI_VPATH_H
18#define ANDROID_HWUI_VPATH_H
19
20#include "Canvas.h"
21#include <SkBitmap.h>
22#include <SkColor.h>
23#include <SkMatrix.h>
24#include <SkPaint.h>
25#include <SkPath.h>
26#include <SkPathMeasure.h>
27#include <SkRect.h>
28
29#include <cutils/compiler.h>
30#include <stddef.h>
31#include <vector>
32#include <string>
33
34namespace android {
35namespace uirenderer {
36
37namespace VectorDrawable {
38#define VD_SET_PROP_WITH_FLAG(field, value, flag) (VD_SET_PROP(field, value) ? (flag = true, true): false);
39#define VD_SET_PROP(field, value) (value != field ? (field = value, true) : false)
40
41/* A VectorDrawable is composed of a tree of nodes.
42 * Each node can be a group node, or a path.
43 * A group node can have groups or paths as children, but a path node has
44 * no children.
45 * One example can be:
46 *                 Root Group
47 *                /    |     \
48 *           Group    Path    Group
49 *          /     \             |
50 *         Path   Path         Path
51 *
52 */
53class ANDROID_API Node {
54public:
55    Node(const Node& node) {
56        mName = node.mName;
57    }
58    Node() {}
59    virtual void draw(Canvas* outCanvas, const SkMatrix& currentMatrix,
60            float scaleX, float scaleY) = 0;
61    virtual void dump() = 0;
62    void setName(const char* name) {
63        mName = name;
64    }
65    virtual ~Node(){}
66protected:
67    std::string mName;
68};
69
70class ANDROID_API Path : public Node {
71public:
72    struct ANDROID_API Data {
73        std::vector<char> verbs;
74        std::vector<size_t> verbSizes;
75        std::vector<float> points;
76        bool operator==(const Data& data) const {
77            return verbs == data.verbs && verbSizes == data.verbSizes
78                    && points == data.points;
79        }
80    };
81    Path(const Data& nodes);
82    Path(const Path& path);
83    Path(const char* path, size_t strLength);
84    Path() {}
85    void dump() override;
86    bool canMorph(const Data& path);
87    bool canMorph(const Path& path);
88    void draw(Canvas* outCanvas, const SkMatrix& groupStackedMatrix,
89            float scaleX, float scaleY) override;
90    void setPath(const char* path, size_t strLength);
91    void setPathData(const Data& data);
92    static float getMatrixScale(const SkMatrix& groupStackedMatrix);
93
94protected:
95    virtual const SkPath& getUpdatedPath();
96    virtual void drawPath(Canvas *outCanvas, const SkPath& renderPath,
97            float strokeScale) = 0;
98    Data mData;
99    SkPath mSkPath;
100    bool mSkPathDirty = true;
101};
102
103class ANDROID_API FullPath: public Path {
104public:
105    FullPath(const FullPath& path); // for cloning
106    FullPath(const char* path, size_t strLength) : Path(path, strLength) {}
107    FullPath() : Path() {}
108    FullPath(const Data& nodes) : Path(nodes) {}
109
110    void updateProperties(float strokeWidth, SkColor strokeColor,
111            float strokeAlpha, SkColor fillColor, float fillAlpha,
112            float trimPathStart, float trimPathEnd, float trimPathOffset,
113            float strokeMiterLimit, int strokeLineCap, int strokeLineJoin);
114    float getStrokeWidth() {
115        return mStrokeWidth;
116    }
117    void setStrokeWidth(float strokeWidth) {
118        mStrokeWidth = strokeWidth;
119    }
120    SkColor getStrokeColor() {
121        return mStrokeColor;
122    }
123    void setStrokeColor(SkColor strokeColor) {
124        mStrokeColor = strokeColor;
125    }
126    float getStrokeAlpha() {
127        return mStrokeAlpha;
128    }
129    void setStrokeAlpha(float strokeAlpha) {
130        mStrokeAlpha = strokeAlpha;
131    }
132    SkColor getFillColor() {
133        return mFillColor;
134    }
135    void setFillColor(SkColor fillColor) {
136        mFillColor = fillColor;
137    }
138    float getFillAlpha() {
139        return mFillAlpha;
140    }
141    void setFillAlpha(float fillAlpha) {
142        mFillAlpha = fillAlpha;
143    }
144    float getTrimPathStart() {
145        return mTrimPathStart;
146    }
147    void setTrimPathStart(float trimPathStart) {
148        VD_SET_PROP_WITH_FLAG(mTrimPathStart, trimPathStart, mTrimDirty);
149    }
150    float getTrimPathEnd() {
151        return mTrimPathEnd;
152    }
153    void setTrimPathEnd(float trimPathEnd) {
154        VD_SET_PROP_WITH_FLAG(mTrimPathEnd, trimPathEnd, mTrimDirty);
155    }
156    float getTrimPathOffset() {
157        return mTrimPathOffset;
158    }
159    void setTrimPathOffset(float trimPathOffset) {
160        VD_SET_PROP_WITH_FLAG(mTrimPathOffset, trimPathOffset, mTrimDirty);
161    }
162    bool getProperties(int8_t* outProperties, int length);
163
164protected:
165    const SkPath& getUpdatedPath() override;
166    void drawPath(Canvas* outCanvas, const SkPath& renderPath,
167            float strokeScale) override;
168
169private:
170    // Applies trimming to the specified path.
171    void applyTrim();
172    float mStrokeWidth = 0;
173    SkColor mStrokeColor = SK_ColorTRANSPARENT;
174    float mStrokeAlpha = 1;
175    SkColor mFillColor = SK_ColorTRANSPARENT;
176    float mFillAlpha = 1;
177    float mTrimPathStart = 0;
178    float mTrimPathEnd = 1;
179    float mTrimPathOffset = 0;
180    bool mTrimDirty = true;
181    SkPaint::Cap mStrokeLineCap = SkPaint::Cap::kButt_Cap;
182    SkPaint::Join mStrokeLineJoin = SkPaint::Join::kMiter_Join;
183    float mStrokeMiterLimit = 4;
184    SkPath mTrimmedSkPath;
185    SkPaint mPaint;
186};
187
188class ANDROID_API ClipPath: public Path {
189public:
190    ClipPath(const ClipPath& path) : Path(path) {}
191    ClipPath(const char* path, size_t strLength) : Path(path, strLength) {}
192    ClipPath() : Path() {}
193    ClipPath(const Data& nodes) : Path(nodes) {}
194
195protected:
196    void drawPath(Canvas* outCanvas, const SkPath& renderPath,
197            float strokeScale) override;
198};
199
200class ANDROID_API Group: public Node {
201public:
202    Group(const Group& group);
203    Group() {}
204    float getRotation() {
205        return mRotate;
206    }
207    void setRotation(float rotation) {
208        mRotate = rotation;
209    }
210    float getPivotX() {
211        return mPivotX;
212    }
213    void setPivotX(float pivotX) {
214        mPivotX = pivotX;
215    }
216    float getPivotY() {
217        return mPivotY;
218    }
219    void setPivotY(float pivotY) {
220        mPivotY = pivotY;
221    }
222    float getScaleX() {
223        return mScaleX;
224    }
225    void setScaleX(float scaleX) {
226        mScaleX = scaleX;
227    }
228    float getScaleY() {
229        return mScaleY;
230    }
231    void setScaleY(float scaleY) {
232        mScaleY = scaleY;
233    }
234    float getTranslateX() {
235        return mTranslateX;
236    }
237    void setTranslateX(float translateX) {
238        mTranslateX = translateX;
239    }
240    float getTranslateY() {
241        return mTranslateY;
242    }
243    void setTranslateY(float translateY) {
244        mTranslateY = translateY;
245    }
246    virtual void draw(Canvas* outCanvas, const SkMatrix& currentMatrix,
247            float scaleX, float scaleY) override;
248    void updateLocalMatrix(float rotate, float pivotX, float pivotY,
249            float scaleX, float scaleY, float translateX, float translateY);
250    void getLocalMatrix(SkMatrix* outMatrix);
251    void addChild(Node* child);
252    void dump() override;
253    bool getProperties(float* outProperties, int length);
254
255private:
256    enum class Property {
257        Rotate_Property = 0,
258        PivotX_Property,
259        PivotY_Property,
260        ScaleX_Property,
261        ScaleY_Property,
262        TranslateX_Property,
263        TranslateY_Property,
264        // Count of the properties, must be at the end.
265        Count,
266    };
267    float mRotate = 0;
268    float mPivotX = 0;
269    float mPivotY = 0;
270    float mScaleX = 1;
271    float mScaleY = 1;
272    float mTranslateX = 0;
273    float mTranslateY = 0;
274    std::vector<Node*> mChildren;
275};
276
277class ANDROID_API Tree {
278public:
279    Tree(Group* rootNode) : mRootNode(rootNode) {}
280    void draw(Canvas* outCanvas, SkColorFilter* colorFilter,
281            const SkRect& bounds, bool needsMirroring, bool canReuseCache);
282    void drawCachedBitmapWithRootAlpha(Canvas* outCanvas, SkColorFilter* filter,
283            const SkRect& originalBounds);
284
285    void updateCachedBitmap(int width, int height);
286    void createCachedBitmapIfNeeded(int width, int height);
287    bool canReuseBitmap(int width, int height);
288    void setAllowCaching(bool allowCaching) {
289        mAllowCaching = allowCaching;
290    }
291    bool setRootAlpha(float rootAlpha) {
292        return VD_SET_PROP(mRootAlpha, rootAlpha);
293    }
294
295    float getRootAlpha() {
296        return mRootAlpha;
297    }
298    void setViewportSize(float viewportWidth, float viewportHeight) {
299        mViewportWidth = viewportWidth;
300        mViewportHeight = viewportHeight;
301    }
302
303private:
304    // Cap the bitmap size, such that it won't hurt the performance too much
305    // and it won't crash due to a very large scale.
306    // The drawable will look blurry above this size.
307    const static int MAX_CACHED_BITMAP_SIZE;
308
309    bool mCacheDirty = true;
310    bool mAllowCaching = true;
311    float mViewportWidth = 0;
312    float mViewportHeight = 0;
313    float mRootAlpha = 1.0f;
314
315    Group* mRootNode;
316    SkRect mBounds;
317    SkMatrix mCanvasMatrix;
318    SkPaint mPaint;
319    SkPathMeasure mPathMeasure;
320    SkBitmap mCachedBitmap;
321
322};
323
324} // namespace VectorDrawable
325
326typedef VectorDrawable::Path::Data PathData;
327} // namespace uirenderer
328} // namespace android
329
330#endif // ANDROID_HWUI_VPATH_H
331