aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrStrokeInfo.h
blob: f008dc6a5d27183cb7da349a0cc22daddd21b9ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrStrokeInfo_DEFINED
#define GrStrokeInfo_DEFINED

#include "SkStrokeRec.h"
#include "SkPathEffect.h"

/*
 * GrStrokeInfo encapsulates the data objects that hold all the pertinent infomation
 * regarding the stroke. The two objects are SkStrokeRec which holds information on fill style,
 * width, miter, cap, and join. The second object is DashInfo. This holds information about the
 * dash like intervals, count, and phase.
 */
class GrStrokeInfo {
public: 
    GrStrokeInfo(SkStrokeRec::InitStyle style) :
        fStroke(style), fDashType(SkPathEffect::kNone_DashType) {}

    GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) {
        if (includeDash) {
            fDashInfo = src.fDashInfo;
            fDashType = src.fDashType;
            fIntervals.reset(src.dashCount());
            memcpy(fIntervals.get(), src.fIntervals.get(), src.dashCount() * sizeof(SkScalar));
        } else {
            fDashType = SkPathEffect::kNone_DashType;
        }
    }

    GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride) :
        fStroke(paint, styleOverride), fDashType(SkPathEffect::kNone_DashType) {
        this->init(paint);
    }

    explicit GrStrokeInfo(const SkPaint& paint) :
        fStroke(paint), fDashType(SkPathEffect::kNone_DashType) {
        this->init(paint);
    }

    GrStrokeInfo& operator=(const GrStrokeInfo& other) {
        fStroke = other.fStroke;
        fDashInfo = other.fDashInfo;
        fDashType = other.fDashType;
        fIntervals.reset(other.dashCount());
        memcpy(fIntervals.get(), other.fIntervals.get(), other.dashCount() * sizeof(SkScalar));
        return *this;
    }

    const SkStrokeRec& getStrokeRec() const { return fStroke; }

    SkStrokeRec* getStrokeRecPtr() { return &fStroke; }

    void setFillStyle() { fStroke.setFillStyle(); }

    /*
     * This functions takes in a patheffect and fills in fDashInfo with the various dashing
     * information if the path effect is a Dash type. Returns true if the path effect is a
     * dashed effect and we are stroking, otherwise it retruns false.
     */
    bool setDashInfo(const SkPathEffect* pe) {
        if (pe && !fStroke.isFillStyle()) {
            fDashInfo.fIntervals = NULL;
            fDashType = pe->asADash(&fDashInfo);
            if (SkPathEffect::kDash_DashType == fDashType) {
                fIntervals.reset(fDashInfo.fCount);
                fDashInfo.fIntervals = fIntervals.get();
                pe->asADash(&fDashInfo);
                return true;
            }
        }
        return false;
    }

    /*
     * Like the above, but sets with an explicit SkPathEffect::DashInfo
     */
    bool setDashInfo(const SkPathEffect::DashInfo& info) {
        if (!fStroke.isFillStyle()) {
            SkASSERT(!fStroke.isFillStyle());
            fDashInfo.fCount = info.fCount;
            fDashInfo.fPhase = info.fPhase;
            fIntervals.reset(info.fCount);
            for (int i = 0; i < info.fCount; i++) {
                fIntervals[i] = info.fIntervals[i];
            }
            fDashInfo.fIntervals = fIntervals.get();
            return true;
        }
        return false;
    }

    bool isDashed() const {
        return (!fStroke.isFillStyle() && SkPathEffect::kDash_DashType == fDashType);
    }

    bool isFillStyle() const { return fStroke.isFillStyle(); }

    int32_t dashCount() const {
        return fDashInfo.fCount;
    }

    void removeDash() {
        fDashType = SkPathEffect::kNone_DashType;
    }
    
    const SkPathEffect::DashInfo& getDashInfo() const { return fDashInfo; }

    /** Applies the dash to a path, if the stroke info has dashing.
     * @return true if the dash ingwas applied (dst and dstStrokeInfo will be modified).
     *         false if the stroke info did not have dashing. The dst and dstStrokeInfo
     *               will be unmodified. The stroking in the SkStrokeRec might still
     *               be applicable.
     */
    bool applyDash(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const;

private:

    void init(const SkPaint& paint) {
        const SkPathEffect* pe = paint.getPathEffect();
        this->setDashInfo(pe);
    }

    SkStrokeRec            fStroke;
    SkPathEffect::DashType fDashType;
    SkPathEffect::DashInfo fDashInfo;
    SkAutoSTArray<2, SkScalar> fIntervals;
};

#endif