Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Static Public Attributes | List of all members
skgpu::graphite::Shape Class Reference

#include <Shape.h>

Public Types

enum class  Type : uint8_t {
  kEmpty , kLine , kRect , kRRect ,
  kPath
}
 

Public Member Functions

 Shape ()
 
 Shape (const Shape &shape)
 
 Shape (Shape &&)=delete
 
 Shape (SkPoint p0, SkPoint p1)
 
 Shape (SkV2 p0, SkV2 p1)
 
 Shape (skvx::float2 p0, skvx::float2 p1)
 
 Shape (const Rect &rect)
 
 Shape (const SkRect &rect)
 
 Shape (const SkRRect &rrect)
 
 Shape (const SkPath &path)
 
 ~Shape ()
 
Shapeoperator= (Shape &&)=delete
 
Shapeoperator= (const Shape &)
 
Type type () const
 
bool isEmpty () const
 
bool isLine () const
 
bool isRect () const
 
bool isRRect () const
 
bool isPath () const
 
bool inverted () const
 
void setInverted (bool inverted)
 
SkPathFillType fillType () const
 
bool conservativeContains (const Rect &rect) const
 
bool conservativeContains (skvx::float2 point) const
 
bool convex (bool simpleFill=true) const
 
Rect bounds () const
 
SkPath asPath () const
 
skvx::float2 p0 () const
 
skvx::float2 p1 () const
 
skvx::float4 line () const
 
const Rectrect () const
 
const SkRRectrrect () const
 
const SkPathpath () const
 
void setLine (SkPoint p0, SkPoint p1)
 
void setLine (SkV2 p0, SkV2 p1)
 
void setLine (skvx::float2 p0, skvx::float2 p1)
 
void setRect (const SkRect &rect)
 
void setRect (const Rect &rect)
 
void setRRect (const SkRRect &rrect)
 
void setPath (const SkPath &path)
 
void reset ()
 
int keySize () const
 
bool hasKey () const
 
void writeKey (uint32_t *key, bool includeInverted) const
 

Static Public Attributes

static constexpr int kTypeCount = static_cast<int>(Type::kPath) + 1
 

Detailed Description

Shape is effectively a std::variant over different geometric shapes, with the most complex being an SkPath. It provides a consistent way to query geometric properties, such as convexity, point containment, or iteration.

Definition at line 28 of file Shape.h.

Member Enumeration Documentation

◆ Type

enum class skgpu::graphite::Shape::Type : uint8_t
strong
Enumerator
kEmpty 
kLine 
kRect 
kRRect 
kPath 

Definition at line 30 of file Shape.h.

30 : uint8_t {
32 };
@ kRRect
constexpr std::array< std::array< float, 2 >, 2 > kRect
@ kPath
Definition: SkGlyph.h:317

Constructor & Destructor Documentation

◆ Shape() [1/10]

skgpu::graphite::Shape::Shape ( )
inline

Definition at line 35 of file Shape.h.

35{}

◆ Shape() [2/10]

skgpu::graphite::Shape::Shape ( const Shape shape)
inline

Definition at line 36 of file Shape.h.

36{ *this = shape; }

◆ Shape() [3/10]

skgpu::graphite::Shape::Shape ( Shape &&  )
delete

◆ Shape() [4/10]

skgpu::graphite::Shape::Shape ( SkPoint  p0,
SkPoint  p1 
)
inline

Definition at line 39 of file Shape.h.

39{ this->setLine(p0, p1); }
void setLine(SkPoint p0, SkPoint p1)
Definition: Shape.h:114
skvx::float2 p1() const
Definition: Shape.h:103

◆ Shape() [5/10]

skgpu::graphite::Shape::Shape ( SkV2  p0,
SkV2  p1 
)
inline

Definition at line 40 of file Shape.h.

40{ this->setLine(p0, p1); }

◆ Shape() [6/10]

skgpu::graphite::Shape::Shape ( skvx::float2  p0,
skvx::float2  p1 
)
inline

Definition at line 41 of file Shape.h.

41{ this->setLine(p0, p1); }

◆ Shape() [7/10]

skgpu::graphite::Shape::Shape ( const Rect rect)
inlineexplicit

Definition at line 42 of file Shape.h.

