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 |