| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #ifndef Sk64_DEFINED | 10 #ifndef Sk64_DEFINED |
| 11 #define Sk64_DEFINED | 11 #define Sk64_DEFINED |
| 12 | 12 |
| 13 #include "SkFixed.h" | 13 #include "SkTypes.h" |
| 14 | 14 |
| 15 /** \class Sk64 | 15 /** \class Sk64 |
| 16 | 16 |
| 17 Sk64 is a 64-bit math package that does not require long long support from t
he compiler. | 17 Sk64 is a 64-bit math package that does not require long long support from t
he compiler. |
| 18 */ | 18 */ |
| 19 struct SK_API Sk64 { | 19 struct SK_API Sk64 { |
| 20 int32_t fHi; //!< the high 32 bits of the number (including sign) | 20 int32_t fHi; //!< the high 32 bits of the number (including sign) |
| 21 uint32_t fLo; //!< the low 32 bits of the number | 21 uint32_t fLo; //!< the low 32 bits of the number |
| 22 | 22 |
| 23 /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integ
er | 23 /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integ
er |
| 24 */ | 24 */ |
| 25 SkBool is32() const { return fHi == ((int32_t)fLo >> 31); } | 25 SkBool is32() const { return fHi == ((int32_t)fLo >> 31); } |
| 26 | 26 |
| 27 /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit in
teger | 27 /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit in
teger |
| 28 */ | 28 */ |
| 29 SkBool is64() const { return fHi != ((int32_t)fLo >> 31); } | 29 SkBool is64() const { return fHi != ((int32_t)fLo >> 31); } |
| 30 | 30 |
| 31 /** Returns non-zero if the Sk64 can be represented as a signed 48 bit integ
er. Used to know | |
| 32 if we can shift the value down by 16 to treat it as a SkFixed. | |
| 33 */ | |
| 34 SkBool isFixed() const; | |
| 35 | |
| 36 /** Return the signed 32 bit integer equivalent. Asserts that is32() returns
non-zero. | 31 /** Return the signed 32 bit integer equivalent. Asserts that is32() returns
non-zero. |
| 37 */ | 32 */ |
| 38 int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; } | 33 int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; } |
| 39 | 34 |
| 40 /** Return the number >> 16. Asserts that this does not loose any significan
t high bits. | |
| 41 */ | |
| 42 SkFixed getFixed() const { | |
| 43 SkASSERT(this->isFixed()); | |
| 44 | |
| 45 uint32_t sum = fLo + (1 << 15); | |
| 46 int32_t hi = fHi; | |
| 47 if (sum < fLo) { | |
| 48 hi += 1; | |
| 49 } | |
| 50 return (hi << 16) | (sum >> 16); | |
| 51 } | |
| 52 | |
| 53 /** Return the number >> 30. Asserts that this does not loose any | |
| 54 significant high bits. | |
| 55 */ | |
| 56 SkFract getFract() const; | |
| 57 | |
| 58 /** Returns the square-root of the number as a signed 32 bit value. */ | 35 /** Returns the square-root of the number as a signed 32 bit value. */ |
| 59 int32_t getSqrt() const; | 36 int32_t getSqrt() const; |
| 60 | 37 |
| 61 /** Returns the number of leading zeros of the absolute value of this. | 38 /** Returns the number of leading zeros of the absolute value of this. |
| 62 Will return in the range [0..64] | 39 Will return in the range [0..64] |
| 63 */ | 40 */ |
| 64 int getClzAbs() const; | 41 int getClzAbs() const; |
| 65 | 42 |
| 66 /** Returns non-zero if the number is zero */ | 43 /** Returns non-zero if the number is zero */ |
| 67 SkBool isZero() const { return (fHi | fLo) == 0; } | 44 SkBool isZero() const { return (fHi | fLo) == 0; } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 enum DivOptions { | 138 enum DivOptions { |
| 162 kTrunc_DivOption, //!< truncate the result when calling div() | 139 kTrunc_DivOption, //!< truncate the result when calling div() |
| 163 kRound_DivOption //!< round the result when calling div() | 140 kRound_DivOption //!< round the result when calling div() |
| 164 }; | 141 }; |
| 165 | 142 |
| 166 /** Divide the number by the specified 32 bit integer, using the specified | 143 /** Divide the number by the specified 32 bit integer, using the specified |
| 167 divide option (either truncate or round). | 144 divide option (either truncate or round). |
| 168 */ | 145 */ |
| 169 void div(int32_t, DivOptions); | 146 void div(int32_t, DivOptions); |
| 170 | 147 |
| 171 /** return (this + other >> 16) as a 32bit result */ | |
| 172 SkFixed addGetFixed(const Sk64& other) const { | |
| 173 return this->addGetFixed(other.fHi, other.fLo); | |
| 174 } | |
| 175 | |
| 176 /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */ | |
| 177 SkFixed addGetFixed(int32_t hi, uint32_t lo) const { | |
| 178 #ifdef SK_DEBUG | |
| 179 Sk64 tmp(*this); | |
| 180 tmp.add(hi, lo); | |
| 181 #endif | |
| 182 | |
| 183 uint32_t sum = fLo + lo; | |
| 184 hi += fHi + (sum < fLo); | |
| 185 lo = sum; | |
| 186 | |
| 187 sum = lo + (1 << 15); | |
| 188 if (sum < lo) | |
| 189 hi += 1; | |
| 190 | |
| 191 hi = (hi << 16) | (sum >> 16); | |
| 192 SkASSERT(hi == tmp.getFixed()); | |
| 193 return hi; | |
| 194 } | |
| 195 | |
| 196 /** Return the result of dividing the number by denom, treating the answer | |
| 197 as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0. | |
| 198 */ | |
| 199 SkFixed getFixedDiv(const Sk64& denom) const; | |
| 200 | |
| 201 friend bool operator==(const Sk64& a, const Sk64& b) { | 148 friend bool operator==(const Sk64& a, const Sk64& b) { |
| 202 return a.fHi == b.fHi && a.fLo == b.fLo; | 149 return a.fHi == b.fHi && a.fLo == b.fLo; |
| 203 } | 150 } |
| 204 | 151 |
| 205 friend bool operator!=(const Sk64& a, const Sk64& b) { | 152 friend bool operator!=(const Sk64& a, const Sk64& b) { |
| 206 return a.fHi != b.fHi || a.fLo != b.fLo; | 153 return a.fHi != b.fHi || a.fLo != b.fLo; |
| 207 } | 154 } |
| 208 | 155 |
| 209 friend bool operator<(const Sk64& a, const Sk64& b) { | 156 friend bool operator<(const Sk64& a, const Sk64& b) { |
| 210 return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo); | 157 return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 221 friend bool operator>=(const Sk64& a, const Sk64& b) { | 168 friend bool operator>=(const Sk64& a, const Sk64& b) { |
| 222 return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo); | 169 return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo); |
| 223 } | 170 } |
| 224 | 171 |
| 225 #ifdef SkLONGLONG | 172 #ifdef SkLONGLONG |
| 226 SkLONGLONG getLongLong() const; | 173 SkLONGLONG getLongLong() const; |
| 227 #endif | 174 #endif |
| 228 }; | 175 }; |
| 229 | 176 |
| 230 #endif | 177 #endif |
| OLD | NEW |