42{ this->setRect(rect); }
const Rect & rect() const
Definition: Shape.h:105
void setRect(const SkRect &rect)
Definition: Shape.h:125

◆ Shape() [8/10]

skgpu::graphite::Shape::Shape ( const SkRect rect)
inlineexplicit

Definition at line 43 of file Shape.h.

43{ this->setRect(rect); }

◆ Shape() [9/10]

skgpu::graphite::Shape::Shape ( const SkRRect rrect)
inlineexplicit

Definition at line 44 of file Shape.h.

44{ this->setRRect(rrect); }
void setRRect(const SkRRect &rrect)
Definition: Shape.h:131

◆ Shape() [10/10]

skgpu::graphite::Shape::Shape ( const SkPath path)
inlineexplicit

Definition at line 45 of file Shape.h.

45{ this->setPath(path); }
void setPath(const SkPath &path)
Definition: Shape.h:136

◆ ~Shape()

skgpu::graphite::Shape::~Shape ( )
inline

Definition at line 47 of file Shape.h.

47{ this->reset(); }

Member Function Documentation

◆ asPath()

SkPath skgpu::graphite::Shape::asPath ( ) const

Definition at line 80 of file Shape.cpp.

80 {
81 if (fType == Type::kPath) {
82 return fPath;
83 }
84
86 switch (fType) {
87 case Type::kEmpty: /* do nothing */ break;
88 case Type::kLine: builder.moveTo(fRect.left(), fRect.top())
89 .lineTo(fRect.right(), fRect.bot()); break;
90 case Type::kRect: builder.addRect(fRect.asSkRect()); break;
91 case Type::kRRect: builder.addRRect(fRRect); break;
93 }
94 return builder.detach();
95}
#define SkUNREACHABLE
Definition: SkAssert.h:135
AI float bot() const
Definition: Rect.h:79
AI float top() const
Definition: Rect.h:77
AI float left() const
Definition: Rect.h:76
AI SkRect asSkRect() const
Definition: Rect.h:91
AI float right() const
Definition: Rect.h:78
SkPathFillType fillType() const
Definition: Shape.h:77

◆ bounds()

Rect skgpu::graphite::Shape::bounds ( ) const

Definition at line 69 of file Shape.cpp.

69 {
70 switch (fType) {
71 case Type::kEmpty: return Rect(0, 0, 0, 0);
72 case Type::kLine: return fRect.makeSorted(); // sorting corners computes bbox of segment
73 case Type::kRect: return fRect; // assuming it's sorted
74 case Type::kRRect: return fRRect.getBounds();
75 case Type::kPath: return fPath.getBounds();
76 }
78}
const SkRect & getBounds() const
Definition: SkPath.cpp:430
const SkRect & getBounds() const
Definition: SkRRect.h:279
AI Rect makeSorted() const
Definition: Rect.h:141
TRect< Scalar > Rect
Definition: rect.h:769

◆ conservativeContains() [1/2]

bool skgpu::graphite::Shape::conservativeContains ( const Rect rect) const

Definition at line 37 of file Shape.cpp.

37 {
38 switch (fType) {
39 case Type::kEmpty: return false;
40 case Type::kLine: return false;
41 case Type::kRect: return fRect.contains(rect);
44 }
46}
bool conservativelyContainsRect(const SkRect &rect) const
Definition: SkPath.cpp:291
bool contains(const SkRect &rect) const
Definition: SkRRect.cpp:360
AI bool contains(Rect rect) const
Definition: Rect.h:127

◆ conservativeContains() [2/2]

bool skgpu::graphite::Shape::conservativeContains ( skvx::float2  point) const

Definition at line 48 of file Shape.cpp.

48 {
49 switch (fType) {
50 case Type::kEmpty: return false;
51 case Type::kLine: return false;
52 case Type::kRect: return fRect.contains(Rect::Point(point));
53 case Type::kRRect: return SkRRectPriv::ContainsPoint(fRRect, {point.x(), point.y()});
54 case Type::kPath: return fPath.contains(point.x(), point.y());
55 }
57}
bool contains(SkScalar x, SkScalar y) const
Definition: SkPath.cpp:3118
static bool ContainsPoint(const SkRRect &rr, const SkPoint &p)
Definition: SkRRectPriv.h:48
static AI Rect Point(float2 p)
Definition: Rect.h:52

