1/*
2 * Copyright 2014 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#ifndef GrStrokeInfo_DEFINED
9#define GrStrokeInfo_DEFINED
10
11#include "SkStrokeRec.h"
12#include "SkPathEffect.h"
13
14/*
15 * GrStrokeInfo encapsulates the data objects that hold all the pertinent infomation
16 * regarding the stroke. The two objects are SkStrokeRec which holds information on fill style,
17 * width, miter, cap, and join. The second object is DashInfo. This holds information about the
18 * dash like intervals, count, and phase.
19 */
20class GrStrokeInfo {
21public:
22    GrStrokeInfo(SkStrokeRec::InitStyle style) :
23        fStroke(style), fDashType(SkPathEffect::kNone_DashType) {}
24
25    GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) {
26        if (includeDash) {
27            fDashInfo = src.fDashInfo;
28            fDashType = src.fDashType;
29            fIntervals.reset(src.dashCount());
30            memcpy(fIntervals.get(), src.fIntervals.get(), src.dashCount() * sizeof(SkScalar));
31        } else {
32            fDashType = SkPathEffect::kNone_DashType;
33        }
34    }
35
36    GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride) :
37        fStroke(paint, styleOverride), fDashType(SkPathEffect::kNone_DashType) {
38        this->init(paint);
39    }
40
41
42    explicit GrStrokeInfo(const SkPaint& paint) :
43        fStroke(paint), fDashType(SkPathEffect::kNone_DashType) {
44        this->init(paint);
45    }
46
47    const SkStrokeRec& getStrokeRec() const { return fStroke; }
48
49    SkStrokeRec* getStrokeRecPtr() { return &fStroke; }
50
51    void setFillStyle() { fStroke.setFillStyle(); }
52
53    /*
54     * This functions takes in a patheffect and fills in fDashInfo with the various dashing
55     * information if the path effect is a Dash type. Returns true if the path effect is a
56     * dashed effect and we are stroking, otherwise it retruns false.
57     */
58    bool setDashInfo(const SkPathEffect* pe) {
59        if (NULL != pe && !fStroke.isFillStyle()) {
60            fDashInfo.fIntervals = NULL;
61            fDashType = pe->asADash(&fDashInfo);
62            if (SkPathEffect::kDash_DashType == fDashType) {
63                fIntervals.reset(fDashInfo.fCount);
64                fDashInfo.fIntervals = fIntervals.get();
65                pe->asADash(&fDashInfo);
66                return true;
67            }
68        }
69        return false;
70    }
71
72    bool isDashed() const {
73        return (!fStroke.isFillStyle() && SkPathEffect::kDash_DashType == fDashType);
74    }
75
76    int32_t dashCount() const {
77        return fDashInfo.fCount;
78    }
79
80    void removeDash() {
81        fDashType = SkPathEffect::kNone_DashType;
82    }
83
84    const SkPathEffect::DashInfo& getDashInfo() const { return fDashInfo; }
85
86private:
87
88    void init(const SkPaint& paint) {
89        const SkPathEffect* pe = paint.getPathEffect();
90        this->setDashInfo(pe);
91    }
92
93    SkStrokeRec            fStroke;
94    SkPathEffect::DashType fDashType;
95    SkPathEffect::DashInfo fDashInfo;
96    SkAutoSTArray<2, SkScalar> fIntervals;
97};
98
99#endif
100