Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkQuadClipper.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2009 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
10
11#include <cstring>
12#include <utility>
13
17
19 // conver to scalars, since that's where we'll see the points
20 fClip.set(clip);
21}
22
23///////////////////////////////////////////////////////////////////////////////
24
27 /* Solve F(t) = y where F(t) := [0](1-t)^2 + 2[1]t(1-t) + [2]t^2
28 * We solve for t, using quadratic equation, hence we have to rearrange
29 * our cooefficents to look like At^2 + Bt + C
30 */
31 SkScalar A = c0 - c1 - c1 + c2;
32 SkScalar B = 2*(c1 - c0);
33 SkScalar C = c0 - target;
34
35 SkScalar roots[2]; // we only expect one, but make room for 2 for safety
36 int count = SkFindUnitQuadRoots(A, B, C, roots);
37 if (count) {
38 *t = roots[0];
39 return true;
40 }
41 return false;
42}
43
44static bool chopMonoQuadAtY(SkPoint pts[3], SkScalar y, SkScalar* t) {
45 return chopMonoQuadAt(pts[0].fY, pts[1].fY, pts[2].fY, y, t);
46}
47
48///////////////////////////////////////////////////////////////////////////////
49
50/* If we somehow returned the fact that we had to flip the pts in Y, we could
51 communicate that to setQuadratic, and then avoid having to flip it back
52 here (only to have setQuadratic do the flip again)
53 */
54bool SkQuadClipper::clipQuad(const SkPoint srcPts[3], SkPoint dst[3]) {
55 bool reverse;
56
57 // we need the data to be monotonically increasing in Y
58 if (srcPts[0].fY > srcPts[2].fY) {
59 dst[0] = srcPts[2];
60 dst[1] = srcPts[1];
61 dst[2] = srcPts[0];
62 reverse = true;
63 } else {
64 memcpy(dst, srcPts, 3 * sizeof(SkPoint));
65 reverse = false;
66 }
67
68 // are we completely above or below
69 const SkScalar ctop = fClip.fTop;
70 const SkScalar cbot = fClip.fBottom;
71 if (dst[2].fY <= ctop || dst[0].fY >= cbot) {
72 return false;
73 }
74
75 SkScalar t;
76 SkPoint tmp[5]; // for SkChopQuadAt
77
78 // are we partially above
79 if (dst[0].fY < ctop) {
80 if (chopMonoQuadAtY(dst, ctop, &t)) {
81 // take the 2nd chopped quad
82 SkChopQuadAt(dst, tmp, t);
83 dst[0] = tmp[2];
84 dst[1] = tmp[3];
85 } else {
86 // if chopMonoQuadAtY failed, then we may have hit inexact numerics
87 // so we just clamp against the top
88 for (int i = 0; i < 3; i++) {
89 if (dst[i].fY < ctop) {
90 dst[i].fY = ctop;
91 }
92 }
93 }
94 }
95
96 // are we partially below
97 if (dst[2].fY > cbot) {
98 if (chopMonoQuadAtY(dst, cbot, &t)) {
99 SkChopQuadAt(dst, tmp, t);
100 dst[1] = tmp[1];
101 dst[2] = tmp[2];
102 } else {
103 // if chopMonoQuadAtY failed, then we may have hit inexact numerics
104 // so we just clamp against the bottom
105 for (int i = 0; i < 3; i++) {
106 if (dst[i].fY > cbot) {
107 dst[i].fY = cbot;
108 }
109 }
110 }
111 }
112
113 if (reverse) {
114 using std::swap;
115 swap(dst[0], dst[2]);
116 }
117 return true;
118}
int count
static bool chopMonoQuadAtY(SkPoint pts[3], SkScalar y, SkScalar *t)
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t)
int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2])
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
static bool chopMonoQuadAtY(SkPoint pts[3], SkScalar y, SkScalar *t)
static bool chopMonoQuadAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar target, SkScalar *t)
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition SkRefCnt.h:341
void setClip(const SkIRect &clip)
bool clipQuad(const SkPoint src[3], SkPoint dst[3])
float SkScalar
Definition extension.cpp:12
uint32_t * target
double y
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
void set(const SkIRect &src)
Definition SkRect.h:849
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15
void setEmpty()
Definition SkRect.h:842