Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | List of all members
SkDQuad Struct Reference

#include <SkPathOpsQuad.h>

Public Member Functions

bool collapsed () const
 
bool controlsInside () const
 
void debugInit ()
 
void debugSet (const SkDPoint *pts)
 
SkDQuad flip () const
 
const SkDQuadset (const SkPoint pts[kPointCount] SkDEBUGPARAMS(SkOpGlobalState *state=nullptr))
 
const SkDPointoperator[] (int n) const
 
SkDPointoperator[] (int n)
 
void align (int endIndex, SkDPoint *dstPt) const
 
SkDQuadPair chopAt (double t) const
 
SkDVector dxdyAtT (double t) const
 
int horizontalIntersect (double yIntercept, double roots[2]) const
 
bool hullIntersects (const SkDQuad &, bool *isLinear) const
 
bool hullIntersects (const SkDConic &, bool *isLinear) const
 
bool hullIntersects (const SkDCubic &, bool *isLinear) const
 
bool isLinear (int startIndex, int endIndex) const
 
bool monotonicInX () const
 
bool monotonicInY () const
 
void otherPts (int oddMan, const SkDPoint *endPt[2]) const
 
SkDPoint ptAtT (double t) const
 
SkDQuad subDivide (double t1, double t2) const
 
void subDivide (double t1, double t2, SkDQuad *quad) const
 
SkDPoint subDivide (const SkDPoint &a, const SkDPoint &c, double t1, double t2) const
 
int verticalIntersect (double xIntercept, double roots[2]) const
 
SkDCubic debugToCubic () const
 
void dump () const
 
void dumpID (int id) const
 
void dumpInner () const
 

Static Public Member Functions

static bool IsConic ()
 
static int AddValidTs (double s[], int realRoots, double *t)
 
static int FindExtrema (const double src[], double tValue[1])
 
static int maxIntersections ()
 
static int pointCount ()
 
static int pointLast ()
 
static int RootsReal (double A, double B, double C, double t[2])
 
static int RootsValidT (const double A, const double B, const double C, double s[2])
 
static void SetABC (const double *quad, double *a, double *b, double *c)
 
static SkDQuad SubDivide (const SkPoint a[kPointCount], double t1, double t2)
 
static SkDPoint SubDivide (const SkPoint pts[kPointCount], const SkDPoint &a, const SkDPoint &c, double t1, double t2)
 

Public Attributes

SkDPoint fPts [kPointCount]
 

Static Public Attributes

static const int kPointCount = 3
 
static const int kPointLast = kPointCount - 1
 
static const int kMaxIntersections = 4
 

Detailed Description

Definition at line 34 of file SkPathOpsQuad.h.

Member Function Documentation

◆ AddValidTs()

int SkDQuad::AddValidTs ( double  s[],
int  realRoots,
double *  t 
)
static

Definition at line 116 of file SkPathOpsQuad.cpp.

116 {
117 int foundRoots = 0;
118 for (int index = 0; index < realRoots; ++index) {
119 double tValue = s[index];
121 if (approximately_less_than_zero(tValue)) {
122 tValue = 0;
123 } else if (approximately_greater_than_one(tValue)) {
124 tValue = 1;
125 }
126 for (int idx2 = 0; idx2 < foundRoots; ++idx2) {
127 if (approximately_equal(t[idx2], tValue)) {
128 goto nextRoot;
129 }
130 }
131 t[foundRoots++] = tValue;
132 }
133nextRoot:
134 {}
135 }
136 return foundRoots;
137}
bool approximately_less_than_zero(double x)
bool approximately_equal(double x, double y)
bool approximately_one_or_less(double x)
bool approximately_zero_or_more(double x)
bool approximately_greater_than_one(double x)
struct MyStruct s

◆ align()

void SkDQuad::align ( int  endIndex,
SkDPoint dstPt 
) const

Definition at line 301 of file SkPathOpsQuad.cpp.

301 {
302 if (fPts[endIndex].fX == fPts[1].fX) {
303 dstPt->fX = fPts[endIndex].fX;
304 }
305 if (fPts[endIndex].fY == fPts[1].fY) {
306 dstPt->fY = fPts[endIndex].fY;
307 }
308}
SkDPoint fPts[kPointCount]
Definition: SkPathOpsQuad.h:39

◆ chopAt()

SkDQuadPair SkDQuad::chopAt ( double  t) const

Definition at line 354 of file SkPathOpsQuad.cpp.

355{
357 interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t);
358 interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t);
359 return dst;
360}
static double interp_quad_coords(const double *src, double t)
dst
Definition: cp.py:12

