Line data Source code
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 : SK_BEGIN_REQUIRE_DENSE
16 : class SkStrokeRec {
17 : public:
18 : enum InitStyle {
19 : kHairline_InitStyle,
20 : kFill_InitStyle
21 : };
22 : SkStrokeRec(InitStyle style);
23 : SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
24 : explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);
25 :
26 : enum Style {
27 : kHairline_Style,
28 : kFill_Style,
29 : kStroke_Style,
30 : kStrokeAndFill_Style
31 : };
32 : enum {
33 : kStyleCount = kStrokeAndFill_Style + 1
34 : };
35 :
36 : Style getStyle() const;
37 0 : SkScalar getWidth() const { return fWidth; }
38 0 : SkScalar getMiter() const { return fMiterLimit; }
39 0 : SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
40 0 : SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }
41 :
42 15 : bool isHairlineStyle() const {
43 15 : return kHairline_Style == this->getStyle();
44 : }
45 :
46 0 : bool isFillStyle() const {
47 0 : return kFill_Style == this->getStyle();
48 : }
49 :
50 : void setFillStyle();
51 : void setHairlineStyle();
52 : /**
53 : * Specify the strokewidth, and optionally if you want stroke + fill.
54 : * Note, if width==0, then this request is taken to mean:
55 : * strokeAndFill==true -> new style will be Fill
56 : * strokeAndFill==false -> new style will be Hairline
57 : */
58 : void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
59 :
60 0 : void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
61 0 : fCap = cap;
62 0 : fJoin = join;
63 0 : fMiterLimit = miterLimit;
64 0 : }
65 :
66 0 : SkScalar getResScale() const {
67 0 : return fResScale;
68 : }
69 :
70 0 : void setResScale(SkScalar rs) {
71 0 : SkASSERT(rs > 0 && SkScalarIsFinite(rs));
72 0 : fResScale = rs;
73 0 : }
74 :
75 : /**
76 : * Returns true if this specifes any thick stroking, i.e. applyToPath()
77 : * will return true.
78 : */
79 0 : bool needToApply() const {
80 0 : Style style = this->getStyle();
81 0 : return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
82 : }
83 :
84 : /**
85 : * Apply these stroke parameters to the src path, returning the result
86 : * in dst.
87 : *
88 : * If there was no change (i.e. style == hairline or fill) this returns
89 : * false and dst is unchanged. Otherwise returns true and the result is
90 : * stored in dst.
91 : *
92 : * src and dst may be the same path.
93 : */
94 : bool applyToPath(SkPath* dst, const SkPath& src) const;
95 :
96 : /**
97 : * Apply these stroke parameters to a paint.
98 : */
99 : void applyToPaint(SkPaint* paint) const;
100 :
101 : /**
102 : * Gives a conservative value for the outset that should applied to a
103 : * geometries bounds to account for any inflation due to applying this
104 : * strokeRec to the geometry.
105 : */
106 : SkScalar getInflationRadius() const;
107 :
108 : /**
109 : * Equivalent to:
110 : * SkStrokeRec rec(paint, style);
111 : * rec.getInflationRadius();
112 : * This does not account for other effects on the paint (i.e. path
113 : * effect).
114 : */
115 : static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style);
116 :
117 : /**
118 : * Compare if two SkStrokeRecs have an equal effect on a path.
119 : * Equal SkStrokeRecs produce equal paths. Equality of produced
120 : * paths does not take the ResScale parameter into account.
121 : */
122 : bool hasEqualEffect(const SkStrokeRec& other) const {
123 : if (!this->needToApply()) {
124 : return this->getStyle() == other.getStyle();
125 : }
126 : return fWidth == other.fWidth &&
127 : fMiterLimit == other.fMiterLimit &&
128 : fCap == other.fCap &&
129 : fJoin == other.fJoin &&
130 : fStrokeAndFill == other.fStrokeAndFill;
131 : }
132 :
133 : private:
134 : void init(const SkPaint&, SkPaint::Style, SkScalar resScale);
135 :
136 : SkScalar fResScale;
137 : SkScalar fWidth;
138 : SkScalar fMiterLimit;
139 : // The following three members are packed together into a single u32.
140 : // This is to avoid unnecessary padding and ensure binary equality for
141 : // hashing (because the padded areas might contain garbage values).
142 : //
143 : // fCap and fJoin are larger than needed to avoid having to initialize
144 : // any pad values
145 : uint32_t fCap : 16; // SkPaint::Cap
146 : uint32_t fJoin : 15; // SkPaint::Join
147 : uint32_t fStrokeAndFill : 1; // bool
148 : };
149 : SK_END_REQUIRE_DENSE
150 :
151 : #endif
|