◆ convex()

bool skgpu::graphite::Shape::convex ( bool  simpleFill = true) const

Definition at line 59 of file Shape.cpp.

59 {
60 if (this->isPath()) {
61 // SkPath.isConvex() really means "is this path convex were it to be closed".
62 return (simpleFill || fPath.isLastContourClosed()) && fPath.isConvex();
63 } else {
64 // Every other shape type is convex by construction.
65 return true;
66 }
67}
bool isConvex() const
Definition: SkPath.cpp:426
bool isLastContourClosed() const
Definition: SkPath.cpp:390
bool isPath() const
Definition: Shape.h:63

◆ fillType()

SkPathFillType skgpu::graphite::Shape::fillType ( ) const
inline

Definition at line 77 of file Shape.h.

77 {
78 if (fType == Type::kPath) {
79 return fPath.getFillType(); // already incorporates invertedness
80 } else {
82 }
83 }
SkPathFillType getFillType() const
Definition: SkPath.h:230

◆ hasKey()

bool skgpu::graphite::Shape::hasKey ( ) const
inline

Definition at line 159 of file Shape.h.

159{ return this->keySize() >= 0; }
int keySize() const
Definition: Shape.cpp:140

◆ inverted()

bool skgpu::graphite::Shape::inverted ( ) const
inline

Definition at line 65 of file Shape.h.

