OLD | NEW |
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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 if (inverted) { | 145 if (inverted) { |
146 *inverted = fRRectData.fInverted; | 146 *inverted = fRRectData.fInverted; |
147 } | 147 } |
148 return true; | 148 return true; |
149 } | 149 } |
150 | 150 |
151 /** | 151 /** |
152 * If the unstyled shape is a straight line segment, returns true and sets p
ts to the endpoints. | 152 * If the unstyled shape is a straight line segment, returns true and sets p
ts to the endpoints. |
153 * An inverse filled line path is still considered a line. | 153 * An inverse filled line path is still considered a line. |
154 */ | 154 */ |
155 bool asLine(SkPoint pts[2], bool* inverted) const { | 155 bool asLine(SkPoint pts[2]) const { |
156 if (fType != Type::kLine) { | 156 if (fType != Type::kPath) { |
157 return false; | 157 return false; |
158 } | 158 } |
159 if (pts) { | 159 return this->path().isLine(pts); |
160 pts[0] = fLineData.fPts[0]; | 160 } |
161 pts[1] = fLineData.fPts[1]; | |
162 } | |
163 if (inverted) { | |
164 *inverted = fLineData.fInverted; | |
165 } | |
166 return true; | |
167 } | |
168 | 161 |
169 /** Returns the unstyled geometry as a path. */ | 162 /** Returns the unstyled geometry as a path. */ |
170 void asPath(SkPath* out) const { | 163 void asPath(SkPath* out) const { |
171 switch (fType) { | 164 switch (fType) { |
172 case Type::kEmpty: | 165 case Type::kEmpty: |
173 out->reset(); | 166 out->reset(); |
174 break; | 167 break; |
175 case Type::kRRect: | 168 case Type::kRRect: |
176 out->reset(); | 169 out->reset(); |
177 out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fSt
art); | 170 out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fSt
art); |
178 // Below matches the fill type that attemptToSimplifyPath uses. | 171 // Below matches the fill type that attemptToSimplifyPath uses. |
179 if (fRRectData.fInverted) { | 172 if (fRRectData.fInverted) { |
180 out->setFillType(kDefaultPathInverseFillType); | 173 out->setFillType(kDefaultPathInverseFillType); |
181 } else { | 174 } else { |
182 out->setFillType(kDefaultPathFillType); | 175 out->setFillType(kDefaultPathFillType); |
183 } | 176 } |
184 break; | 177 break; |
185 case Type::kLine: | |
186 out->reset(); | |
187 out->moveTo(fLineData.fPts[0]); | |
188 out->lineTo(fLineData.fPts[1]); | |
189 if (fLineData.fInverted) { | |
190 out->setFillType(kDefaultPathInverseFillType); | |
191 } else { | |
192 out->setFillType(kDefaultPathFillType); | |
193 } | |
194 break; | |
195 case Type::kPath: | 178 case Type::kPath: |
196 *out = this->path(); | 179 *out = this->path(); |
197 break; | 180 break; |
198 } | 181 } |
199 } | 182 } |
200 | 183 |
201 /** | 184 /** |
202 * Returns whether the geometry is empty. Note that applying the style could
produce a | 185 * Returns whether the geometry is empty. Note that applying the style could
produce a |
203 * non-empty shape. | 186 * non-empty shape. |
204 */ | 187 */ |
205 bool isEmpty() const { return Type::kEmpty == fType; } | 188 bool isEmpty() const { return Type::kEmpty == fType; } |
206 | 189 |
207 /** | 190 /** |
208 * Gets the bounds of the geometry without reflecting the shape's styling. T
his ignores | 191 * Gets the bounds of the geometry without reflecting the shape's styling. T
his ignores |
209 * the inverse fill nature of the geometry. | 192 * the inverse fill nature of the geometry. |
210 */ | 193 */ |
211 SkRect bounds() const; | 194 const SkRect& bounds() const; |
212 | 195 |
213 /** | 196 /** |
214 * Gets the bounds of the geometry reflecting the shape's styling (ignoring
inverse fill | 197 * Gets the bounds of the geometry reflecting the shape's styling (ignoring
inverse fill |
215 * status). | 198 * status). |
216 */ | 199 */ |
217 SkRect styledBounds() const; | 200 void styledBounds(SkRect* bounds) const; |
218 | 201 |
219 /** | 202 /** |
220 * Is this shape known to be convex, before styling is applied. An unclosed
but otherwise | 203 * Is this shape known to be convex, before styling is applied. An unclosed
but otherwise |
221 * convex path is considered to be closed if they styling reflects a fill an
d not otherwise. | 204 * convex path is considered to be closed if they styling reflects a fill an
d not otherwise. |
222 * This is because filling closes all contours in the path. | 205 * This is because filling closes all contours in the path. |
223 */ | 206 */ |
224 bool knownToBeConvex() const { | 207 bool knownToBeConvex() const { |
225 switch (fType) { | 208 switch (fType) { |
226 case Type::kEmpty: | 209 case Type::kEmpty: |
227 return true; | 210 return true; |
228 case Type::kRRect: | 211 case Type::kRRect: |
229 return true; | 212 return true; |
230 case Type::kLine: | |
231 return true; | |
232 case Type::kPath: | 213 case Type::kPath: |
233 // SkPath.isConvex() really means "is this path convex were it t
o be closed" and | 214 // SkPath.isConvex() really means "is this path convex were it t
o be closed" and |
234 // thus doesn't give the correct answer for stroked paths, hence
we also check | 215 // thus doesn't give the correct answer for stroked paths, hence
we also check |
235 // whether the path is either filled or closed. Convex paths may
only have one | 216 // whether the path is either filled or closed. Convex paths may
only have one |
236 // contour hence isLastContourClosed() is a sufficient for a con
vex path. | 217 // contour hence isLastContourClosed() is a sufficient for a con
vex path. |
237 return (this->style().isSimpleFill() || this->path().isLastConto
urClosed()) && | 218 return (this->style().isSimpleFill() || this->path().isLastConto
urClosed()) && |
238 this->path().isConvex(); | 219 this->path().isConvex(); |
239 } | 220 } |
240 return false; | 221 return false; |
241 } | 222 } |
242 | 223 |
243 /** Is the pre-styled geometry inverse filled? */ | 224 /** Is the pre-styled geometry inverse filled? */ |
244 bool inverseFilled() const { | 225 bool inverseFilled() const { |
245 bool ret = false; | 226 bool ret = false; |
246 switch (fType) { | 227 switch (fType) { |
247 case Type::kEmpty: | 228 case Type::kEmpty: |
248 ret = false; | 229 ret = false; |
249 break; | 230 break; |
250 case Type::kRRect: | 231 case Type::kRRect: |
251 ret = fRRectData.fInverted; | 232 ret = fRRectData.fInverted; |
252 break; | 233 break; |
253 case Type::kLine: | |
254 ret = fLineData.fInverted; | |
255 break; | |
256 case Type::kPath: | 234 case Type::kPath: |
257 ret = this->path().isInverseFillType(); | 235 ret = this->path().isInverseFillType(); |
258 break; | 236 break; |
259 } | 237 } |
260 // Dashing ignores inverseness. We should have caught this earlier. skbu
g.com/5421 | 238 // Dashing ignores inverseness. We should have caught this earlier. skbu
g.com/5421 |
261 SkASSERT(!(ret && this->style().isDashed())); | 239 SkASSERT(!(ret && this->style().isDashed())); |
262 return ret; | 240 return ret; |
263 } | 241 } |
264 | 242 |
265 /** | 243 /** |
(...skipping 13 matching lines...) Expand all Loading... |
279 /** | 257 /** |
280 * Is it known that the unstyled geometry has no unclosed contours. This mea
ns that it will | 258 * Is it known that the unstyled geometry has no unclosed contours. This mea
ns that it will |
281 * not have any caps if stroked (modulo the effect of any path effect). | 259 * not have any caps if stroked (modulo the effect of any path effect). |
282 */ | 260 */ |
283 bool knownToBeClosed() const { | 261 bool knownToBeClosed() const { |
284 switch (fType) { | 262 switch (fType) { |
285 case Type::kEmpty: | 263 case Type::kEmpty: |
286 return true; | 264 return true; |
287 case Type::kRRect: | 265 case Type::kRRect: |
288 return true; | 266 return true; |
289 case Type::kLine: | |
290 return false; | |
291 case Type::kPath: | 267 case Type::kPath: |
292 // SkPath doesn't keep track of the closed status of each contou
r. | 268 // SkPath doesn't keep track of the closed status of each contou
r. |
293 return SkPathPriv::IsClosedSingleContour(this->path()); | 269 return SkPathPriv::IsClosedSingleContour(this->path()); |
294 } | 270 } |
295 return false; | 271 return false; |
296 } | 272 } |
297 | 273 |
298 uint32_t segmentMask() const { | 274 uint32_t segmentMask() const { |
299 switch (fType) { | 275 switch (fType) { |
300 case Type::kEmpty: | 276 case Type::kEmpty: |
301 return 0; | 277 return 0; |
302 case Type::kRRect: | 278 case Type::kRRect: |
303 if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) { | 279 if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) { |
304 return SkPath::kConic_SegmentMask; | 280 return SkPath::kConic_SegmentMask; |
305 } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) { | 281 } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) { |
306 return SkPath::kLine_SegmentMask; | 282 return SkPath::kLine_SegmentMask; |
307 } | 283 } |
308 return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask; | 284 return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask; |
309 case Type::kLine: | |
310 return SkPath::kLine_SegmentMask; | |
311 case Type::kPath: | 285 case Type::kPath: |
312 return this->path().getSegmentMasks(); | 286 return this->path().getSegmentMasks(); |
313 } | 287 } |
314 return 0; | 288 return 0; |
315 } | 289 } |
316 | 290 |
317 /** | 291 /** |
318 * Gets the size of the key for the shape represented by this GrShape (ignor
ing its styling). | 292 * Gets the size of the key for the shape represented by this GrShape (ignor
ing its styling). |
319 * A negative value is returned if the shape has no key (shouldn't be cached
). | 293 * A negative value is returned if the shape has no key (shouldn't be cached
). |
320 */ | 294 */ |
321 int unstyledKeySize() const; | 295 int unstyledKeySize() const; |
322 | 296 |
323 bool hasUnstyledKey() const { return this->unstyledKeySize() >= 0; } | 297 bool hasUnstyledKey() const { return this->unstyledKeySize() >= 0; } |
324 | 298 |
325 /** | 299 /** |
326 * Writes unstyledKeySize() bytes into the provided pointer. Assumes that th
ere is enough | 300 * Writes unstyledKeySize() bytes into the provided pointer. Assumes that th
ere is enough |
327 * space allocated for the key and that unstyledKeySize() does not return a
negative value | 301 * space allocated for the key and that unstyledKeySize() does not return a
negative value |
328 * for this shape. | 302 * for this shape. |
329 */ | 303 */ |
330 void writeUnstyledKey(uint32_t* key) const; | 304 void writeUnstyledKey(uint32_t* key) const; |
331 | 305 |
332 private: | 306 private: |
333 enum class Type { | 307 enum class Type { |
334 kEmpty, | 308 kEmpty, |
335 kRRect, | 309 kRRect, |
336 kLine, | |
337 kPath, | 310 kPath, |
338 }; | 311 }; |
339 | 312 |
340 void initType(Type type, const SkPath* path = nullptr) { | 313 void initType(Type type, const SkPath* path = nullptr) { |
341 fType = Type::kEmpty; | 314 fType = Type::kEmpty; |
342 this->changeType(type, path); | 315 this->changeType(type, path); |
343 } | 316 } |
344 | 317 |
345 void changeType(Type type, const SkPath* path = nullptr) { | 318 void changeType(Type type, const SkPath* path = nullptr) { |
346 bool wasPath = Type::kPath == fType; | 319 bool wasPath = Type::kPath == fType; |
(...skipping 29 matching lines...) Expand all Loading... |
376 GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale); | 349 GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale); |
377 | 350 |
378 /** | 351 /** |
379 * Determines the key we should inherit from the input shape's geometry and
style when | 352 * Determines the key we should inherit from the input shape's geometry and
style when |
380 * we are applying the style to create a new shape. | 353 * we are applying the style to create a new shape. |
381 */ | 354 */ |
382 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc
ale); | 355 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc
ale); |
383 | 356 |
384 void attemptToSimplifyPath(); | 357 void attemptToSimplifyPath(); |
385 void attemptToSimplifyRRect(); | 358 void attemptToSimplifyRRect(); |
386 void attemptToSimplifyLine(); | |
387 | 359 |
388 // Defaults to use when there is no distinction between even/odd and winding
fills. | 360 // Defaults to use when there is no distinction between even/odd and winding
fills. |
389 static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_Fi
llType; | 361 static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_Fi
llType; |
390 static constexpr SkPath::FillType kDefaultPathInverseFillType = | 362 static constexpr SkPath::FillType kDefaultPathInverseFillType = |
391 SkPath::kInverseEvenOdd_FillType; | 363 SkPath::kInverseEvenOdd_FillType; |
392 | 364 |
393 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; | 365 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; |
394 static constexpr unsigned kDefaultRRectStart = 0; | 366 static constexpr unsigned kDefaultRRectStart = 0; |
395 | 367 |
396 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath
Effect, | 368 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath
Effect, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 SkRRect fRRect; | 413 SkRRect fRRect; |
442 SkPath::Direction fDir; | 414 SkPath::Direction fDir; |
443 unsigned fStart; | 415 unsigned fStart; |
444 bool fInverted; | 416 bool fInverted; |
445 } fRRectData; | 417 } fRRectData; |
446 struct { | 418 struct { |
447 SkPath fPath; | 419 SkPath fPath; |
448 // Gen ID of the original path (fPath may be modified) | 420 // Gen ID of the original path (fPath may be modified) |
449 int32_t fGenID; | 421 int32_t fGenID; |
450 } fPathData; | 422 } fPathData; |
451 struct { | |
452 SkPoint fPts[2]; | |
453 bool fInverted; | |
454 } fLineData; | |
455 }; | 423 }; |
456 GrStyle fStyle; | 424 GrStyle fStyle; |
457 SkAutoSTArray<8, uint32_t> fInheritedKey; | 425 SkAutoSTArray<8, uint32_t> fInheritedKey; |
458 }; | 426 }; |
459 #endif | 427 #endif |
OLD | NEW |