Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: src/gpu/GrShape.h

Issue 2056523002: Make GrShape capable of representing inverse filled rrects. (Closed) Base URL: https://chromium.googlesource.com/skia.git@faildashstrokeandfill
Patch Set: Fix windows warning Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/gpu/GrShape.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef GrShape_DEFINED 8 #ifndef GrShape_DEFINED
9 #define GrShape_DEFINED 9 #define GrShape_DEFINED
10 10
(...skipping 26 matching lines...) Expand all
37 GrShape() : fType(Type::kEmpty) {} 37 GrShape() : fType(Type::kEmpty) {}
38 38
39 explicit GrShape(const SkPath& path) 39 explicit GrShape(const SkPath& path)
40 : fType(Type::kPath) 40 : fType(Type::kPath)
41 , fPath(&path) { 41 , fPath(&path) {
42 this->attemptToReduceFromPath(); 42 this->attemptToReduceFromPath();
43 } 43 }
44 44
45 explicit GrShape(const SkRRect& rrect) 45 explicit GrShape(const SkRRect& rrect)
46 : fType(Type::kRRect) 46 : fType(Type::kRRect)
47 , fRRect(rrect) { 47 , fRRect(rrect)
48 , fRRectIsInverted(false) {
48 fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir); 49 fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir);
49 this->attemptToReduceFromRRect(); 50 this->attemptToReduceFromRRect();
50 } 51 }
51 52
52 explicit GrShape(const SkRect& rect) 53 explicit GrShape(const SkRect& rect)
53 : fType(Type::kRRect) 54 : fType(Type::kRRect)
54 , fRRect(SkRRect::MakeRect(rect)) { 55 , fRRect(SkRRect::MakeRect(rect))
56 , fRRectIsInverted(false) {
55 fRRectStart = DefaultRectDirAndStartIndex(rect, false, &fRRectDir); 57 fRRectStart = DefaultRectDirAndStartIndex(rect, false, &fRRectDir);
56 this->attemptToReduceFromRRect(); 58 this->attemptToReduceFromRRect();
57 } 59 }
58 60
59 GrShape(const SkPath& path, const GrStyle& style) 61 GrShape(const SkPath& path, const GrStyle& style)
60 : fType(Type::kPath) 62 : fType(Type::kPath)
61 , fPath(&path) 63 , fPath(&path)
62 , fStyle(style) { 64 , fStyle(style) {
63 this->attemptToReduceFromPath(); 65 this->attemptToReduceFromPath();
64 } 66 }
65 67
66 GrShape(const SkRRect& rrect, const GrStyle& style) 68 GrShape(const SkRRect& rrect, const GrStyle& style)
67 : fType(Type::kRRect) 69 : fType(Type::kRRect)
68 , fRRect(rrect) 70 , fRRect(rrect)
71 , fRRectIsInverted(false)
69 , fStyle(style) { 72 , fStyle(style) {
70 fRRectStart = DefaultRRectDirAndStartIndex(rrect, style.hasPathEffect(), &fRRectDir); 73 fRRectStart = DefaultRRectDirAndStartIndex(rrect, style.hasPathEffect(), &fRRectDir);
71 this->attemptToReduceFromRRect(); 74 this->attemptToReduceFromRRect();
72 } 75 }
73 76
74 GrShape(const SkRRect& rrect, SkPath::Direction dir, unsigned start, const G rStyle& style) 77 GrShape(const SkRRect& rrect, SkPath::Direction dir, unsigned start, bool in verted,
78 const GrStyle& style)
75 : fType(Type::kRRect) 79 : fType(Type::kRRect)
76 , fRRect(rrect) 80 , fRRect(rrect)
81 , fRRectIsInverted(inverted)
77 , fStyle(style) { 82 , fStyle(style) {
78 if (style.pathEffect()) { 83 if (style.pathEffect()) {
79 fRRectDir = dir; 84 fRRectDir = dir;
80 fRRectStart = start; 85 fRRectStart = start;
86 if (fRRect.getType() == SkRRect::kRect_Type) {
87 fRRectStart = (fRRectStart + 1) & 0b110;
88 } else if (fRRect.getType() == SkRRect::kOval_Type) {
89 fRRectStart &= 0b110;
90 }
81 } else { 91 } else {
82 fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir) ; 92 fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir) ;
83 } 93 }
84 this->attemptToReduceFromRRect(); 94 this->attemptToReduceFromRRect();
85 } 95 }
86 96
87 GrShape(const SkRect& rect, const GrStyle& style) 97 GrShape(const SkRect& rect, const GrStyle& style)
88 : fType(Type::kRRect) 98 : fType(Type::kRRect)
89 , fRRect(SkRRect::MakeRect(rect)) 99 , fRRect(SkRRect::MakeRect(rect))
100 , fRRectIsInverted(false)
90 , fStyle(style) { 101 , fStyle(style) {
91 fRRectStart = DefaultRectDirAndStartIndex(rect, style.hasPathEffect(), & fRRectDir); 102 fRRectStart = DefaultRectDirAndStartIndex(rect, style.hasPathEffect(), & fRRectDir);
92 this->attemptToReduceFromRRect(); 103 this->attemptToReduceFromRRect();
93 } 104 }
94 105
95 GrShape(const SkPath& path, const SkPaint& paint) 106 GrShape(const SkPath& path, const SkPaint& paint)
96 : fType(Type::kPath) 107 : fType(Type::kPath)
97 , fPath(&path) 108 , fPath(&path)
98 , fStyle(paint) { 109 , fStyle(paint) {
99 this->attemptToReduceFromPath(); 110 this->attemptToReduceFromPath();
100 } 111 }
101 112
102 GrShape(const SkRRect& rrect, const SkPaint& paint) 113 GrShape(const SkRRect& rrect, const SkPaint& paint)
103 : fType(Type::kRRect) 114 : fType(Type::kRRect)
104 , fRRect(rrect) 115 , fRRect(rrect)
116 , fRRectIsInverted(false)
105 , fStyle(paint) { 117 , fStyle(paint) {
106 fRRectStart = DefaultRRectDirAndStartIndex(rrect, fStyle.hasPathEffect() , &fRRectDir); 118 fRRectStart = DefaultRRectDirAndStartIndex(rrect, fStyle.hasPathEffect() , &fRRectDir);
107 this->attemptToReduceFromRRect(); 119 this->attemptToReduceFromRRect();
108 } 120 }
109 121
110 GrShape(const SkRect& rect, const SkPaint& paint) 122 GrShape(const SkRect& rect, const SkPaint& paint)
111 : fType(Type::kRRect) 123 : fType(Type::kRRect)
112 , fRRect(SkRRect::MakeRect(rect)) 124 , fRRect(SkRRect::MakeRect(rect))
125 , fRRectIsInverted(false)
113 , fStyle(paint) { 126 , fStyle(paint) {
114 fRRectStart = DefaultRectDirAndStartIndex(rect, fStyle.hasPathEffect(), &fRRectDir); 127 fRRectStart = DefaultRectDirAndStartIndex(rect, fStyle.hasPathEffect(), &fRRectDir);
115 this->attemptToReduceFromRRect(); 128 this->attemptToReduceFromRRect();
116 } 129 }
117 130
118 GrShape(const GrShape&); 131 GrShape(const GrShape&);
119 GrShape& operator=(const GrShape& that); 132 GrShape& operator=(const GrShape& that);
120 133
121 ~GrShape() { 134 ~GrShape() {
122 if (Type::kPath == fType) { 135 if (Type::kPath == fType) {
123 fPath.reset(); 136 fPath.reset();
124 } 137 }
125 } 138 }
126 139
127 const GrStyle& style() const { return fStyle; } 140 const GrStyle& style() const { return fStyle; }
128 141
129 /** 142 /**
130 * Returns a shape that has either applied the path effect or path effect an d stroking 143 * Returns a shape that has either applied the path effect or path effect an d stroking
131 * information from this shape's style to its geometry. Scale is used when a pproximating the 144 * information from this shape's style to its geometry. Scale is used when a pproximating the
132 * output geometry and typically is computed from the view matrix 145 * output geometry and typically is computed from the view matrix
133 */ 146 */
134 GrShape applyStyle(GrStyle::Apply apply, SkScalar scale) { 147 GrShape applyStyle(GrStyle::Apply apply, SkScalar scale) {
135 return GrShape(*this, apply, scale); 148 return GrShape(*this, apply, scale);
136 } 149 }
137 150
138 /** Returns the unstyled geometry as a rrect if possible. */ 151 /** Returns the unstyled geometry as a rrect if possible. */
139 bool asRRect(SkRRect* rrect, SkPath::Direction* dir, unsigned* start) const { 152 bool asRRect(SkRRect* rrect, SkPath::Direction* dir, unsigned* start, bool* inverted) const {
140 if (Type::kRRect != fType) { 153 if (Type::kRRect != fType) {
141 return false; 154 return false;
142 } 155 }
143 if (rrect) { 156 if (rrect) {
144 *rrect = fRRect; 157 *rrect = fRRect;
145 } 158 }
146 if (dir) { 159 if (dir) {
147 *dir = fRRectDir; 160 *dir = fRRectDir;
148 } 161 }
149 if (start) { 162 if (start) {
150 *start = fRRectStart; 163 *start = fRRectStart;
151 } 164 }
165 if (inverted) {
166 *inverted = fRRectIsInverted;
167 }
152 return true; 168 return true;
153 } 169 }
154 170
155 /** Returns the unstyled geometry as a path. */ 171 /** Returns the unstyled geometry as a path. */
156 void asPath(SkPath* out) const { 172 void asPath(SkPath* out) const {
157 switch (fType) { 173 switch (fType) {
158 case Type::kEmpty: 174 case Type::kEmpty:
159 out->reset(); 175 out->reset();
160 break; 176 break;
161 case Type::kRRect: 177 case Type::kRRect:
162 out->reset(); 178 out->reset();
163 out->addRRect(fRRect, fRRectDir, fRRectStart); 179 out->addRRect(fRRect, fRRectDir, fRRectStart);
180 if (fRRectIsInverted) {
181 out->setFillType(SkPath::kInverseWinding_FillType);
182 }
164 break; 183 break;
165 case Type::kPath: 184 case Type::kPath:
166 *out = *fPath.get(); 185 *out = *fPath.get();
167 break; 186 break;
168 } 187 }
169 } 188 }
170 189
171 /** 190 /**
172 * Returns whether the geometry is empty. Note that applying the style could produce a 191 * Returns whether the geometry is empty. Note that applying the style could produce a
173 * non-empty shape. 192 * non-empty shape.
174 */ 193 */
175 bool isEmpty() const { return Type::kEmpty == fType; } 194 bool isEmpty() const { return Type::kEmpty == fType; }
176 195
177 /** Gets the bounds of the geometry without reflecting the shape's styling. */ 196 /**
197 * Gets the bounds of the geometry without reflecting the shape's styling. T his ignores
198 * the inverse fill nature of the geometry.
199 */
178 const SkRect& bounds() const; 200 const SkRect& bounds() const;
179 201
180 /** Gets the bounds of the geometry reflecting the shape's styling. */ 202 /**
203 * Gets the bounds of the geometry reflecting the shape's styling (ignoring inverse fill
204 * status).
205 */
181 void styledBounds(SkRect* bounds) const; 206 void styledBounds(SkRect* bounds) const;
182 207
183 /** 208 /**
184 * Is it known that the unstyled geometry has no unclosed contours. This mea ns that it will 209 * Is it known that the unstyled geometry has no unclosed contours. This mea ns that it will
185 * not have any caps if stroked (modulo the effect of any path effect). 210 * not have any caps if stroked (modulo the effect of any path effect).
186 */ 211 */
187 bool knownToBeClosed() const { 212 bool knownToBeClosed() const {
188 switch (fType) { 213 switch (fType) {
189 case Type::kEmpty: 214 case Type::kEmpty:
190 return true; 215 return true;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 263
239 /** 264 /**
240 * Determines the key we should inherit from the input shape's geometry and style when 265 * Determines the key we should inherit from the input shape's geometry and style when
241 * we are applying the style to create a new shape. 266 * we are applying the style to create a new shape.
242 */ 267 */
243 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc ale); 268 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc ale);
244 269
245 void attemptToReduceFromPath() { 270 void attemptToReduceFromPath() {
246 SkASSERT(Type::kPath == fType); 271 SkASSERT(Type::kPath == fType);
247 fType = AttemptToReduceFromPathImpl(*fPath.get(), &fRRect, &fRRectDir, & fRRectStart, 272 fType = AttemptToReduceFromPathImpl(*fPath.get(), &fRRect, &fRRectDir, & fRRectStart,
248 fStyle.pathEffect(), fStyle.strokeRe c()); 273 &fRRectIsInverted, fStyle.pathEffect (),
274 fStyle.strokeRec());
249 if (Type::kPath != fType) { 275 if (Type::kPath != fType) {
250 fPath.reset(); 276 fPath.reset();
251 fInheritedKey.reset(0); 277 fInheritedKey.reset(0);
252 } 278 }
253 } 279 }
254 280
255 void attemptToReduceFromRRect() { 281 void attemptToReduceFromRRect() {
256 SkASSERT(Type::kRRect == fType); 282 SkASSERT(Type::kRRect == fType);
257 SkASSERT(!fInheritedKey.count()); 283 SkASSERT(!fInheritedKey.count());
258 if (fRRect.isEmpty()) { 284 if (fRRectIsInverted) {
285 if (!fStyle.hasNonDashPathEffect()) {
286 SkStrokeRec::Style recStyle = fStyle.strokeRec().getStyle();
287 if (SkStrokeRec::kStroke_Style == recStyle ||
288 SkStrokeRec::kHairline_Style == recStyle) {
289 // stroking ignores the path fill rule.
290 fRRectIsInverted = false;
291 }
292 }
293 } else if (fRRect.isEmpty()) {
259 fType = Type::kEmpty; 294 fType = Type::kEmpty;
260 } 295 }
261 } 296 }
262 297
263 static Type AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect, 298 static Type AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect,
264 SkPath::Direction* rrectDir, unsigne d* rrectStart, 299 SkPath::Direction* rrectDir, unsigne d* rrectStart,
265 const SkPathEffect* pe, const SkStro keRec& strokeRec); 300 bool* rrectIsInverted, const SkPathE ffect* pe,
301 const SkStrokeRec& strokeRec);
266 302
267 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; 303 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction;
268 static constexpr unsigned kDefaultRRectStart = 0; 304 static constexpr unsigned kDefaultRRectStart = 0;
269 305
270 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath Effect, 306 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath Effect,
271 SkPath::Direction* dir) { 307 SkPath::Direction* dir) {
272 *dir = kDefaultRRectDir; 308 *dir = kDefaultRRectDir;
273 // This comes from SkPath's interface. The default for adding a SkRect i s counter clockwise 309 // This comes from SkPath's interface. The default for adding a SkRect i s counter clockwise
274 // beginning at index 0 (which happens to correspond to rrect index 0 or 7). 310 // beginning at index 0 (which happens to correspond to rrect index 0 or 7).
275 if (!hasPathEffect) { 311 if (!hasPathEffect) {
(...skipping 30 matching lines...) Expand all
306 // It doesn't matter what start we use, just be consistent to avoid redundant keys. 342 // It doesn't matter what start we use, just be consistent to avoid redundant keys.
307 return kDefaultRRectStart; 343 return kDefaultRRectStart;
308 } 344 }
309 return kPathRRectStartIdx; 345 return kPathRRectStartIdx;
310 } 346 }
311 347
312 Type fType; 348 Type fType;
313 SkRRect fRRect; 349 SkRRect fRRect;
314 SkPath::Direction fRRectDir; 350 SkPath::Direction fRRectDir;
315 unsigned fRRectStart; 351 unsigned fRRectStart;
352 bool fRRectIsInverted;
316 SkTLazy<SkPath> fPath; 353 SkTLazy<SkPath> fPath;
317 GrStyle fStyle; 354 GrStyle fStyle;
318 SkAutoSTArray<8, uint32_t> fInheritedKey; 355 SkAutoSTArray<8, uint32_t> fInheritedKey;
319 }; 356 };
320 #endif 357 #endif
OLDNEW
« no previous file with comments | « no previous file | src/gpu/GrShape.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698