65 {
66 SkASSERT(fType != Type::kPath || fInverted == fPath.isInverseFillType());
67 return fInverted;
68 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
bool isInverseFillType() const
Definition: SkPath.h:244

◆ isEmpty()

bool skgpu::graphite::Shape::isEmpty ( ) const
inline

Definition at line 59 of file Shape.h.

59{ return fType == Type::kEmpty; }

◆ isLine()

bool skgpu::graphite::Shape::isLine ( ) const
inline

Definition at line 60 of file Shape.h.

60{ return fType == Type::kLine; }

◆ isPath()

bool skgpu::graphite::Shape::isPath ( ) const
inline

Definition at line 63 of file Shape.h.

63{ return fType == Type::kPath; }

◆ isRect()

bool skgpu::graphite::Shape::isRect ( ) const
inline

Definition at line 61 of file Shape.h.

61{ return fType == Type::kRect; }

◆ isRRect()

bool skgpu::graphite::Shape::isRRect ( ) const
inline

Definition at line 62 of file Shape.h.

62{ return fType == Type::kRRect; }

◆ keySize()

int skgpu::graphite::Shape::keySize ( ) const

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

Definition at line 140 of file Shape.cpp.

140 {
141 int count = 1; // Every key has the state flags from the Shape
142 switch(this->type()) {
143 case Type::kLine:
144 static_assert(0 == sizeof(skvx::float4) % sizeof(uint32_t));
145 count += sizeof(skvx::float4) / sizeof(uint32_t);
146 break;
147 case Type::kRect:
148 static_assert(0 == sizeof(Rect) % sizeof(uint32_t));
149 count += sizeof(Rect) / sizeof(uint32_t);
150 break;
151 case Type::kRRect:
152 static_assert(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
153 count += SkRRect::kSizeInMemory / sizeof(uint32_t);
154 break;
155 case Type::kPath: {
156 if (this->path().isVolatile()) {
157 return -1; // volatile, so won't be keyed
158 }
159 if (this->path().isEmpty()) {
160 return -1; // empty, so won't be keyed
161 }
162 int dataKeySize = path_key_from_data_size(this->path());
163 if (dataKeySize >= 0) {
164 count += dataKeySize;
165 } else {
166 count++; // Just adds the gen ID.
167 }
168 break;
169 }
170 default:
171 // else it's empty, which just needs the state flags for its key
172 SkASSERT(this->isEmpty());
173 }
174 return count;
175}
int count
Definition: FontMgrTest.cpp:50
static int path_key_from_data_size(const SkPath &path)
bool isEmpty() const
Definition: SkPath.cpp:416
bool isVolatile() const
Definition: SkPath.h:350
static constexpr size_t kSizeInMemory
Definition: SkRRect.h:422
const SkPath & path() const
Definition: Shape.h:107
bool isEmpty() const
Definition: Shape.h:59
Type type() const
Definition: Shape.h:57
Vec< 4, float > float4
Definition: SkVx.h:1146

◆ line()

skvx::float4 skgpu::graphite::Shape::line ( ) const
inline

Definition at line 104 of file Shape.h.

104{ SkASSERT(this->isLine()); return fRect.ltrb(); }
AI float4 ltrb() const
Definition: Rect.h:82
bool isLine() const
Definition: Shape.h:60

◆ operator=() [1/2]

Shape & skgpu::graphite::Shape::operator= ( const Shape shape)

Definition at line 24 of file Shape.cpp.

24 {
25 switch (shape.type()) {
26 case Type::kEmpty: this->reset(); break;
27 case Type::kLine: this->setLine(shape.p0(), shape.p1()); break;
28 case Type::kRect: this->setRect(shape.rect()); break;
29 case Type::kRRect: this->setRRect(shape.rrect()); break;
30 case Type::kPath: this->setPath(shape.path()); break;
31 }
32
33 fInverted = shape.fInverted;
34 return *this;
35}

◆ operator=() [2/2]

Shape & skgpu::graphite::Shape::operator= ( Shape &&  )
delete

◆ p0()

skvx::float2 skgpu::graphite::Shape::p0 ( ) const
inline

Definition at line 102 of file Shape.h.

102{ SkASSERT(this->isLine()); return fRect.topLeft(); }
AI float2 topLeft() const
Definition: Rect.h:80

◆ p1()

skvx::float2 skgpu::graphite::Shape::p1 ( ) const
inline

Definition at line 103 of file Shape.h.

103{ SkASSERT(this->isLine()); return fRect.botRight(); }
AI float2 botRight() const
Definition: Rect.h:81

◆ path()

const SkPath & skgpu::graphite::Shape::path ( ) const
inline

Definition at line 107 of file Shape.h.

107{ SkASSERT(this->isPath()); return fPath; }

◆ rect()

const Rect & skgpu::graphite::Shape::rect ( ) const
inline

Definition at line 105 of file Shape.h.

105{ SkASSERT(this->isRect()); return fRect; }
bool isRect() const
Definition: Shape.h:61

◆ reset()

void skgpu::graphite::Shape::reset ( )
inline

Definition at line 148 of file Shape.h.

148 {
149 this->setType(Type::kEmpty);
150 fInverted = false;
151 }

◆ rrect()

const SkRRect & skgpu::graphite::Shape::rrect ( ) const
inline

Definition at line 106 of file Shape.h.

106{ SkASSERT(this->isRRect()); return fRRect; }
bool isRRect() const
Definition: Shape.h:62

◆ setInverted()

void skgpu::graphite::Shape::setInverted ( bool  inverted)
inline

Definition at line 70 of file Shape.h.

70 {
71 if (fType == Type::kPath && inverted != fPath.isInverseFillType()) {
73 }
74 fInverted = inverted;
75 }
void toggleInverseFillType()
Definition: SkPath.h:249
bool inverted() const
Definition: Shape.h:65

◆ setLine() [1/3]

void skgpu::graphite::Shape::setLine ( SkPoint  p0,
SkPoint  p1 
)
inline

Definition at line 114 of file Shape.h.

114 {
115 this->setLine(skvx::float2{p0.fX, p0.fY}, skvx::float2{p1.fX, p1.fY});
116 }
skvx::float2 p0() const
Definition: Shape.h:102
Definition: SkVx.h:83

◆ setLine() [2/3]

void skgpu::graphite::Shape::setLine ( SkV2  p0,
SkV2  p1 
)
inline

Definition at line 117 of file Shape.h.

117 {
118 this->setLine(skvx::float2{p0.x, p0.y}, skvx::float2{p1.x, p1.y});
119 }

◆ setLine() [3/3]

void skgpu::graphite::Shape::setLine ( skvx::float2  p0,
skvx::float2  p1 
)
inline

Definition at line 120 of file Shape.h.

120 {
121 this->setType(Type::kLine);
122 fRect = Rect(p0, p1);
123 fInverted = false;
124 }

◆ setPath()

void skgpu::graphite::Shape::setPath ( const SkPath path)
inline

Definition at line 136 of file Shape.h.

136 {
137 if (fType == Type::kPath) {
138 // Assign directly
139 fPath = path;
140 } else {
141 // In-place initialize
142 this->setType(Type::kPath);
143 new (&fPath) SkPath(path);
144 }
145 fInverted = path.isInverseFillType();
146 }
Definition: SkPath.h:59

◆ setRect() [1/2]

void skgpu::graphite::Shape::setRect ( const Rect rect)
inline

Definition at line 126 of file Shape.h.

126 {
127 this->setType(Type::kRect);
128 fRect = rect;
129 fInverted = false;
130 }

◆ setRect() [2/2]

void skgpu::graphite::Shape::setRect ( const SkRect rect)
inline

Definition at line 125 of file Shape.h.

125{ this->setRect(Rect(rect)); }

◆ setRRect()

void skgpu::graphite::Shape::setRRect ( const SkRRect rrect)
inline

Definition at line 131 of file Shape.h.

131 {
132 this->setType(Type::kRRect);
133 fRRect = rrect;
134 fInverted = false;
135 }
const SkRRect & rrect() const
Definition: Shape.h:106

◆ type()

Type skgpu::graphite::Shape::type ( ) const
inline

Definition at line 57 of file Shape.h.

57{ return fType; }

◆ writeKey()

void skgpu::graphite::Shape::writeKey ( uint32_t *  key,
bool  includeInverted 
) const

Writes keySize() bytes into the provided pointer. Assumes that there is enough space allocated for the key and that keySize() does not return a negative value for this shape. If includeInverted is false, non-inverted state will be written into the key regardless of the Shape's state.

Definition at line 177 of file Shape.cpp.

177 {
178 SkASSERT(this->keySize());
179 SkDEBUGCODE(uint32_t* origKey = key;)
180
181 // Every key starts with the state from the Shape (this includes path fill type,
182 // and any tracked inversion, as well as the class of geometry).
183 *key++ = this->stateKey(includeInverted);
184
185 switch(this->type()) {
186 case Type::kPath: {
187 SkASSERT(!this->path().isVolatile());
188 SkASSERT(!this->path().isEmpty());
189 // Ensure that the path's inversion matches our state so that the path's key suffices.
190 SkASSERT(this->inverted() == this->path().isInverseFillType());
191
192 int dataKeySize = path_key_from_data_size(this->path());
193 if (dataKeySize >= 0) {
195 return;
196 } else {
197 *key++ = this->path().getGenerationID();
198 }
199 break;
200 }
201 case Type::kRect:
202 memcpy(key, &this->rect(), sizeof(Rect));
203 key += sizeof(Rect) / sizeof(uint32_t);
204 break;
205 case Type::kRRect:
206 this->rrect().writeToMemory(key);
207 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
208 break;
209 case Type::kLine: {
210 skvx::float4 line = this->line();
211 memcpy(key, &line, sizeof(skvx::float4));
212 key += sizeof(skvx::float4) / sizeof(uint32_t);
213 break;
214 }
215 default:
216 // Nothing other than the flag state is needed in the key for an empty shape
217 SkASSERT(this->isEmpty());
218 }
219 SkASSERT(key - origKey == this->keySize());
220}
static void write_path_key_from_data(const SkPath &path, uint32_t *origKey)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
uint32_t getGenerationID() const
Definition: SkPath.cpp:366
size_t writeToMemory(void *buffer) const
Definition: SkRRect.cpp:599
skvx::float4 line() const
Definition: Shape.h:104

Member Data Documentation

◆ fPath

SkPath skgpu::graphite::Shape::fPath

Definition at line 188 of file Shape.h.

◆ fRect

Rect skgpu::graphite::Shape::fRect

Definition at line 186 of file Shape.h.

◆ fRRect

SkRRect skgpu::graphite::Shape::fRRect

Definition at line 187 of file Shape.h.

◆ kTypeCount

constexpr int skgpu::graphite::Shape::kTypeCount = static_cast<int>(Type::kPath) + 1
inlinestaticconstexpr

Definition at line 33 of file Shape.h.


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