Index: include/private/SkFixed.h |
diff --git a/include/private/SkFixed.h b/include/private/SkFixed.h |
index 56821d4d8268989045dbb98fce1db0557bf21468..c90d5e9ffd093e98a7335fd210be962a2436ac3e 100644 |
--- a/include/private/SkFixed.h |
+++ b/include/private/SkFixed.h |
@@ -9,6 +9,8 @@ |
#define SkFixed_DEFINED |
#include "SkScalar.h" |
+#include "math.h" |
+ |
#include "SkTypes.h" |
/** \file SkFixed.h |
@@ -29,15 +31,18 @@ typedef int32_t SkFixed; |
#define SK_FixedRoot2Over2 (0xB505) |
#define SkFixedToFloat(x) ((x) * 1.52587890625e-5f) |
-#if 1 |
- #define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1)) |
-#else |
- // pins over/under flows to max/min int32 (slower than just a cast) |
- static inline SkFixed SkFloatToFixed(float x) { |
- int64_t n = x * SK_Fixed1; |
- return (SkFixed)n; |
- } |
-#endif |
+#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1)) |
+ |
+// Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). |
+static inline SkFixed SkFloatPinToFixed(float x) { |
+ x *= SK_Fixed1; |
+ // Casting float to int outside the range of the target type (int32_t) is undefined behavior. |
+ if (x >= SK_FixedMax) return SK_FixedMax; |
+ if (x <= SK_FixedMin) return SK_FixedMin; |
+ const SkFixed result = static_cast<SkFixed>(x); |
+ SkASSERT(truncf(x) == static_cast<float>(result)); |
+ return result; |
+} |
#ifdef SK_DEBUG |
static inline SkFixed SkFloatToFixed_Check(float x) { |
@@ -53,6 +58,17 @@ typedef int32_t SkFixed; |
#define SkFixedToDouble(x) ((x) * 1.52587890625e-5) |
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) |
+// Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). |
+static inline SkFixed SkDoublePinToFixed(double x) { |
+ x *= SK_Fixed1; |
+ // Casting double to int outside the range of the target type (int32_t) is undefined behavior. |
+ if (x >= SK_FixedMax) return SK_FixedMax; |
+ if (x <= SK_FixedMin) return SK_FixedMin; |
+ const SkFixed result = static_cast<SkFixed>(x); |
+ SkASSERT(trunc(x) == static_cast<double>(result)); |
+ return result; |
+} |
+ |
/** Converts an integer to a SkFixed, asserting that the result does not overflow |
a 32 bit signed integer |
*/ |
@@ -147,11 +163,13 @@ inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) { |
#define SkFixedToScalar(x) SkFixedToFloat(x) |
#define SkScalarToFixed(x) SkFloatToFixed(x) |
+#define SkScalarPinToFixed(x) SkFloatPinToFixed(x) |
#else // SK_SCALAR_IS_DOUBLE |
#define SkFixedToScalar(x) SkFixedToDouble(x) |
#define SkScalarToFixed(x) SkDoubleToFixed(x) |
+#define SkScalarPinToFixed(x) SkDoublePinToFixed(x) |
#endif |