Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
GrStyledShape Class Reference

#include <GrStyledShape.h>

Public Types

enum class  DoSimplify : bool { kNo = false , kYes }
 
enum class  FillInversion { kPreserve , kFlip , kForceNoninverted , kForceInverted }
 

Public Member Functions

 GrStyledShape ()
 
 GrStyledShape (const SkPath &path, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRRect &rrect, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRect &rect, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkPath &path, const SkPaint &paint, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRRect &rrect, const SkPaint &paint, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRect &rect, const SkPaint &paint, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkPath &path, const GrStyle &style, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRRect &rrect, const GrStyle &style, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRRect &rrect, SkPathDirection dir, unsigned start, bool inverted, const GrStyle &style, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const SkRect &rect, const GrStyle &style, DoSimplify doSimplify=DoSimplify::kYes)
 
 GrStyledShape (const GrStyledShape &)
 
GrStyledShapeoperator= (const GrStyledShape &that)
 
const GrStylestyle () const
 
bool simplified () const
 
GrStyledShape applyStyle (GrStyle::Apply apply, SkScalar scale) const
 
bool isRect () const
 
bool asRRect (SkRRect *rrect, SkPathDirection *dir, unsigned *start, bool *inverted) const
 
bool asLine (SkPoint pts[2], bool *inverted) const
 
bool asNestedRects (SkRect rects[2]) const
 
void asPath (SkPath *out) const
 
bool isEmpty () const
 
SkRect bounds () const
 
SkRect styledBounds () const
 
bool knownToBeConvex () const
 
bool knownDirection () const
 
bool inverseFilled () const
 
bool mayBeInverseFilledAfterStyling () const
 
bool knownToBeClosed () const
 
uint32_t segmentMask () const
 
int unstyledKeySize () const
 
bool hasUnstyledKey () const
 
void writeUnstyledKey (uint32_t *key) const
 
void addGenIDChangeListener (sk_sp< SkIDChangeListener >) const
 
uint32_t testingOnly_getOriginalGenerationID () const
 
bool testingOnly_isPath () const
 
bool testingOnly_isNonVolatilePath () const
 
void simplify ()
 

Static Public Member Functions

static GrStyledShape MakeArc (const SkRect &oval, SkScalar startAngleDegrees, SkScalar sweepAngleDegrees, bool useCenter, const GrStyle &style, DoSimplify=DoSimplify::kYes)
 
static GrStyledShape MakeFilled (const GrStyledShape &original, FillInversion=FillInversion::kPreserve)
 

Static Public Attributes

static constexpr int kMaxKeyFromDataVerbCnt = 10
 

Detailed Description

Represents a geometric shape (rrect or path) and the GrStyle that it should be rendered with. It is possible to apply the style to the GrStyledShape to produce a new GrStyledShape where the geometry reflects the styling information (e.g. is stroked). It is also possible to apply just the path effect from the style. In this case the resulting shape will include any remaining stroking information that is to be applied after the path effect.

Shapes can produce keys that represent only the geometry information, not the style. Note that when styling information is applied to produce a new shape then the style has been converted to geometric information and is included in the new shape's key. When the same style is applied to two shapes that reflect the same underlying geometry the computed keys of the stylized shapes will be the same.

Currently this can only be constructed from a path, rect, or rrect though it can become a path applying style to the geometry. The idea is to expand this to cover most or all of the geometries that have fast paths in the GPU backend.

Definition at line 48 of file GrStyledShape.h.

Member Enumeration Documentation

◆ DoSimplify

enum class GrStyledShape::DoSimplify : bool
strong
Enumerator
kNo 
kYes 

Definition at line 56 of file GrStyledShape.h.

◆ FillInversion

enum class GrStyledShape::FillInversion
strong

Informs MakeFilled on how to modify that shape's fill rule when making a simple filled version of the shape.

Enumerator
kPreserve 
kFlip 
kForceNoninverted 
kForceInverted 

Definition at line 123 of file GrStyledShape.h.

Constructor & Destructor Documentation

◆ GrStyledShape() [1/12]

GrStyledShape::GrStyledShape ( )
inline

Definition at line 54 of file GrStyledShape.h.

54{}

◆ GrStyledShape() [2/12]

