Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Macros | Functions
SkRect.cpp File Reference
#include "include/core/SkRect.h"
#include "include/core/SkM44.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTPin.h"
#include "src/core/SkRectPriv.h"
#include "src/base/SkVx.h"
#include "include/core/SkString.h"
#include "src/core/SkStringUtils.h"

Go to the source code of this file.

Macros

#define CHECK_INTERSECT(al, at, ar, ab, bl, bt, br, bb)
 

Functions

static const char * set_scalar (SkString *storage, float value, SkScalarAsStringType asType)
 
template<typename R >
static bool subtract (const R &a, const R &b, R *out)
 

Macro Definition Documentation

◆ CHECK_INTERSECT

#define CHECK_INTERSECT (   al,
  at,
  ar,
  ab,
  bl,
  bt,
  br,
  bb 
)
Value:
float L = std::max(al, bl); \
float R = std::min(ar, br); \
float T = std::max(at, bt); \
float B = std::min(ab, bb); \
do { if (!(L < R && T < B)) return false; } while (0)
#define R(r)
Definition ab.py:1
#define T

Definition at line 106 of file SkRect.cpp.

111 { if (!(L < R && T < B)) return false; } while (0)

Function Documentation

◆ set_scalar()

static const char * set_scalar ( SkString storage,
float  value,
SkScalarAsStringType  asType 
)
static

Definition at line 146 of file SkRect.cpp.

146 {
147 storage->reset();
148 SkAppendScalar(storage, value, asType);
149 return storage->c_str();
150}
void SkAppendScalar(SkString *str, SkScalar value, SkScalarAsStringType asType)
void reset()
Definition SkString.cpp:358
const char * c_str() const
Definition SkString.h:133

◆ subtract()

template<typename R >
static bool subtract ( const R a,
const R b,
R out 
)
static

Definition at line 177 of file SkRect.cpp.

177 {
178 if (a.isEmpty() || b.isEmpty() || !R::Intersects(a, b)) {
179 // Either already empty, or subtracting the empty rect, or there's no intersection, so
180 // in all cases the answer is A.
181 *out = a;
182 return true;
183 }
184
185 // 4 rectangles to consider. If the edge in A is contained in B, the resulting difference can
186 // be represented exactly as a rectangle. Otherwise the difference is the largest subrectangle
187 // that is disjoint from B:
188 // 1. Left part of A: (A.left, A.top, B.left, A.bottom)
189 // 2. Right part of A: (B.right, A.top, A.right, A.bottom)
190 // 3. Top part of A: (A.left, A.top, A.right, B.top)
191 // 4. Bottom part of A: (A.left, B.bottom, A.right, A.bottom)
192 //
193 // Depending on how B intersects A, there will be 1 to 4 positive areas:
194 // - 4 occur when A contains B
195 // - 3 occur when B intersects a single edge
196 // - 2 occur when B intersects at a corner, or spans two opposing edges
197 // - 1 occurs when B spans two opposing edges and contains a 3rd, resulting in an exact rect
198 // - 0 occurs when B contains A, resulting in the empty rect
199 //
200 // Compute the relative areas of the 4 rects described above. Since each subrectangle shares
201 // either the width or height of A, we only have to divide by the other dimension, which avoids
202 // overflow on int32 types, and even if the float relative areas overflow to infinity, the
203 // comparisons work out correctly and (one of) the infinitely large subrects will be chosen.
204 float aHeight = (float) a.height();
205 float aWidth = (float) a.width();
206 float leftArea = 0.f, rightArea = 0.f, topArea = 0.f, bottomArea = 0.f;
207 int positiveCount = 0;
208 if (b.fLeft > a.fLeft) {
209 leftArea = (b.fLeft - a.fLeft) / aWidth;
210 positiveCount++;
211 }
212 if (a.fRight > b.fRight) {
213 rightArea = (a.fRight - b.fRight) / aWidth;
214 positiveCount++;
215 }
216 if (b.fTop > a.fTop) {
217 topArea = (b.fTop - a.fTop) / aHeight;
218 positiveCount++;
219 }
220 if (a.fBottom > b.fBottom) {
221 bottomArea = (a.fBottom - b.fBottom) / aHeight;
222 positiveCount++;
223 }
224
225 if (positiveCount == 0) {
226 SkASSERT(b.contains(a));
227 *out = R::MakeEmpty();
228 return true;
229 }
230
231 *out = a;
232 if (leftArea > rightArea && leftArea > topArea && leftArea > bottomArea) {
233 // Left chunk of A, so the new right edge is B's left edge
234 out->fRight = b.fLeft;
235 } else if (rightArea > topArea && rightArea > bottomArea) {
236 // Right chunk of A, so the new left edge is B's right edge
237 out->fLeft = b.fRight;
238 } else if (topArea > bottomArea) {
239 // Top chunk of A, so the new bottom edge is B's top edge
240 out->fBottom = b.fTop;
241 } else {
242 // Bottom chunk of A, so the new top edge is B's bottom edge
243 SkASSERT(bottomArea > 0.f);
244 out->fTop = b.fBottom;
245 }
246
247 // If we have 1 valid area, the disjoint shape is representable as a rectangle.
248 SkASSERT(!R::Intersects(*out, b));
249 return positiveCount == 1;
250}
#define SkASSERT(cond)
Definition SkAssert.h:116
static bool b
struct MyStruct a[10]