1/* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7#include "DataTypes.h" 8 9#include <sys/types.h> 10#include <stdlib.h> 11 12#if USE_EPSILON 13const double PointEpsilon = 0.000001; 14const double SquaredEpsilon = PointEpsilon * PointEpsilon; 15#endif 16 17const int UlpsEpsilon = 16; 18 19_Vector operator-(const _Point& a, const _Point& b) { 20 _Vector v = {a.x - b.x, a.y - b.y}; 21 return v; 22} 23 24_Point operator+(const _Point& a, const _Vector& b) { 25 _Point v = {a.x + b.x, a.y + b.y}; 26 return v; 27} 28 29// from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ 30union Float_t 31{ 32 Float_t(float num = 0.0f) : f(num) {} 33 // Portable extraction of components. 34 bool negative() const { return (i >> 31) != 0; } 35#if 0 // unused 36 int32_t RawMantissa() const { return i & ((1 << 23) - 1); } 37 int32_t RawExponent() const { return (i >> 23) & 0xFF; } 38#endif 39 int32_t i; 40 float f; 41#ifdef SK_DEBUG 42 struct 43 { // Bitfields for exploration. Do not use in production code. 44 uint32_t mantissa : 23; 45 uint32_t exponent : 8; 46 uint32_t sign : 1; 47 } parts; 48#endif 49}; 50 51bool AlmostEqualUlps(float A, float B) 52{ 53 Float_t uA(A); 54 Float_t uB(B); 55 56 // Different signs means they do not match. 57 if (uA.negative() != uB.negative()) 58 { 59 // Check for equality to make sure +0==-0 60 return A == B; 61 } 62 63 // Find the difference in ULPs. 64 int ulpsDiff = abs(uA.i - uB.i); 65 return ulpsDiff <= UlpsEpsilon; 66} 67 68// FIXME: obsolete, delete 69#if 1 70int UlpsDiff(float A, float B) 71{ 72 Float_t uA(A); 73 Float_t uB(B); 74 75 return abs(uA.i - uB.i); 76} 77#endif 78 79#ifdef SK_DEBUG 80void mathematica_ize(char* str, size_t bufferLen) { 81 size_t len = strlen(str); 82 bool num = false; 83 for (size_t idx = 0; idx < len; ++idx) { 84 if (num && str[idx] == 'e') { 85 if (len + 2 >= bufferLen) { 86 return; 87 } 88 memmove(&str[idx + 2], &str[idx + 1], len - idx); 89 str[idx] = '*'; 90 str[idx + 1] = '^'; 91 ++len; 92 } 93 num = str[idx] >= '0' && str[idx] <= '9'; 94 } 95} 96 97bool valid_wind(int wind) { 98 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; 99} 100 101void winding_printf(int wind) { 102 if (wind == SK_MinS32) { 103 SkDebugf("?"); 104 } else { 105 SkDebugf("%d", wind); 106 } 107} 108#endif 109