GrStyledShape::GrStyledShape ( const SkPath path,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inlineexplicit

Definition at line 58 of file GrStyledShape.h.

59 : GrStyledShape(path, GrStyle::SimpleFill(), doSimplify) {}
static const GrStyle & SimpleFill()
Definition GrStyle.h:30

◆ GrStyledShape() [3/12]

GrStyledShape::GrStyledShape ( const SkRRect rrect,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inlineexplicit

Definition at line 61 of file GrStyledShape.h.

62 : GrStyledShape(rrect, GrStyle::SimpleFill(), doSimplify) {}

◆ GrStyledShape() [4/12]

GrStyledShape::GrStyledShape ( const SkRect rect,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inlineexplicit

Definition at line 64 of file GrStyledShape.h.

65 : GrStyledShape(rect, GrStyle::SimpleFill(), doSimplify) {}

◆ GrStyledShape() [5/12]

GrStyledShape::GrStyledShape ( const SkPath path,
const SkPaint paint,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 67 of file GrStyledShape.h.

69 : GrStyledShape(path, GrStyle(paint), doSimplify) {}
const Paint & paint

◆ GrStyledShape() [6/12]

GrStyledShape::GrStyledShape ( const SkRRect rrect,
const SkPaint paint,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 71 of file GrStyledShape.h.

73 : GrStyledShape(rrect, GrStyle(paint), doSimplify) {}

◆ GrStyledShape() [7/12]

GrStyledShape::GrStyledShape ( const SkRect rect,
const SkPaint paint,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 75 of file GrStyledShape.h.

77 : GrStyledShape(rect, GrStyle(paint), doSimplify) {}

◆ GrStyledShape() [8/12]

GrStyledShape::GrStyledShape ( const SkPath path,
const GrStyle style,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 79 of file GrStyledShape.h.

81 : fShape(path), fStyle(style) {
82 if (doSimplify == DoSimplify::kYes) {
83 this->simplify();
84 }
85 }
const GrStyle & style() const

◆ GrStyledShape() [9/12]

GrStyledShape::GrStyledShape ( const SkRRect rrect,
const GrStyle style,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 87 of file GrStyledShape.h.

90 : GrStyledShape(rrect, SkPathDirection::kCW, 6, false, style, doSimplify) {}

◆ GrStyledShape() [10/12]

GrStyledShape::GrStyledShape ( const SkRRect rrect,
SkPathDirection  dir,
unsigned  start,
bool  inverted,
const GrStyle style,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 92 of file GrStyledShape.h.

94 : fShape(rrect)
95 , fStyle(style) {
96 fShape.setPathWindingParams(dir, start);
97 fShape.setInverted(inverted);
98 if (doSimplify == DoSimplify::kYes) {
99 this->simplify();
100 }
101 }
void setPathWindingParams(SkPathDirection dir, unsigned start)
Definition GrShape.h:112
void setInverted(bool inverted)
Definition GrShape.h:119

◆ GrStyledShape() [11/12]

GrStyledShape::GrStyledShape ( const SkRect rect,
const GrStyle style,
DoSimplify  doSimplify = DoSimplify::kYes 
)
inline

Definition at line 103 of file GrStyledShape.h.

105 : fShape(rect), fStyle(style) {
106 if (doSimplify == DoSimplify::kYes) {
107 this->simplify();
108 }
109 }

◆ GrStyledShape() [12/12]

GrStyledShape::GrStyledShape ( const GrStyledShape that)

Definition at line 329 of file GrStyledShape.cpp.

330 : fShape(that.fShape)
331 , fStyle(that.fStyle)
332 , fGenID(that.fGenID)
333 , fSimplified(that.fSimplified) {
334 fInheritedKey.reset(that.fInheritedKey.count());
335 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
336 sizeof(uint32_t) * fInheritedKey.count());
337 if (that.fInheritedPathForListeners.isValid()) {
338 fInheritedPathForListeners.set(*that.fInheritedPathForListeners);
339 }
340}
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
Definition SkMalloc.h:125
bool isValid() const
Definition SkTLazy.h:77
T * set(const T &src)
Definition SkTLazy.h:56

Member Function Documentation

◆ addGenIDChangeListener()

void GrStyledShape::addGenIDChangeListener ( sk_sp< SkIDChangeListener listener) const

Adds a listener to the original path. Typically used to invalidate cached resources when a path is no longer in-use. If the shape started out as something other than a path, this does nothing.

Definition at line 311 of file GrStyledShape.cpp.

311 {
312 if (const auto* lp = this->originalPathForListeners()) {
313 SkPathPriv::AddGenIDChangeListener(*lp, std::move(listener));
314 }
315}
static void AddGenIDChangeListener(const SkPath &path, sk_sp< SkIDChangeListener > listener)
Definition SkPathPriv.h:105

◆ applyStyle()

GrStyledShape GrStyledShape::applyStyle ( GrStyle::Apply  apply,
SkScalar  scale 
) const
inline

Returns a shape that has either applied the path effect or path effect and stroking information from this shape's style to its geometry. Scale is used when approximating the output geometry and typically is computed from the view matrix

Definition at line 149 of file GrStyledShape.h.

149 {
150 return GrStyledShape(*this, apply, scale);
151 }
static bool apply(Pass *pass, SkRecord *record)
const Scalar scale

◆ asLine()

bool GrStyledShape::asLine ( SkPoint  pts[2],
bool *  inverted 
) const

If the unstyled shape is a straight line segment, returns true and sets pts to the endpoints. An inverse filled line path is still considered a line.

Definition at line 518 of file GrStyledShape.cpp.

518 {
519 if (!fShape.isLine()) {
520 return false;
521 }
522
523 if (pts) {
524 pts[0] = fShape.line().fP1;
525 pts[1] = fShape.line().fP2;
526 }
527 if (inverted) {
528 *inverted = fShape.inverted();
529 }
530 return true;
531}
bool isLine() const
Definition GrShape.h:90
GrLineSegment & line()
Definition GrShape.h:146
bool inverted() const
Definition GrShape.h:99
SkPoint fP2
Definition GrShape.h:28
SkPoint fP1
Definition GrShape.h:27

◆ asNestedRects()

bool GrStyledShape::asNestedRects ( SkRect  rects[2]) const

Definition at line 533 of file GrStyledShape.cpp.

533 {
534 if (!fShape.isPath()) {
535 return false;
536 }
537
538 // TODO: it would be better two store DRRects natively in the shape rather than converting
539 // them to a path and then reextracting the nested rects
540 if (fShape.path().isInverseFillType()) {
541 return false;
542 }
543
544 SkPathDirection dirs[2];
545 if (!SkPathPriv::IsNestedFillRects(fShape.path(), rects, dirs)) {
546 return false;
547 }
548
549 if (SkPathFillType::kWinding == fShape.path().getFillType() && dirs[0] == dirs[1]) {
550 // The two rects need to be wound opposite to each other
551 return false;
552 }
553
554 // Right now, nested rects where the margin is not the same width
555 // all around do not render correctly
556 const SkScalar* outer = rects[0].asScalars();
557 const SkScalar* inner = rects[1].asScalars();
558
559 bool allEq = true;
560
561 SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
562 bool allGoE1 = margin >= SK_Scalar1;
563
564 for (int i = 1; i < 4; ++i) {
565 SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
566 if (temp < SK_Scalar1) {
567 allGoE1 = false;
568 }
569 if (!SkScalarNearlyEqual(margin, temp)) {
570 allEq = false;
571 }
572 }
573
574 return allEq || allGoE1;
575}
SkPathDirection
Definition SkPathTypes.h:34
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define SK_Scalar1
Definition SkScalar.h:18
#define SkScalarAbs(x)
Definition SkScalar.h:39
bool isPath() const
Definition GrShape.h:88
SkPath & path()
Definition GrShape.h:140
static bool IsNestedFillRects(const SkPath &, SkRect rect[2], SkPathDirection dirs[2]=nullptr)
Definition SkPath.cpp:3712
bool isInverseFillType() const
Definition SkPath.h:244
SkPathFillType getFillType() const
Definition SkPath.h:230
float SkScalar
Definition extension.cpp:12
const float * asScalars() const
Definition SkRect.h:1340

◆ asPath()

void GrStyledShape::asPath ( SkPath out) const
inline

Returns the unstyled geometry as a path.

Definition at line 172 of file GrStyledShape.h.

172 {
173 fShape.asPath(out, fStyle.isSimpleFill());
174 }
void asPath(SkPath *out, bool simpleFill=true) const
Definition GrShape.cpp:421
bool isSimpleFill() const
Definition GrStyle.h:114

◆ asRRect()

bool GrStyledShape::asRRect ( SkRRect rrect,
SkPathDirection dir,
unsigned *  start,
bool *  inverted 
) const

Returns the unstyled geometry as a rrect if possible.

Definition at line 436 of file GrStyledShape.cpp.

437 {
438 if (!fShape.isRRect() && !fShape.isRect()) {
439 return false;
440 }
441
442 // Validity check here, if we don't have a path effect on the style, we should have passed
443 // appropriate flags to GrShape::simplify() to have reset these parameters.
444 SkASSERT(fStyle.hasPathEffect() || (fShape.dir() == GrShape::kDefaultDir &&
446
447 // If the shape is a regular rect, map to round rect winding parameters, including accounting
448 // for the automatic sorting of edges that SkRRect::MakeRect() performs.
449 if (fShape.isRect()) {
450 if (rrect) {
451 *rrect = SkRRect::MakeRect(fShape.rect());
452 }
453 // Don't bother mapping these if we don't have a path effect, however.
454 if (!fStyle.hasPathEffect()) {
455 if (dir) {
457 }
458 if (start) {
460 }
461 } else {
462 // In SkPath a rect starts at index 0 by default. This is the top left corner. However,
463 // we store rects as rrects. RRects don't preserve the invertedness, but rather sort the
464 // rect edges. Thus, we may need to modify the rrect's start index and direction.
465 SkPathDirection rectDir = fShape.dir();
466 unsigned rectStart = fShape.startIndex();
467
468 if (fShape.rect().fLeft > fShape.rect().fRight) {
469 // Toggle direction, and modify index by mapping through the array
470 static const unsigned kMapping[] = {1, 0, 3, 2};
471 rectDir = rectDir == SkPathDirection::kCCW ? SkPathDirection::kCW
473 rectStart = kMapping[rectStart];
474 }
475 if (fShape.rect().fTop > fShape.rect().fBottom) {
476 // Toggle direction and map index by 3 - start
477 // NOTE: if we earlier flipped for X as well, this results in no net direction
478 // change and effectively flipping the start index to the diagonal corners of the
479 // rect (matching what we'd expect for a rect with both X and Y flipped).
480 rectDir = rectDir == SkPathDirection::kCCW ? SkPathDirection::kCW
482 rectStart = 3 - rectStart;
483 }
484
485 if (dir) {
486 *dir = rectDir;
487 }
488 if (start) {
489 // Convert to round rect indexing
490 *start = 2 * rectStart;
491 }
492 }
493 } else {
494 // Straight forward export
495 if (rrect) {
496 *rrect = fShape.rrect();
497 }
498 if (dir) {
499 *dir = fShape.dir();
500 }
501 if (start) {
502 *start = fShape.startIndex();
503 // Canonicalize the index if the rrect is an oval, which GrShape doesn't treat special
504 // but we do for dashing placement
505 if (fShape.rrect().isOval()) {
506 *start &= 0b110;
507 }
508 }
509 }
510
511 if (inverted) {
512 *inverted = fShape.inverted();
513 }
514
515 return true;
516}
#define SkASSERT(cond)
Definition SkAssert.h:116
SkRect & rect()
Definition GrShape.h:134
bool isRRect() const
Definition GrShape.h:87
SkRRect & rrect()
Definition GrShape.h:137
bool isRect() const
Definition GrShape.h:86
SkPathDirection dir() const
Definition GrShape.h:105
static constexpr SkPathDirection kDefaultDir
Definition GrShape.h:60
unsigned startIndex() const
Definition GrShape.h:108
static constexpr unsigned kDefaultStart
Definition GrShape.h:61
bool hasPathEffect() const
Definition GrStyle.h:122
bool isOval() const
Definition SkRRect.h:85
static SkRRect MakeRect(const SkRect &r)
Definition SkRRect.h:149
SkRRect rrect
Definition SkRecords.h:232
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition switches.h:145
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15

◆ bounds()

SkRect GrStyledShape::bounds ( ) const
inline

Gets the bounds of the geometry without reflecting the shape's styling. This ignores the inverse fill nature of the geometry.

Definition at line 186 of file GrStyledShape.h.

186{ return fShape.bounds(); }
SkRect bounds() const
Definition GrShape.cpp:365

◆ hasUnstyledKey()

bool GrStyledShape::hasUnstyledKey ( ) const
inline

Definition at line 258 of file GrStyledShape.h.

258{ return this->unstyledKeySize() >= 0; }
int unstyledKeySize() const

◆ inverseFilled()

bool GrStyledShape::inverseFilled ( ) const
inline

Is the pre-styled geometry inverse filled?

Definition at line 216 of file GrStyledShape.h.

216 {
217 // Since the path tracks inverted-fillness itself, it should match what was recorded.
218 SkASSERT(!fShape.isPath() || fShape.inverted() == fShape.path().isInverseFillType());
219 // Dashing ignores inverseness. We should have caught this earlier. skbug.com/5421
220 SkASSERT(!(fShape.inverted() && this->style().isDashed()));
221 return fShape.inverted();
222 }

◆ isEmpty()

bool GrStyledShape::isEmpty ( ) const
inline

Returns whether the geometry is empty. Note that applying the style could produce a non-empty shape. It also may have an inverse fill.

Definition at line 180 of file GrStyledShape.h.

180{ return fShape.isEmpty(); }
bool isEmpty() const
Definition GrShape.h:84

◆ isRect()

bool GrStyledShape::isRect ( ) const
inline

Definition at line 153 of file GrStyledShape.h.

153 {
154 // Should have simplified a rrect to a rect if possible already.
155 SkASSERT(!fShape.isRRect() || !fShape.rrect().isRect());
156 return fShape.isRect();
157 }
bool isRect() const
Definition SkRRect.h:84

◆ knownDirection()

bool GrStyledShape::knownDirection ( ) const
inline

Does the shape have a known winding direction. Some degenerate convex shapes may not have a computable direction, but this is not always a requirement for path renderers so it is kept separate from knownToBeConvex().

Definition at line 208 of file GrStyledShape.h.

208 {
209 // Assuming this is called after knownToBeConvex(), this should just be relying on
210 // cached convexity and direction and will be cheap.
211 return !fShape.isPath() ||
213 }
static SkPathFirstDirection ComputeFirstDirection(const SkPath &)
Definition SkPath.cpp:2563

◆ knownToBeClosed()

bool GrStyledShape::knownToBeClosed ( ) const
inline

Is it known that the unstyled geometry has no unclosed contours. This means that it will not have any caps if stroked (modulo the effect of any path effect).

Definition at line 242 of file GrStyledShape.h.

242 {
243 // This refers to the base shape and does not depend on invertedness.
244 return fShape.closed();
245 }
bool closed() const
Definition GrShape.cpp:328

◆ knownToBeConvex()

bool GrStyledShape::knownToBeConvex ( ) const
inline

Is this shape known to be convex, before styling is applied. An unclosed but otherwise convex path is considered to be closed if they styling reflects a fill and not otherwise. This is because filling closes all contours in the path.

Definition at line 199 of file GrStyledShape.h.

199 {
200 return fShape.convex(fStyle.isSimpleFill());
201 }
bool convex(bool simpleFill=true) const
Definition GrShape.cpp:346

◆ MakeArc()

GrStyledShape GrStyledShape::MakeArc ( const SkRect oval,
SkScalar  startAngleDegrees,
SkScalar  sweepAngleDegrees,
bool  useCenter,
const GrStyle style,
DoSimplify  doSimplify = DoSimplify::kYes 
)
static

Definition at line 317 of file GrStyledShape.cpp.

319 {
321 result.fShape.setArc({oval.makeSorted(), startAngleDegrees, sweepAngleDegrees, useCenter});
322 result.fStyle = style;
323 if (doSimplify == DoSimplify::kYes) {
324 result.simplify();
325 }
326 return result;
327}
void setArc(const SkArc &arc)
Definition GrShape.h:167
GAsyncResult * result
SkRect oval
Definition SkRecords.h:249
SkRect makeSorted() const
Definition SkRect.h:1330

◆ MakeFilled()

GrStyledShape GrStyledShape::MakeFilled ( const GrStyledShape original,
FillInversion  inversion = FillInversion::kPreserve 
)
static

Makes a filled shape from the pre-styled original shape and optionally modifies whether the fill is inverted or not. It's important to note that the original shape's geometry may already have been modified if doing so was neutral with respect to its style (e.g. filled paths are always closed when stored in a shape and dashed paths are always made non-inverted since dashing ignores inverseness).

Definition at line 56 of file GrStyledShape.cpp.

56 {
57 bool newIsInverted = is_inverted(original.fShape.inverted(), inversion);
58 if (original.style().isSimpleFill() && newIsInverted == original.fShape.inverted()) {
59 // By returning the original rather than falling through we can preserve any inherited style
60 // key. Otherwise, we wipe it out below since the style change invalidates it.
61 return original;
62 }
64 SkASSERT(result.fStyle.isSimpleFill());
65 if (original.fInheritedPathForListeners.isValid()) {
66 result.fInheritedPathForListeners.set(*original.fInheritedPathForListeners);
67 }
68
69 result.fShape = original.fShape;
70 result.fGenID = original.fGenID;
71 result.fShape.setInverted(newIsInverted);
72
73 if (!original.style().isSimpleFill()) {
74 // Going from a non-filled style to fill may allow additional simplifications (e.g.
75 // closing an open rect that wasn't closed in the original shape because it had
76 // stroke style).
77 result.simplify();
78 // The above simplify() call only sets simplified to true if its geometry was changed,
79 // since it already sees its style as a simple fill. Since the original style was not a
80 // simple fill, MakeFilled always simplifies.
81 result.fSimplified = true;
82 }
83
84 // Verify that lines/points were converted to empty by the style change
85 SkASSERT((!original.fShape.isLine() && !original.fShape.isPoint()) || result.fShape.isEmpty());
86
87 // We don't copy the inherited key since it can contain path effect information that we just
88 // stripped.
89 return result;
90}
static bool inversion(Vertex *prev, Vertex *next, Edge *origEdge, const Comparator &c)
static bool is_inverted(const SkRect &r)
bool isPoint() const
Definition GrShape.h:85

◆ mayBeInverseFilledAfterStyling()

bool GrStyledShape::mayBeInverseFilledAfterStyling ( ) const
inline

Might applying the styling to the geometry produce an inverse fill. The "may" part comes in because an arbitrary path effect could produce an inverse filled path. In other cases this can be thought of as "inverseFilledAfterStyling()".

Definition at line 229 of file GrStyledShape.h.

229 {
230 // An arbitrary path effect can produce an arbitrary output path, which may be inverse
231 // filled.
232 if (this->style().hasNonDashPathEffect()) {
233 return true;
234 }
235 return this->inverseFilled();
236 }
bool inverseFilled() const

◆ operator=()

GrStyledShape & GrStyledShape::operator= ( const GrStyledShape that)

Definition at line 25 of file GrStyledShape.cpp.

25 {
26 fShape = that.fShape;
27 fStyle = that.fStyle;
28 fGenID = that.fGenID;
29 fSimplified = that.fSimplified;
30
31 fInheritedKey.reset(that.fInheritedKey.count());
32 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
33 sizeof(uint32_t) * fInheritedKey.count());
34 if (that.fInheritedPathForListeners.isValid()) {
35 fInheritedPathForListeners.set(*that.fInheritedPathForListeners);
36 } else {
37 fInheritedPathForListeners.reset();
38 }
39 return *this;
40}
void reset()
Definition SkTLazy.h:69

◆ segmentMask()

uint32_t GrStyledShape::segmentMask ( ) const
inline

Definition at line 247 of file GrStyledShape.h.

247 {
248 // This refers to the base shape and does not depend on invertedness.
249 return fShape.segmentMask();
250 }
uint32_t segmentMask() const
Definition GrShape.cpp:391

◆ simplified()

bool GrStyledShape::simplified ( ) const
inline

Definition at line 142 of file GrStyledShape.h.

142{ return fSimplified; }

◆ simplify()

void GrStyledShape::simplify ( )

Similar to GrShape::simplify but also takes into account style and stroking, possibly applying the style explicitly to produce a new analytic shape with a simpler style. Unless "doSimplify" is kNo, this method gets called automatically during construction.

Definition at line 594 of file GrStyledShape.cpp.

594 {
595 AutoRestoreInverseness ari(&fShape, fStyle);
596
597 unsigned simplifyFlags = 0;
598 if (fStyle.isSimpleFill()) {
599 simplifyFlags = GrShape::kAll_Flags;
600 } else if (!fStyle.hasPathEffect()) {
601 // Everything but arcs with caps that might extend beyond the oval edge can ignore winding
602 if (!fShape.isArc() || fStyle.strokeRec().getCap() == SkPaint::kButt_Cap) {
603 simplifyFlags |= GrShape::kIgnoreWinding_Flag;
604 }
605 simplifyFlags |= GrShape::kMakeCanonical_Flag;
606 } // else if there's a path effect, every destructive simplification is disabledd
607
608 // Remember if the original shape was closed; in the event we simplify to a point or line
609 // because of degenerate geometry, we need to update joins and caps.
610 GrShape::Type oldType = fShape.type();
611 fClosed = fShape.simplify(simplifyFlags);
612 fSimplified = oldType != fShape.type();
613
614 if (fShape.isPath()) {
615 // The shape remains a path, so configure the gen ID and canonicalize fill type if possible
616 if (fInheritedKey.count() || fShape.path().isVolatile()) {
617 fGenID = 0;
618 } else {
619 fGenID = fShape.path().getGenerationID();
620 }
621 if (!fStyle.hasNonDashPathEffect() &&
624 fShape.path().isConvex())) {
625 // Stroke styles don't differentiate between winding and even/odd. There is no
626 // distinction between even/odd and non-zero winding count for convex paths.
627 // Moreover, dashing ignores inverseness (skbug.com/5421)
629 }
630 } else {
631 fInheritedKey.reset(0);
632 // Whenever we simplify to a non-path, break the chain so we no longer refer to the
633 // original path. This prevents attaching genID listeners to temporary paths created when
634 // drawing simple shapes.
635 fInheritedPathForListeners.reset();
636 // Further simplifications to the shape based on the style
637 this->simplifyStroke();
638 }
639}
Type type() const
Definition GrShape.h:92
@ kMakeCanonical_Flag
Definition GrShape.h:203
@ kIgnoreWinding_Flag
Definition GrShape.h:200
@ kAll_Flags
Definition GrShape.h:205
static constexpr SkPathFillType kDefaultFillType
Definition GrShape.h:63
bool isArc() const
Definition GrShape.h:89
bool simplify(unsigned flags=kAll_Flags)
Definition GrShape.cpp:242
bool hasNonDashPathEffect() const
Definition GrStyle.h:124
const SkStrokeRec & strokeRec() const
Definition GrStyle.h:140
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
uint32_t getGenerationID() const
Definition SkPath.cpp:356
void setFillType(SkPathFillType ft)
Definition SkPath.h:235
bool isVolatile() const
Definition SkPath.h:350
bool isConvex() const
Definition SkPath.cpp:416
Style getStyle() const
SkPaint::Cap getCap() const
Definition SkStrokeRec.h:44

◆ style()

const GrStyle & GrStyledShape::style ( ) const
inline

Definition at line 139 of file GrStyledShape.h.

139{ return fStyle; }

◆ styledBounds()

SkRect GrStyledShape::styledBounds ( ) const

Gets the bounds of the geometry reflecting the shape's styling (ignoring inverse fill status).

Definition at line 92 of file GrStyledShape.cpp.

92 {
93 if (this->isEmpty() && !fStyle.hasNonDashPathEffect()) {
94 return SkRect::MakeEmpty();
95 }
96
98 fStyle.adjustBounds(&bounds, this->bounds());
99 return bounds;
100}
void adjustBounds(SkRect *dst, const SkRect &src) const
Definition GrStyle.h:173
bool isEmpty() const
SkRect bounds() const
static constexpr SkRect MakeEmpty()
Definition SkRect.h:595

◆ testingOnly_getOriginalGenerationID()

uint32_t GrStyledShape::testingOnly_getOriginalGenerationID ( ) const

Helpers that are only exposed for unit tests, to determine if the shape is a path, and get the generation ID of the original path. This is the path that will receive GenIDChangeListeners added to this shape.

Definition at line 49 of file GrStyledShapeTest.cpp.

49 {
50 if (const auto* lp = this->originalPathForListeners()) {
51 return lp->getGenerationID();
52 }
53 return SkPath().getGenerationID();
54}

◆ testingOnly_isNonVolatilePath()

bool GrStyledShape::testingOnly_isNonVolatilePath ( ) const

Definition at line 60 of file GrStyledShapeTest.cpp.

60 {
61 return fShape.isPath() && !fShape.path().isVolatile();
62}

◆ testingOnly_isPath()

bool GrStyledShape::testingOnly_isPath ( ) const

Definition at line 56 of file GrStyledShapeTest.cpp.

56 {
57 return fShape.isPath();
58}

◆ unstyledKeySize()

int GrStyledShape::unstyledKeySize ( ) const

Gets the size of the key for the shape represented by this GrStyledShape (ignoring its styling). A negative value is returned if the shape has no key (shouldn't be cached).

Definition at line 144 of file GrStyledShape.cpp.

144 {
145 if (fInheritedKey.count()) {
146 return fInheritedKey.count();
147 }
148
149 int count = 1; // Every key has the state flags from the GrShape
150 switch(fShape.type()) {
152 static_assert(0 == sizeof(SkPoint) % sizeof(uint32_t));
153 count += sizeof(SkPoint) / sizeof(uint32_t);
154 break;
156 static_assert(0 == sizeof(SkRect) % sizeof(uint32_t));
157 count += sizeof(SkRect) / sizeof(uint32_t);
158 break;
160 static_assert(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
161 count += SkRRect::kSizeInMemory / sizeof(uint32_t);
162 break;
164 static_assert(0 == sizeof(SkArc) % sizeof(uint32_t));
165 count += sizeof(SkArc) / sizeof(uint32_t);
166 break;
168 static_assert(0 == sizeof(GrLineSegment) % sizeof(uint32_t));
169 count += sizeof(GrLineSegment) / sizeof(uint32_t);
170 break;
172 if (0 == fGenID) {
173 return -1; // volatile, so won't be keyed
174 }
175 int dataKeySize = path_key_from_data_size(fShape.path());
176 if (dataKeySize >= 0) {
177 count += dataKeySize;
178 } else {
179 count++; // Just adds the gen ID.
180 }
181 break; }
182 default:
183 // else it's empty, which just needs the state flags for its key
184 SkASSERT(fShape.isEmpty());
185 }
186 return count;
187}
int count
static int path_key_from_data_size(const SkPath &path)
static constexpr size_t kSizeInMemory
Definition SkRRect.h:422
Definition SkArc.h:15

◆ writeUnstyledKey()

void GrStyledShape::writeUnstyledKey ( uint32_t *  key) const

Writes unstyledKeySize() bytes into the provided pointer. Assumes that there is enough space allocated for the key and that unstyledKeySize() does not return a negative value for this shape.

Definition at line 189 of file GrStyledShape.cpp.

189 {
190 SkASSERT(this->unstyledKeySize());
191 SkDEBUGCODE(uint32_t* origKey = key;)
192 if (fInheritedKey.count()) {
193 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count());
194 SkDEBUGCODE(key += fInheritedKey.count();)
195 } else {
196 // Dir and start are only used for rect and rrect shapes, so are not included in other
197 // shape type keys. Make sure that they are the defaults for other shapes so it doesn't
198 // matter that we universally include them in the flag key value.
199 SkASSERT((fShape.isRect() || fShape.isRRect()) ||
200 (fShape.dir() == GrShape::kDefaultDir &&
202
203 // Every key starts with the state from the GrShape (this includes path fill type,
204 // and any tracked winding, start, inversion, as well as the class of geometry).
205 *key++ = fShape.stateKey();
206
207 switch(fShape.type()) {
209 SkASSERT(fGenID != 0);
210 // Ensure that the path's inversion matches our state so that the path's key suffices.
211 SkASSERT(fShape.inverted() == fShape.path().isInverseFillType());
212
213 int dataKeySize = path_key_from_data_size(fShape.path());
214 if (dataKeySize >= 0) {
216 return;
217 } else {
218 *key++ = fGenID;
219 }
220 break; }
222 memcpy(key, &fShape.point(), sizeof(SkPoint));
223 key += sizeof(SkPoint) / sizeof(uint32_t);
224 break;
226 memcpy(key, &fShape.rect(), sizeof(SkRect));
227 key += sizeof(SkRect) / sizeof(uint32_t);
228 break;
230 fShape.rrect().writeToMemory(key);
231 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
232 break;
234 // Write dense floats first
235 memcpy(key, &fShape.arc(), sizeof(SkRect) + 2 * sizeof(float));
236 key += (sizeof(SkArc) / sizeof(uint32_t) - 1);
237 // Then write the final bool as an int, to make sure upper bits are set
238 *key++ = fShape.arc().fUseCenter ? 1 : 0;
239 break;
241 memcpy(key, &fShape.line(), sizeof(GrLineSegment));
242 key += sizeof(GrLineSegment) / sizeof(uint32_t);
243 break;
244 default:
245 // Nothing other than the flag state is needed in the key for an empty shape
246 SkASSERT(fShape.isEmpty());
247 }
248 }
249 SkASSERT(key - origKey == this->unstyledKeySize());
250}
static void write_path_key_from_data(const SkPath &path, uint32_t *origKey)
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
uint32_t stateKey() const
Definition GrShape.cpp:48
SkArc & arc()
Definition GrShape.h:143
SkPoint & point()
Definition GrShape.h:131
size_t writeToMemory(void *buffer) const
Definition SkRRect.cpp:599
bool fUseCenter
Definition SkArc.h:26

Member Data Documentation

◆ kMaxKeyFromDataVerbCnt

constexpr int GrStyledShape::kMaxKeyFromDataVerbCnt = 10
inlinestaticconstexpr

Definition at line 52 of file GrStyledShape.h.


The documentation for this class was generated from the following files: