Chromium Code Reviews| 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 |
| */ |