Flutter Engine
The Flutter Engine
GrStyle.h
Go to the documentation of this file.
1/*
2 * Copyright 2016 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 GrStyle_DEFINED
9#define GrStyle_DEFINED
10
13#include "include/gpu/GrTypes.h"
16
17/**
18 * Represents the various ways that a GrStyledShape can be styled. It has fill/stroking information
19 * as well as an optional path effect. If the path effect represents dashing, the dashing
20 * information is extracted from the path effect and stored explicitly.
21 *
22 * This will replace GrStrokeInfo as GrStyledShape is deployed.
23 */
24class GrStyle {
25public:
26 /**
27 * A style object that represents a fill with no path effect.
28 * TODO: constexpr with C++14
29 */
30 static const GrStyle& SimpleFill() {
32 return kFill;
33 }
34
35 /**
36 * A style object that represents a hairline stroke with no path effect.
37 * TODO: constexpr with C++14
38 */
39 static const GrStyle& SimpleHairline() {
41 return kHairline;
42 }
43
44 enum class Apply {
45 kPathEffectOnly,
46 kPathEffectAndStrokeRec
47 };
48
49 /**
50 * Optional flags for computing keys that may remove unnecessary variation in the key due to
51 * style settings that don't affect particular classes of geometry.
52 */
53 enum KeyFlags {
54 // The shape being styled has no open contours.
56 // The shape being styled doesn't have any joins and so isn't affected by join type.
58 };
59
60 /**
61 * Computes the key length for a GrStyle. The return will be negative if it cannot be turned
62 * into a key. This occurs when there is a path effect that is not a dash. The key can
63 * either reflect just the path effect (if one) or the path effect and the strokerec. Note
64 * that a simple fill has a zero sized key.
65 */
66 static int KeySize(const GrStyle&, Apply, uint32_t flags = 0);
67
68 /**
69 * Writes a unique key for the style into the provided buffer. This function assumes the buffer
70 * has room for at least KeySize() values. It assumes that KeySize() returns a non-negative
71 * value for the combination of GrStyle, Apply and flags params. This is written so that the key
72 * for just dash application followed by the key for the remaining SkStrokeRec is the same as
73 * the key for applying dashing and SkStrokeRec all at once.
74 */
75 static void WriteKey(uint32_t*, const GrStyle&, Apply, SkScalar scale, uint32_t flags = 0);
76
77 GrStyle() : GrStyle(SkStrokeRec::kFill_InitStyle) {}
78
79 explicit GrStyle(SkStrokeRec::InitStyle initStyle) : fStrokeRec(initStyle) {}
80
82 this->initPathEffect(std::move(pe));
83 }
84
85 GrStyle(const GrStyle& that) = default;
86
87 explicit GrStyle(const SkPaint& paint) : fStrokeRec(paint) {
88 this->initPathEffect(paint.refPathEffect());
89 }
90
91 explicit GrStyle(const SkPaint& paint, SkPaint::Style overrideStyle)
92 : fStrokeRec(paint, overrideStyle) {
93 this->initPathEffect(paint.refPathEffect());
94 }
95
96 GrStyle& operator=(const GrStyle& that) {
97 fPathEffect = that.fPathEffect;
98 fDashInfo = that.fDashInfo;
99 fStrokeRec = that.fStrokeRec;
100 return *this;
101 }
102
104 fDashInfo.reset();
105 fPathEffect.reset(nullptr);
106 if (SkStrokeRec::kFill_InitStyle == fillOrHairline) {
107 fStrokeRec.setFillStyle();
108 } else {
109 fStrokeRec.setHairlineStyle();
110 }
111 }
112
113 /** Is this style a fill with no path effect? */
114 bool isSimpleFill() const { return fStrokeRec.isFillStyle() && !fPathEffect; }
115
116 /** Is this style a hairline with no path effect? */
117 bool isSimpleHairline() const { return fStrokeRec.isHairlineStyle() && !fPathEffect; }
118
119 SkPathEffect* pathEffect() const { return fPathEffect.get(); }
120 sk_sp<SkPathEffect> refPathEffect() const { return fPathEffect; }
121
122 bool hasPathEffect() const { return SkToBool(fPathEffect.get()); }
123
124 bool hasNonDashPathEffect() const { return fPathEffect.get() && !this->isDashed(); }
125
126 bool isDashed() const { return SkPathEffect::kDash_DashType == fDashInfo.fType; }
128 SkASSERT(this->isDashed());
129 return fDashInfo.fPhase;
130 }
131 int dashIntervalCnt() const {
132 SkASSERT(this->isDashed());
133 return fDashInfo.fIntervals.count();
134 }
135 const SkScalar* dashIntervals() const {
136 SkASSERT(this->isDashed());
137 return fDashInfo.fIntervals.get();
138 }
139
140 const SkStrokeRec& strokeRec() const { return fStrokeRec; }
141
142 /** Hairline or fill styles without path effects make no alterations to a geometry. */
143 bool applies() const {
144 return this->pathEffect() || (!fStrokeRec.isFillStyle() && !fStrokeRec.isHairlineStyle());
145 }
146
148 // getMaxScale will return -1 if the matrix has perspective. In that case we can use a scale
149 // factor of 1. This isn't necessarily a good choice and in the future we might consider
150 // taking a bounds here for the perspective case.
151 return SkScalarAbs(matrix.getMaxScale());
152 }
153 /**
154 * Applies just the path effect and returns remaining stroke information. This will fail if
155 * there is no path effect. dst may or may not have been overwritten on failure. Scale controls
156 * geometric approximations made by the path effect. It is typically computed from the view
157 * matrix.
158 */
159 [[nodiscard]] bool applyPathEffectToPath(SkPath* dst, SkStrokeRec* remainingStoke,
160 const SkPath& src, SkScalar scale) const;
161
162 /**
163 * If this succeeds then the result path should be filled or hairlined as indicated by the
164 * returned SkStrokeRec::InitStyle value. Will fail if there is no path effect and the
165 * strokerec doesn't change the geometry. When this fails the outputs may or may not have
166 * been overwritten. Scale controls geometric approximations made by the path effect and
167 * stroker. It is typically computed from the view matrix.
168 */
169 [[nodiscard]] bool applyToPath(SkPath* dst, SkStrokeRec::InitStyle* fillOrHairline,
170 const SkPath& src, SkScalar scale) const;
171
172 /** Given bounds of a path compute the bounds of path with the style applied. */
173 void adjustBounds(SkRect* dst, const SkRect& src) const {
174 *dst = src;
175 auto pe = as_PEB(this->pathEffect());
176 if (pe && !pe->computeFastBounds(dst)) {
177 // Restore dst == src since ComputeFastBounds leaves it undefined when returning false
178 *dst = src;
179 }
180
181 // This may not be the correct SkStrokeRec to use if there's a path effect: skbug.com/5299
182 // It happens to work for dashing.
183 SkScalar radius = fStrokeRec.getInflationRadius();
184 dst->outset(radius, radius);
185 }
186
187private:
188 void initPathEffect(sk_sp<SkPathEffect> pe);
189
190 struct DashInfo {
191 DashInfo() : fType(SkPathEffectBase::kNone_DashType) {}
192 DashInfo(const DashInfo& that) { *this = that; }
193 DashInfo& operator=(const DashInfo& that) {
194 fType = that.fType;
195 fPhase = that.fPhase;
196 fIntervals.reset(that.fIntervals.count());
197 sk_careful_memcpy(fIntervals.get(), that.fIntervals.get(),
198 sizeof(SkScalar) * that.fIntervals.count());
199 return *this;
200 }
201 void reset() {
203 fIntervals.reset(0);
204 }
206 SkScalar fPhase{0};
208 };
209
210 bool applyPathEffect(SkPath* dst, SkStrokeRec* strokeRec, const SkPath& src) const;
211
212 SkStrokeRec fStrokeRec;
213 sk_sp<SkPathEffect> fPathEffect;
214 DashInfo fDashInfo;
215};
216
217#endif
SkScalar fIntervals[2]
Definition: DashOp.cpp:190
SkScalar fPhase
Definition: DashOp.cpp:189
m reset()
#define SkASSERT(cond)
Definition: SkAssert.h:116
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
Definition: SkMalloc.h:125
static SkPathEffectBase * as_PEB(SkPathEffect *effect)
#define SkScalarAbs(x)
Definition: SkScalar.h:39
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
bool isDashed() const
Definition: GrStyle.h:126
KeyFlags
Definition: GrStyle.h:53
@ kNoJoins_KeyFlag
Definition: GrStyle.h:57
@ kClosed_KeyFlag
Definition: GrStyle.h:55
static const GrStyle & SimpleHairline()
Definition: GrStyle.h:39
void adjustBounds(SkRect *dst, const SkRect &src) const
Definition: GrStyle.h:173
const SkScalar * dashIntervals() const
Definition: GrStyle.h:135
bool applyToPath(SkPath *dst, SkStrokeRec::InitStyle *fillOrHairline, const SkPath &src, SkScalar scale) const
Definition: GrStyle.cpp:175
GrStyle(const SkPaint &paint, SkPaint::Style overrideStyle)
Definition: GrStyle.h:91
GrStyle(const SkStrokeRec &strokeRec, sk_sp< SkPathEffect > pe)
Definition: GrStyle.h:81
SkPathEffect * pathEffect() const
Definition: GrStyle.h:119
bool isSimpleHairline() const
Definition: GrStyle.h:117
bool hasPathEffect() const
Definition: GrStyle.h:122
static void WriteKey(uint32_t *, const GrStyle &, Apply, SkScalar scale, uint32_t flags=0)
Definition: GrStyle.cpp:33
static const GrStyle & SimpleFill()
Definition: GrStyle.h:30
GrStyle & operator=(const GrStyle &that)
Definition: GrStyle.h:96
bool hasNonDashPathEffect() const
Definition: GrStyle.h:124
bool applies() const
Definition: GrStyle.h:143
GrStyle(const GrStyle &that)=default
GrStyle(const SkPaint &paint)
Definition: GrStyle.h:87
int dashIntervalCnt() const
Definition: GrStyle.h:131
bool applyPathEffectToPath(SkPath *dst, SkStrokeRec *remainingStoke, const SkPath &src, SkScalar scale) const
Definition: GrStyle.cpp:163
static SkScalar MatrixToScaleFactor(const SkMatrix &matrix)
Definition: GrStyle.h:147
GrStyle(SkStrokeRec::InitStyle initStyle)
Definition: GrStyle.h:79
bool isSimpleFill() const
Definition: GrStyle.h:114
void resetToInitStyle(SkStrokeRec::InitStyle fillOrHairline)
Definition: GrStyle.h:103
SkScalar dashPhase() const
Definition: GrStyle.h:127
static int KeySize(const GrStyle &, Apply, uint32_t flags=0)
Definition: GrStyle.cpp:11
sk_sp< SkPathEffect > refPathEffect() const
Definition: GrStyle.h:120
GrStyle()
Definition: GrStyle.h:77
const SkStrokeRec & strokeRec() const
Definition: GrStyle.h:140
@ kNone_DashType
ignores the info parameter
Definition: SkPathEffect.h:61
@ kDash_DashType
fills in all of the info parameter
Definition: SkPathEffect.h:62
Definition: SkPath.h:59
@ kHairline_InitStyle
Definition: SkStrokeRec.h:25
void setHairlineStyle()
Definition: SkStrokeRec.cpp:86
void setFillStyle()
Definition: SkStrokeRec.cpp:81
SkScalar getInflationRadius() const
bool isHairlineStyle() const
Definition: SkStrokeRec.h:47
bool isFillStyle() const
Definition: SkStrokeRec.h:51
T * get() const
Definition: SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
FlutterSemanticsFlag flags
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
dst
Definition: cp.py:12
const Scalar scale