1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkFloatBits.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,133 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2008 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkFloatBits_DEFINED 1.14 +#define SkFloatBits_DEFINED 1.15 + 1.16 +#include "SkTypes.h" 1.17 + 1.18 +/** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement 1.19 + int. This also converts -0 (0x80000000) to 0. Doing this to a float allows 1.20 + it to be compared using normal C operators (<, <=, etc.) 1.21 +*/ 1.22 +static inline int32_t SkSignBitTo2sCompliment(int32_t x) { 1.23 + if (x < 0) { 1.24 + x &= 0x7FFFFFFF; 1.25 + x = -x; 1.26 + } 1.27 + return x; 1.28 +} 1.29 + 1.30 +/** Convert a 2s compliment int to a sign-bit (i.e. int interpreted as float). 1.31 + This undoes the result of SkSignBitTo2sCompliment(). 1.32 + */ 1.33 +static inline int32_t Sk2sComplimentToSignBit(int32_t x) { 1.34 + int sign = x >> 31; 1.35 + // make x positive 1.36 + x = (x ^ sign) - sign; 1.37 + // set the sign bit as needed 1.38 + x |= sign << 31; 1.39 + return x; 1.40 +} 1.41 + 1.42 +/** Given the bit representation of a float, return its value cast to an int. 1.43 + If the value is out of range, or NaN, return return +/- SK_MaxS32 1.44 +*/ 1.45 +int32_t SkFloatBits_toIntCast(int32_t floatBits); 1.46 + 1.47 +/** Given the bit representation of a float, return its floor as an int. 1.48 + If the value is out of range, or NaN, return return +/- SK_MaxS32 1.49 + */ 1.50 +SK_API int32_t SkFloatBits_toIntFloor(int32_t floatBits); 1.51 + 1.52 +/** Given the bit representation of a float, return it rounded to an int. 1.53 + If the value is out of range, or NaN, return return +/- SK_MaxS32 1.54 + */ 1.55 +SK_API int32_t SkFloatBits_toIntRound(int32_t floatBits); 1.56 + 1.57 +/** Given the bit representation of a float, return its ceiling as an int. 1.58 + If the value is out of range, or NaN, return return +/- SK_MaxS32 1.59 + */ 1.60 +SK_API int32_t SkFloatBits_toIntCeil(int32_t floatBits); 1.61 + 1.62 + 1.63 +union SkFloatIntUnion { 1.64 + float fFloat; 1.65 + int32_t fSignBitInt; 1.66 +}; 1.67 + 1.68 +// Helper to see a float as its bit pattern (w/o aliasing warnings) 1.69 +static inline int32_t SkFloat2Bits(float x) { 1.70 + SkFloatIntUnion data; 1.71 + data.fFloat = x; 1.72 + return data.fSignBitInt; 1.73 +} 1.74 + 1.75 +// Helper to see a bit pattern as a float (w/o aliasing warnings) 1.76 +static inline float SkBits2Float(int32_t floatAsBits) { 1.77 + SkFloatIntUnion data; 1.78 + data.fSignBitInt = floatAsBits; 1.79 + return data.fFloat; 1.80 +} 1.81 + 1.82 +/** Return the float as a 2s compliment int. Just to be used to compare floats 1.83 + to each other or against positive float-bit-constants (like 0). This does 1.84 + not return the int equivalent of the float, just something cheaper for 1.85 + compares-only. 1.86 + */ 1.87 +static inline int32_t SkFloatAs2sCompliment(float x) { 1.88 + return SkSignBitTo2sCompliment(SkFloat2Bits(x)); 1.89 +} 1.90 + 1.91 +/** Return the 2s compliment int as a float. This undos the result of 1.92 + SkFloatAs2sCompliment 1.93 + */ 1.94 +static inline float Sk2sComplimentAsFloat(int32_t x) { 1.95 + return SkBits2Float(Sk2sComplimentToSignBit(x)); 1.96 +} 1.97 + 1.98 +/** Return x cast to a float (i.e. (float)x) 1.99 +*/ 1.100 +float SkIntToFloatCast(int x); 1.101 +float SkIntToFloatCast_NoOverflowCheck(int x); 1.102 + 1.103 +/** Return the float cast to an int. 1.104 + If the value is out of range, or NaN, return +/- SK_MaxS32 1.105 +*/ 1.106 +static inline int32_t SkFloatToIntCast(float x) { 1.107 + return SkFloatBits_toIntCast(SkFloat2Bits(x)); 1.108 +} 1.109 + 1.110 +/** Return the floor of the float as an int. 1.111 + If the value is out of range, or NaN, return +/- SK_MaxS32 1.112 +*/ 1.113 +static inline int32_t SkFloatToIntFloor(float x) { 1.114 + return SkFloatBits_toIntFloor(SkFloat2Bits(x)); 1.115 +} 1.116 + 1.117 +/** Return the float rounded to an int. 1.118 + If the value is out of range, or NaN, return +/- SK_MaxS32 1.119 +*/ 1.120 +static inline int32_t SkFloatToIntRound(float x) { 1.121 + return SkFloatBits_toIntRound(SkFloat2Bits(x)); 1.122 +} 1.123 + 1.124 +/** Return the ceiling of the float as an int. 1.125 + If the value is out of range, or NaN, return +/- SK_MaxS32 1.126 +*/ 1.127 +static inline int32_t SkFloatToIntCeil(float x) { 1.128 + return SkFloatBits_toIntCeil(SkFloat2Bits(x)); 1.129 +} 1.130 + 1.131 +// Scalar wrappers for float-bit routines 1.132 + 1.133 +#define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x) 1.134 +#define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x) 1.135 + 1.136 +#endif