1 /*
2  * Copyright 2012 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 SkStrokeRec_DEFINED
9 #define SkStrokeRec_DEFINED
10 
11 #include "SkPaint.h"
12 
13 class SkPath;
14 
15 class SkStrokeRec {
16 public:
17     enum InitStyle {
18         kHairline_InitStyle,
19         kFill_InitStyle
20     };
21     SkStrokeRec(InitStyle style);
22 
23     SkStrokeRec(const SkStrokeRec&);
24     SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
25     explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);
26 
27     enum Style {
28         kHairline_Style,
29         kFill_Style,
30         kStroke_Style,
31         kStrokeAndFill_Style
32     };
33     enum {
34         kStyleCount = kStrokeAndFill_Style + 1
35     };
36 
37     Style getStyle() const;
getWidth()38     SkScalar getWidth() const { return fWidth; }
getMiter()39     SkScalar getMiter() const { return fMiterLimit; }
getCap()40     SkPaint::Cap getCap() const { return fCap; }
getJoin()41     SkPaint::Join getJoin() const { return fJoin; }
42 
isHairlineStyle()43     bool isHairlineStyle() const {
44         return kHairline_Style == this->getStyle();
45     }
46 
isFillStyle()47     bool isFillStyle() const {
48         return kFill_Style == this->getStyle();
49     }
50 
51     void setFillStyle();
52     void setHairlineStyle();
53     /**
54      *  Specify the strokewidth, and optionally if you want stroke + fill.
55      *  Note, if width==0, then this request is taken to mean:
56      *      strokeAndFill==true -> new style will be Fill
57      *      strokeAndFill==false -> new style will be Hairline
58      */
59     void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
60 
setStrokeParams(SkPaint::Cap cap,SkPaint::Join join,SkScalar miterLimit)61     void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
62         fCap = cap;
63         fJoin = join;
64         fMiterLimit = miterLimit;
65     }
66 
setResScale(SkScalar rs)67     void setResScale(SkScalar rs) {
68         SkASSERT(rs > 0 && SkScalarIsFinite(rs));
69         fResScale = rs;
70     }
71 
72     /**
73      *  Returns true if this specifes any thick stroking, i.e. applyToPath()
74      *  will return true.
75      */
needToApply()76     bool needToApply() const {
77         Style style = this->getStyle();
78         return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
79     }
80 
81     /**
82      *  Apply these stroke parameters to the src path, returning the result
83      *  in dst.
84      *
85      *  If there was no change (i.e. style == hairline or fill) this returns
86      *  false and dst is unchanged. Otherwise returns true and the result is
87      *  stored in dst.
88      *
89      *  src and dst may be the same path.
90      */
91     bool applyToPath(SkPath* dst, const SkPath& src) const;
92 
93     /**
94      *  Apply these stroke parameters to a paint.
95      */
96     void applyToPaint(SkPaint* paint) const;
97 
98     /**
99      * Compare if two SkStrokeRecs have an equal effect on a path.
100      * Equal SkStrokeRecs produce equal paths. Equality of produced
101      * paths does not take the ResScale parameter into account.
102      */
hasEqualEffect(const SkStrokeRec & other)103     bool hasEqualEffect(const SkStrokeRec& other) const {
104         if (!this->needToApply()) {
105             return this->getStyle() == other.getStyle();
106         }
107         return fWidth == other.fWidth &&
108                fMiterLimit == other.fMiterLimit &&
109                fCap == other.fCap &&
110                fJoin == other.fJoin &&
111                fStrokeAndFill == other.fStrokeAndFill;
112     }
113 
114 private:
115     void init(const SkPaint&, SkPaint::Style, SkScalar resScale);
116 
117     SkScalar        fResScale;
118     SkScalar        fWidth;
119     SkScalar        fMiterLimit;
120     SkPaint::Cap    fCap;
121     SkPaint::Join   fJoin;
122     bool            fStrokeAndFill;
123 };
124 
125 #endif
126