◆ collapsed()

bool SkDQuad::collapsed ( ) const
inline

Definition at line 41 of file SkPathOpsQuad.h.

41 {
43 }
bool approximatelyEqual(const SkDPoint &a) const

◆ controlsInside()

bool SkDQuad::controlsInside ( ) const
inline

Definition at line 45 of file SkPathOpsQuad.h.

45 {
46 SkDVector v01 = fPts[0] - fPts[1];
47 SkDVector v02 = fPts[0] - fPts[2];
48 SkDVector v12 = fPts[1] - fPts[2];
49 return v02.dot(v01) > 0 && v02.dot(v12) > 0;
50 }
double dot(const SkDVector &a) const

◆ debugInit()

void SkDQuad::debugInit ( )
inline

Definition at line 52 of file SkPathOpsQuad.h.

52 {
53 sk_bzero(fPts, sizeof(fPts));
54 }
sk_bzero(glyphs, sizeof(glyphs))

◆ debugSet()

void SkDQuad::debugSet ( const SkDPoint pts)

Definition at line 707 of file SkPathOpsDebug.cpp.

707 {
708 memcpy(fPts, pts, sizeof(fPts));
709 SkDEBUGCODE(fDebugGlobalState = nullptr);
710}
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()

◆ debugToCubic()

SkDCubic SkDQuad::debugToCubic ( ) const

Definition at line 695 of file SkPathOpsDebug.cpp.

695 {
697 cubic[0] = fPts[0];
698 cubic[2] = fPts[1];
699 cubic[3] = fPts[2];
700 cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3;
701 cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3;
702 cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3;
703 cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3;
704 return cubic;
705}
AI float cubic(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:195

◆ dump()

void SkDQuad::dump ( ) const

Definition at line 205 of file PathOpsDebug.cpp.

205 {
206 dumpInner();
207 SkDebugf("}},\n");
208}
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
void dumpInner() const

◆ dumpID()

void SkDQuad::dumpID ( int  id) const

Definition at line 210 of file PathOpsDebug.cpp.

210 {
211 dumpInner();
212 SkDebugf("}");
213 DumpID(id);
214}
static void DumpID(int id)

◆ dumpInner()

void SkDQuad::dumpInner ( ) const

Definition at line 216 of file PathOpsDebug.cpp.

216 {
217 SkDebugf("{{");
218 int index = 0;
219 do {
220 fPts[index].dump();
221 SkDebugf(", ");
222 } while (++index < 2);
223 fPts[index].dump();
224}
void dump() const

◆ dxdyAtT()

SkDVector SkDQuad::dxdyAtT ( double  t) const

Definition at line 206 of file SkPathOpsQuad.cpp.

206 {
207 double a = t - 1;
208 double b = 1 - 2 * t;
209 double c = t;
210 SkDVector result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX,
211 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY };
212 if (result.fX == 0 && result.fY == 0) {
213 if (zero_or_one(t)) {
214 result = fPts[2] - fPts[0];
215 } else {
216 // incomplete
217 SkDebugf("!q");
218 }
219 }
220 return result;
221}
bool zero_or_one(double x)
static bool b
struct MyStruct a[10]
GAsyncResult * result

◆ FindExtrema()

int SkDQuad::FindExtrema ( const double  src[],
double  tValue[1] 
)
static

Quad'(t) = At + B, where A = 2(a - 2b + c) B = 2(b - a) Solve for t, only if it fits between 0 < t < 1

Definition at line 384 of file SkPathOpsQuad.cpp.

384 {
385 /* At + B == 0
386 t = -B / A
387 */
388 double a = src[0];
389 double b = src[2];
390 double c = src[4];
391 return valid_unit_divide(a - b, a - b - b + c, tValue);
392}
static int valid_unit_divide(double numer, double denom, double *ratio)

◆ flip()

SkDQuad SkDQuad::flip ( ) const
inline

Definition at line 58 of file SkPathOpsQuad.h.

58 {
59 SkDQuad result = {{fPts[2], fPts[1], fPts[0]} SkDEBUGPARAMS(fDebugGlobalState) };
60 return result;
61 }
#define SkDEBUGPARAMS(...)

◆ horizontalIntersect()

int SkDQuad::horizontalIntersect ( double  yIntercept,
double  roots[2] 
) const

Return the number of valid roots (0 < root < 1) for this cubic intersecting the specified horizontal line.

Definition at line 472 of file SkDQuadLineIntersection.cpp.

472 {
473 return SkIntersections::HorizontalIntercept(*this, yIntercept, roots);
474}
static double HorizontalIntercept(const SkDLine &line, double y)

