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