2018-01-03 20:35:33 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2018 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SkRectPriv_DEFINED
|
|
|
|
#define SkRectPriv_DEFINED
|
|
|
|
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "include/core/SkRect.h"
|
|
|
|
#include "src/core/SkMathPriv.h"
|
2018-01-03 20:35:33 +00:00
|
|
|
|
|
|
|
class SkRectPriv {
|
|
|
|
public:
|
2018-01-17 17:20:04 +00:00
|
|
|
// Returns an irect that is very large, and can be safely round-trip with SkRect and still
|
|
|
|
// be considered non-empty (i.e. width/height > 0) even if we round-out the SkRect.
|
|
|
|
static SkIRect MakeILarge() {
|
|
|
|
// SK_MaxS32 >> 1 seemed better, but it did not survive round-trip with SkRect and rounding.
|
|
|
|
// Also, 1 << 29 can be perfectly represented in float, while SK_MaxS32 >> 1 cannot.
|
|
|
|
const int32_t large = 1 << 29;
|
|
|
|
return { -large, -large, large, large };
|
2018-01-09 20:36:51 +00:00
|
|
|
}
|
2018-01-08 20:05:02 +00:00
|
|
|
|
2018-01-09 20:36:51 +00:00
|
|
|
static SkIRect MakeILargestInverted() {
|
|
|
|
return { SK_MaxS32, SK_MaxS32, SK_MinS32, SK_MinS32 };
|
2018-01-08 20:05:02 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 17:20:04 +00:00
|
|
|
static SkRect MakeLargeS32() {
|
2018-01-09 20:36:51 +00:00
|
|
|
SkRect r;
|
2018-01-17 17:20:04 +00:00
|
|
|
r.set(MakeILarge());
|
2018-01-09 20:36:51 +00:00
|
|
|
return r;
|
2018-01-08 20:05:02 +00:00
|
|
|
}
|
|
|
|
|
2018-01-09 20:36:51 +00:00
|
|
|
static SkRect MakeLargest() {
|
|
|
|
return { SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax };
|
2018-01-08 20:05:02 +00:00
|
|
|
}
|
|
|
|
|
2018-11-12 20:45:49 +00:00
|
|
|
static constexpr SkRect MakeLargestInverted() {
|
2018-01-08 20:05:02 +00:00
|
|
|
return { SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin };
|
|
|
|
}
|
|
|
|
|
2018-01-08 22:09:54 +00:00
|
|
|
static void GrowToInclude(SkRect* r, const SkPoint& pt) {
|
2020-02-05 18:34:09 +00:00
|
|
|
r->fLeft = std::min(pt.fX, r->fLeft);
|
|
|
|
r->fRight = std::max(pt.fX, r->fRight);
|
|
|
|
r->fTop = std::min(pt.fY, r->fTop);
|
|
|
|
r->fBottom = std::max(pt.fY, r->fBottom);
|
2018-01-08 22:09:54 +00:00
|
|
|
}
|
2018-01-18 18:46:21 +00:00
|
|
|
|
2018-02-26 22:00:58 +00:00
|
|
|
// Conservative check if r can be expressed in fixed-point.
|
|
|
|
// Will return false for very large values that might have fit
|
2018-01-18 18:46:21 +00:00
|
|
|
static bool FitsInFixed(const SkRect& r) {
|
|
|
|
return SkFitsInFixed(r.fLeft) && SkFitsInFixed(r.fTop) &&
|
|
|
|
SkFitsInFixed(r.fRight) && SkFitsInFixed(r.fBottom);
|
|
|
|
}
|
2018-04-11 18:30:17 +00:00
|
|
|
|
|
|
|
static bool Is16Bit(const SkIRect& r) {
|
|
|
|
return SkTFitsIn<int16_t>(r.fLeft) && SkTFitsIn<int16_t>(r.fTop) &&
|
|
|
|
SkTFitsIn<int16_t>(r.fRight) && SkTFitsIn<int16_t>(r.fBottom);
|
|
|
|
}
|
2020-04-15 19:26:05 +00:00
|
|
|
|
|
|
|
// Evaluate A-B. If the difference shape cannot be represented as a rectangle then false is
|
|
|
|
// returned and 'out' is set to the largest rectangle contained in said shape. If true is
|
|
|
|
// returned then A-B is representable as a rectangle, which is stored in 'out'.
|
|
|
|
static bool Subtract(const SkRect& a, const SkRect& b, SkRect* out);
|
|
|
|
static bool Subtract(const SkIRect& a, const SkIRect& b, SkIRect* out);
|
|
|
|
|
|
|
|
// Evaluate A-B, and return the largest rectangle contained in that shape (since the difference
|
|
|
|
// may not be representable as rectangle). The returned rectangle will not intersect B.
|
|
|
|
static SkRect Subtract(const SkRect& a, const SkRect& b) {
|
|
|
|
SkRect diff;
|
|
|
|
Subtract(a, b, &diff);
|
|
|
|
return diff;
|
|
|
|
}
|
|
|
|
static SkIRect Subtract(const SkIRect& a, const SkIRect& b) {
|
|
|
|
SkIRect diff;
|
|
|
|
Subtract(a, b, &diff);
|
|
|
|
return diff;
|
|
|
|
}
|
2018-01-03 20:35:33 +00:00
|
|
|
};
|
|
|
|
|
2018-01-08 20:05:02 +00:00
|
|
|
|
2018-01-03 20:35:33 +00:00
|
|
|
#endif
|