◆ hullIntersects() [1/3]

bool SkDQuad::hullIntersects ( const SkDConic conic,
bool *  isLinear 
) const

Definition at line 91 of file SkPathOpsQuad.cpp.

91 {
92 return conic.hullIntersects(*this, isLinear);
93}
AI float conic(float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:287
bool isLinear(int startIndex, int endIndex) const

◆ hullIntersects() [2/3]

bool SkDQuad::hullIntersects ( const SkDCubic cubic,
bool *  isLinear 
) const

Definition at line 95 of file SkPathOpsQuad.cpp.

95 {
96 return cubic.hullIntersects(*this, isLinear);
97}

◆ hullIntersects() [3/3]

bool SkDQuad::hullIntersects ( const SkDQuad q2,
bool *  isLinear 
) const

Definition at line 53 of file SkPathOpsQuad.cpp.

53 {
54 bool linear = true;
55 for (int oddMan = 0; oddMan < kPointCount; ++oddMan) {
56 const SkDPoint* endPt[2];
57 this->otherPts(oddMan, endPt);
58 double origX = endPt[0]->fX;
59 double origY = endPt[0]->fY;
60 double adj = endPt[1]->fX - origX;
61 double opp = endPt[1]->fY - origY;
62 double sign = (fPts[oddMan].fY - origY) * adj - (fPts[oddMan].fX - origX) * opp;
64 continue;
65 }
66 linear = false;
67 bool foundOutlier = false;
68 for (int n = 0; n < kPointCount; ++n) {
69 double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp;
70 if (test * sign > 0 && !precisely_zero(test)) {
71 foundOutlier = true;
72 break;
73 }
74 }
75 if (!foundOutlier) {
76 return false;
77 }
78 }
79 if (linear && !matchesEnd(fPts, q2.fPts[0]) && !matchesEnd(fPts, q2.fPts[2])) {
80 // if the end point of the opposite quad is inside the hull that is nearly a line,
81 // then representing the quad as a line may cause the intersection to be missed.
82 // Check to see if the endpoint is in the triangle.
83 if (pointInTriangle(fPts, q2.fPts[0]) || pointInTriangle(fPts, q2.fPts[2])) {
84 linear = false;
85 }
86 }
88 return true;
89}
static bool approximately_zero(double x)
Definition: SkCubics.cpp:153
static bool pointInTriangle(const SkDPoint fPts[3], const SkDPoint &test)
static bool matchesEnd(const SkDPoint fPts[3], const SkDPoint &test)
bool precisely_zero(double x)
static int sign(SkScalar x)
Definition: SkPath.cpp:2205
void otherPts(int oddMan, const SkDPoint *endPt[2]) const
static const int kPointCount
Definition: SkPathOpsQuad.h:35
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)

◆ IsConic()

static bool SkDQuad::IsConic ( )
inlinestatic

Definition at line 63 of file SkPathOpsQuad.h.

63{ return false; }

◆ isLinear()

bool SkDQuad::isLinear ( int  startIndex,
int  endIndex 
) const

Definition at line 192 of file SkPathOpsQuad.cpp.

