зеркало из https://github.com/mozilla/moz-skia.git
add SkScalarIsFinite(), and use it for a more portable impl of SkRect::isValidCoords()
git-svn-id: http://skia.googlecode.com/svn/trunk@775 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
4854327772
Коммит
077910e20c
|
@ -60,6 +60,12 @@
|
|||
/** SkScalarIsNaN(n) returns true if argument is not a number
|
||||
*/
|
||||
static inline bool SkScalarIsNaN(float x) { return x != x; }
|
||||
/** Returns true if x is not NaN and not infinite */
|
||||
static inline bool SkScalarIsFinite(float x) {
|
||||
uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
|
||||
int exponent = bits << 1 >> 24;
|
||||
return exponent != 0xFF;
|
||||
}
|
||||
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
||||
*/
|
||||
#define SkIntToScalar(n) ((float)(n))
|
||||
|
@ -177,6 +183,8 @@
|
|||
#define SK_ScalarMin SK_FixedMin
|
||||
#define SK_ScalarNaN SK_FixedNaN
|
||||
#define SkScalarIsNaN(x) ((x) == SK_FixedNaN)
|
||||
#define SkScalarIsFinite(x) ((x) != SK_FixedNaN)
|
||||
|
||||
#define SkIntToScalar(n) SkIntToFixed(n)
|
||||
#define SkFixedToScalar(x) (x)
|
||||
#define SkScalarToFixed(x) (x)
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "SkRect.h"
|
||||
#include <limits>
|
||||
|
||||
void SkIRect::join(int32_t left, int32_t top, int32_t right, int32_t bottom)
|
||||
{
|
||||
|
@ -45,17 +44,11 @@ void SkIRect::sort()
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename NumType> static inline bool isValidRange(const NumType& x)
|
||||
{
|
||||
static const NumType max = std::numeric_limits<NumType>::max();
|
||||
return x >= -max && x <= max;
|
||||
}
|
||||
|
||||
|
||||
bool SkRect::hasValidCoordinates() const
|
||||
{
|
||||
return isValidRange<SkScalar>(fLeft) && isValidRange<SkScalar>(fRight) &&
|
||||
isValidRange<SkScalar>(fTop) && isValidRange<SkScalar>(fBottom);
|
||||
bool SkRect::hasValidCoordinates() const {
|
||||
return SkScalarIsFinite(fLeft) &&
|
||||
SkScalarIsFinite(fTop) &&
|
||||
SkScalarIsFinite(fRight) &&
|
||||
SkScalarIsFinite(fBottom);
|
||||
}
|
||||
|
||||
void SkRect::sort()
|
||||
|
@ -85,14 +78,14 @@ void SkRect::set(const SkPoint pts[], int count)
|
|||
} else {
|
||||
#ifdef SK_SCALAR_SLOW_COMPARES
|
||||
int32_t l, t, r, b;
|
||||
|
||||
|
||||
l = r = SkScalarAs2sCompliment(pts[0].fX);
|
||||
t = b = SkScalarAs2sCompliment(pts[0].fY);
|
||||
|
||||
|
||||
for (int i = 1; i < count; i++) {
|
||||
int32_t x = SkScalarAs2sCompliment(pts[i].fX);
|
||||
int32_t y = SkScalarAs2sCompliment(pts[i].fY);
|
||||
|
||||
|
||||
if (x < l) l = x; else if (x > r) r = x;
|
||||
if (y < t) t = y; else if (y > b) b = y;
|
||||
}
|
||||
|
@ -143,7 +136,7 @@ void SkRect::join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
|
|||
// do nothing if the params are empty
|
||||
if (left >= right || top >= bottom)
|
||||
return;
|
||||
|
||||
|
||||
// if we are empty, just assign
|
||||
if (fLeft >= fRight || fTop >= fBottom)
|
||||
this->set(left, top, right, bottom);
|
||||
|
|
|
@ -146,6 +146,40 @@ static void unittest_fastfloat(skiatest::Reporter* reporter) {
|
|||
}
|
||||
}
|
||||
|
||||
static float make_zero() {
|
||||
return sk_float_sin(0);
|
||||
}
|
||||
|
||||
static void unittest_isfinite(skiatest::Reporter* reporter) {
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
float nan = ::asin(2);
|
||||
float inf = 1.0 / make_zero();
|
||||
float big = 3.40282e+038;
|
||||
|
||||
REPORTER_ASSERT(reporter, SkScalarIsNaN(nan));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
|
||||
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
|
||||
REPORTER_ASSERT(reporter, SkScalarIsFinite(big));
|
||||
REPORTER_ASSERT(reporter, SkScalarIsFinite(-big));
|
||||
REPORTER_ASSERT(reporter, SkScalarIsFinite(0));
|
||||
#else
|
||||
REPORTER_ASSERT(reporter, SkScalarIsNaN(0x80000000));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(0x7FFFFFFF));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(0x80000001));
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
|
||||
|
||||
REPORTER_ASSERT(reporter, !SkScalarIsFinite(0x80000000));
|
||||
REPORTER_ASSERT(reporter, SkScalarIsFinite(0x7FFFFFFF));
|
||||
REPORTER_ASSERT(reporter, SkScalarIsFinite(0x80000001));
|
||||
REPORTER_ASSERT(reporter, SkScalarIsFinite(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void test_muldiv255(skiatest::Reporter* reporter) {
|
||||
|
@ -309,6 +343,7 @@ static void TestMath(skiatest::Reporter* reporter) {
|
|||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
unittest_fastfloat(reporter);
|
||||
unittest_isfinite(reporter);
|
||||
#endif
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
|
|
Загрузка…
Ссылка в новой задаче