Index: include/core/SkFixed.h |
diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h |
index 1541e32105ff55cb995cfcbce4a3d2cf1ba5127c..a65347297494935459194d72899e5d6582f92841 100644 |
--- a/include/core/SkFixed.h |
+++ b/include/core/SkFixed.h |
@@ -28,15 +28,26 @@ 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)) |
+ |
+// Maximum input value for SkFloatToFixed. (-SK_FloatToFixedMax is the minimum.) |
+// SkFixed has more precision than float near SK_FixedMax/SK_FixedMin. Values higher than |
mtklein
2016/03/11 15:01:29
Let's write "near SK_FixedMax and SK_FixedMin". B
dogben
2016/03/11 16:33:19
Removed.
|
+// SK_FloatToFixedMax will overflow SkFixed. |
+// This must be a macro because MSVC doesn't like constexpr float. |
+#define SK_FloatToFixedMax SkFixedToFloat(SK_FixedMax - 0x7f) |
mtklein
2016/03/11 15:01:29
Walk me through this math / logic? I'm curious if
dogben
2016/03/11 16:33:19
Done, except it feels wrong to return values less
|
+ |
+// Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). |
+static inline SkFixed SkFloatPinToFixed(float x) { |
+ static_assert(SkFixedToFloat(SkFloatToFixed(SK_FloatToFixedMax)) == SK_FloatToFixedMax, |
+ "SK_FloatToFixedMax is not the real max."); |
+ static_assert(SkFixedToFloat(SkFloatToFixed(-SK_FloatToFixedMax)) == -SK_FloatToFixedMax, |
+ "-SK_FloatToFixedMax is not the real min."); |
+ // Unlike SkDoublePinToFixed, we don't use SkTPin, because that would |
+ // produce SkFloatToFixed(SK_FloatToFixedMax), which is less than SK_FixedMax. |
+ if (x > SK_FloatToFixedMax) return SK_FixedMax; |
+ if (x < -SK_FloatToFixedMax) return SK_FixedMin; |
+ return SkFloatToFixed(x); |
+} |
#ifdef SK_DEBUG |
static inline SkFixed SkFloatToFixed_Check(float x) { |
@@ -52,6 +63,19 @@ typedef int32_t SkFixed; |
#define SkFixedToDouble(x) ((x) * 1.52587890625e-5) |
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) |
+// Maximum input value for SkDoubleToFixed. (-SK_DoubleToFixedMax is the minimum.) |
+// This must be a macro because MSVC doesn't like constexpr float. |
+#define SK_DoubleToFixedMax SkFixedToDouble(SK_FixedMax) |
+ |
+// Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). |
+static inline SkFixed SkDoublePinToFixed(double x) { |
+ static_assert(SkFixedToDouble(SkDoubleToFixed(SK_DoubleToFixedMax)) == SK_DoubleToFixedMax, |
+ "SK_DoubleToFixedMax is not the real max."); |
+ static_assert(SkFixedToDouble(SkDoubleToFixed(-SK_DoubleToFixedMax)) == -SK_DoubleToFixedMax, |
+ "-SK_DoubleToFixedMax is not the real min."); |
+ return static_cast<SkFixed>(SkTPin(x, -SK_DoubleToFixedMax, SK_DoubleToFixedMax) * SK_Fixed1); |
+} |
+ |
/** Converts an integer to a SkFixed, asserting that the result does not overflow |
a 32 bit signed integer |
*/ |