192 {
193 SkLineParameters lineParameters;
194 lineParameters.quadEndPoints(*this, startIndex, endIndex);
195 // FIXME: maybe it's possible to avoid this and compare non-normalized
196 lineParameters.normalize();
197 double distance = lineParameters.controlPtDistance(*this);
198 double tiniest = std::min(std::min(std::min(std::min(std::min(fPts[0].fX, fPts[0].fY),
199 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY);
200 double largest = std::max(std::max(std::max(std::max(std::max(fPts[0].fX, fPts[0].fY),
201 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY);
202 largest = std::max(largest, -tiniest);
204}
bool approximately_zero_when_compared_to(double x, double y)
double controlPtDistance(const SkDCubic &pts, int index) const
bool quadEndPoints(const SkDQuad &pts)
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48

◆ maxIntersections()

static int SkDQuad::maxIntersections ( )
inlinestatic

Definition at line 97 of file SkPathOpsQuad.h.

97{ return kMaxIntersections; }
static const int kMaxIntersections
Definition: SkPathOpsQuad.h:37

◆ monotonicInX()

bool SkDQuad::monotonicInX ( ) const

Definition at line 253 of file SkPathOpsQuad.cpp.

253 {
254 return between(fPts[0].fX, fPts[1].fX, fPts[2].fX);
255}
bool between(double a, double b, double c)

◆ monotonicInY()

bool SkDQuad::monotonicInY ( ) const

Definition at line 257 of file SkPathOpsQuad.cpp.

257 {
258 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY);
259}

◆ operator[]() [1/2]

SkDPoint & SkDQuad::operator[] ( int  n)
inline

Definition at line 75 of file SkPathOpsQuad.h.

75{ SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
#define SkASSERT(cond)
Definition: SkAssert.h:116

◆ operator[]() [2/2]

const SkDPoint & SkDQuad::operator[] ( int  n) const
inline

Definition at line 74 of file SkPathOpsQuad.h.

74{ SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }

◆ otherPts()

void SkDQuad::otherPts ( int  oddMan,
const SkDPoint endPt[2] 
) const

Definition at line 108 of file SkPathOpsQuad.cpp.

108 {
109 for (int opp = 1; opp < kPointCount; ++opp) {
110 int end = (oddMan ^ opp) - oddMan; // choose a value not equal to oddMan
111 end &= ~(end >> 2); // if the value went negative, set it to zero
112 endPt[opp - 1] = &fPts[end];
113 }
114}
glong glong end

◆ pointCount()

static int SkDQuad::pointCount ( )
inlinestatic

Definition at line 101 of file SkPathOpsQuad.h.

101{ return kPointCount; }

◆ pointLast()

static int SkDQuad::pointLast ( )
inlinestatic

Definition at line 102 of file SkPathOpsQuad.h.

102{ return kPointLast; }
static const int kPointLast
Definition: SkPathOpsQuad.h:36

◆ ptAtT()

SkDPoint SkDQuad::ptAtT ( double  t) const

Definition at line 224 of file SkPathOpsQuad.cpp.

224 {
225 if (0 == t) {
226 return fPts[0];
227 }
228 if (1 == t) {
229 return fPts[2];
230 }
231 double one_t = 1 - t;
232 double a = one_t * one_t;
233 double b = 2 * one_t * t;
234 double c = t * t;
235 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX,
236 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY };
237 return result;
238}

◆ RootsReal()

int SkDQuad::RootsReal ( double  A,
double  B,
double  C,
double  t[2] 
)
static

Definition at line 169 of file SkPathOpsQuad.cpp.

169 {
170 if (!A) {
171 return handle_zero(B, C, s);
172 }
173 const double p = B / (2 * A);
174 const double q = C / A;
176 return handle_zero(B, C, s);
177 }
178 /* normal form: x^2 + px + q = 0 */
179 const double p2 = p * p;
180 if (!AlmostDequalUlps(p2, q) && p2 < q) {
181 return 0;
182 }
183 double sqrt_D = 0;
184 if (p2 > q) {
185 sqrt_D = sqrt(p2 - q);
186 }
187 s[0] = sqrt_D - p;
188 s[1] = -sqrt_D - p;
189 return 1 + !AlmostDequalUlps(s[0], s[1]);
190}
static int handle_zero(const double B, const double C, double s[2])
bool AlmostDequalUlps(float a, float b)
bool approximately_zero_inverse(double x)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706

◆ RootsValidT()

int SkDQuad::RootsValidT ( const double  A,
const double  B,
const double  C,
double  s[2] 
)
static

Definition at line 144 of file SkPathOpsQuad.cpp.

144 {
145 double s[2];
146 int realRoots = RootsReal(A, B, C, s);
147 int foundRoots = AddValidTs(s, realRoots, t);
148 return foundRoots;
149}
static int RootsReal(double A, double B, double C, double t[2])
static int AddValidTs(double s[], int realRoots, double *t)

◆ set()

const SkDQuad & SkDQuad::set ( const SkPoint pts   SkDEBUGPARAMS(SkOpGlobalState *state=nullptr)[kPointCount])
inline

Definition at line 65 of file SkPathOpsQuad.h.

66 {
67 fPts[0] = pts[0];
68 fPts[1] = pts[1];
69 fPts[2] = pts[2];
70 SkDEBUGCODE(fDebugGlobalState = state);
71 return *this;
72 }
AtkStateType state

◆ SetABC()

void SkDQuad::SetABC ( const double *  quad,
double *  a,
double *  b,
double *  c 
)
static

Definition at line 400 of file SkPathOpsQuad.cpp.

400 {
401 *a = quad[0]; // a = A
402 *b = 2 * quad[2]; // b = 2*B
403 *c = quad[4]; // c = C
404 *b -= *c; // b = 2*B - C
405 *a -= *b; // a = A - 2*B + C
406 *b -= *c; // b = 2*B - 2*C
407}

◆ subDivide() [1/3]

SkDPoint SkDQuad::subDivide ( const SkDPoint a,
const SkDPoint c,
double  t1,
double  t2 
) const

Definition at line 310 of file SkPathOpsQuad.cpp.

310 {
311 SkASSERT(t1 != t2);
312 SkDPoint b;
313 SkDQuad sub = subDivide(t1, t2);
314 SkDLine b0 = {{a, sub[1] + (a - sub[0])}};
315 SkDLine b1 = {{c, sub[1] + (c - sub[2])}};
317 i.intersectRay(b0, b1);
318 if (i.used() == 1 && i[0][0] >= 0 && i[1][0] >= 0) {
319 b = i.pt(0);
320 } else {
321 SkASSERT(i.used() <= 2);
322 return SkDPoint::Mid(b0[1], b1[1]);
323 }
324 if (t1 == 0 || t2 == 0) {
325 align(0, &b);
326 }
327 if (t1 == 1 || t2 == 1) {
328 align(2, &b);
329 }
330 if (AlmostBequalUlps(b.fX, a.fX)) {
331 b.fX = a.fX;
332 } else if (AlmostBequalUlps(b.fX, c.fX)) {
333 b.fX = c.fX;
334 }
335 if (AlmostBequalUlps(b.fY, a.fY)) {
336 b.fY = a.fY;
337 } else if (AlmostBequalUlps(b.fY, c.fY)) {
338 b.fY = c.fY;
339 }
340 return b;
341}
bool AlmostBequalUlps(float a, float b)
static SkDPoint Mid(const SkDPoint &a, const SkDPoint &b)
SkDQuad subDivide(double t1, double t2) const
void align(int endIndex, SkDPoint *dstPt) const

◆ SubDivide() [1/2]

static SkDQuad SkDQuad::SubDivide ( const SkPoint  a[kPointCount],
double  t1,
double  t2 
)
inlinestatic

Definition at line 110 of file SkPathOpsQuad.h.

110 {
111 SkDQuad quad;
112 quad.set(a);
113 return quad.subDivide(t1, t2);
114 }
const SkDQuad & set(const SkPoint pts[kPointCount] SkDEBUGPARAMS(SkOpGlobalState *state=nullptr))
Definition: SkPathOpsQuad.h:65

◆ SubDivide() [2/2]

static SkDPoint SkDQuad::SubDivide ( const SkPoint  pts[kPointCount],
const SkDPoint a,
const SkDPoint c,
double  t1,
double  t2 
)
inlinestatic

Definition at line 116 of file SkPathOpsQuad.h.

117 {
118 SkDQuad quad;
119 quad.set(pts);
120 return quad.subDivide(a, c, t1, t2);
121 }

◆ subDivide() [2/3]

SkDQuad SkDQuad::subDivide ( double  t1,
double  t2 
) const

Definition at line 285 of file SkPathOpsQuad.cpp.

285 {
286 if (0 == t1 && 1 == t2) {
287 return *this;
288 }
289 SkDQuad dst;
290 double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1);
291 double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1);
292 double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2);
293 double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2);
294 double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2);
295 double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2);
296 /* bx = */ dst[1].fX = 2 * dx - (ax + cx) / 2;
297 /* by = */ dst[1].fY = 2 * dy - (ay + cy) / 2;
298 return dst;
299}
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ subDivide() [3/3]

void SkDQuad::subDivide ( double  t1,
double  t2,
SkDQuad quad 
) const
inline

Definition at line 108 of file SkPathOpsQuad.h.

108{ *quad = this->subDivide(t1, t2); }

◆ verticalIntersect()

int SkDQuad::verticalIntersect ( double  xIntercept,
double  roots[2] 
) const

Return the number of valid roots (0 < root < 1) for this cubic intersecting the specified vertical line.

Definition at line 476 of file SkDQuadLineIntersection.cpp.

476 {
477 return SkIntersections::VerticalIntercept(*this, xIntercept, roots);
478}
static double VerticalIntercept(const SkDLine &line, double x)

Member Data Documentation

◆ fPts

SkDPoint SkDQuad::fPts[kPointCount]

Definition at line 39 of file SkPathOpsQuad.h.

◆ kMaxIntersections

const int SkDQuad::kMaxIntersections = 4
static

Definition at line 37 of file SkPathOpsQuad.h.

◆ kPointCount

const int SkDQuad::kPointCount = 3
static

Definition at line 35 of file SkPathOpsQuad.h.

◆ kPointLast

const int SkDQuad::kPointLast = kPointCount - 1
static

Definition at line 36 of file SkPathOpsQuad.h.


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