Gnash
0.8.10
|
00001 // GnashNumeric.h: vaguely useful mathematical functions. 00002 // 00003 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 00004 // Free Software Foundation, Inc 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 // 00020 00021 #ifndef GNASH_NUMERIC_H 00022 #define GNASH_NUMERIC_H 00023 00024 #ifdef HAVE_CONFIG_H 00025 # include "gnashconfig.h" 00026 #endif 00027 00028 #ifdef SOLARIS_HOST 00029 # include <ieeefp.h> // for finite() 00030 #endif 00031 00032 #include <cassert> 00033 #include <cmath> 00034 #include <algorithm> 00035 #include <boost/cstdint.hpp> 00036 #include <limits> 00037 #include <boost/utility/enable_if.hpp> 00038 00039 namespace gnash { 00040 00041 // Using a possible built-in pi constant M_PI, which is not in 00042 // the C++ standard, has no greate advantage, so we will use this 00043 // one. Make it as accurate as you like. 00044 static const double PI = 3.14159265358979323846; 00045 00046 inline bool 00047 isFinite(double d) 00048 { 00049 #if defined(HAVE_FINITE) && !defined(HAVE_ISFINITE) 00050 return (finite(d)); 00051 #else 00052 // Put using namespace std; here if you have to 00053 // put it anywhere. 00054 using namespace std; 00055 return (isfinite(d)); 00056 #endif 00057 } 00058 00059 inline double 00060 infinite_to_zero(double x) 00061 { 00062 return isFinite(x) ? x : 0.0; 00063 } 00064 00065 template <typename T> 00066 inline T 00067 clamp(T i, T min, T max) 00068 { 00069 assert(min <= max); 00070 return std::max<T>(min, std::min<T>(i, max)); 00071 } 00072 00073 template<typename T> 00074 inline T 00075 lerp(T a, T b, T f) 00076 { 00077 return (b - a) * f + a; 00078 } 00079 00080 inline int 00081 frnd(float f) 00082 { 00083 return static_cast<int>(f + 0.5f); 00084 } 00085 00086 inline double 00087 twipsToPixels(int i) 00088 { 00089 return static_cast<double>(i / 20.0); 00090 } 00091 00092 template<size_t Factor> 00093 boost::int32_t 00094 truncateWithFactor(double a) 00095 { 00096 00097 const double factor = static_cast<double>(Factor); 00098 00099 // This truncates large values without relying on undefined behaviour. 00100 // For very large values of 'a' it is noticeably slower than the UB 00101 // version (due to fmod), but should always be legal behaviour. For 00102 // ordinary values (within ±1.07374e+08 pixels) it is comparable to 00103 // the UB version for speed. Because values outside the limit are 00104 // extremely rare, using this safe version has no implications for 00105 // performance under normal circumstances. 00106 static const double upperUnsignedLimit = 00107 std::numeric_limits<boost::uint32_t>::max() + 1.0; 00108 static const double upperSignedLimit = 00109 std::numeric_limits<boost::int32_t>::max() / factor; 00110 static const double lowerSignedLimit = 00111 std::numeric_limits<boost::int32_t>::min() / factor; 00112 00113 if (a >= lowerSignedLimit && a <= upperSignedLimit) { 00114 return a * Factor; 00115 } 00116 00117 // This slow truncation happens only in very unlikely cases. 00118 return a >= 0 ? 00119 static_cast<boost::uint32_t>( 00120 std::fmod(a * factor, upperUnsignedLimit)) 00121 : 00122 -static_cast<boost::uint32_t>( 00123 std::fmod(-a * factor, upperUnsignedLimit)); 00124 } 00125 00126 // truncate when overflow occurs. 00127 inline boost::int32_t 00128 pixelsToTwips(double a) 00129 { 00130 return truncateWithFactor<20>(a); 00131 } 00132 00133 } // namespace gnash 00134 00135 #endif