19e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com/* 29e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * Copyright 2012 Google Inc. 39e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * 49e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be 59e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * found in the LICENSE file. 69e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com */ 7639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "DataTypes.h" 8639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 92e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com#include <sys/types.h> 102e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com#include <stdlib.h> 112e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com 12b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com#if USE_EPSILON 13639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comconst double PointEpsilon = 0.000001; 14639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comconst double SquaredEpsilon = PointEpsilon * PointEpsilon; 15b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com#endif 16b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 17b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.comconst int UlpsEpsilon = 16; 18639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 197ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com_Vector operator-(const _Point& a, const _Point& b) { 207ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com _Vector v = {a.x - b.x, a.y - b.y}; 217ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return v; 227ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com} 237ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 247ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com_Point operator+(const _Point& a, const _Vector& b) { 257ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com _Point v = {a.x + b.x, a.y + b.y}; 267ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return v; 277ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com} 287ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 292e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com// from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ 302e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.comunion Float_t 312e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com{ 322e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com Float_t(float num = 0.0f) : f(num) {} 332e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com // Portable extraction of components. 34f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com bool negative() const { return (i >> 31) != 0; } 35f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com#if 0 // unused 362e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com int32_t RawMantissa() const { return i & ((1 << 23) - 1); } 372e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com int32_t RawExponent() const { return (i >> 23) & 0xFF; } 38f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com#endif 392e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com int32_t i; 402e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com float f; 41f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com#if SK_DEBUG 422e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com struct 432e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com { // Bitfields for exploration. Do not use in production code. 442e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com uint32_t mantissa : 23; 452e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com uint32_t exponent : 8; 462e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com uint32_t sign : 1; 472e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com } parts; 482e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com#endif 492e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com}; 50d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 510b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.combool AlmostEqualUlps(float A, float B) 522e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com{ 532e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com Float_t uA(A); 542e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com Float_t uB(B); 55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 562e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com // Different signs means they do not match. 57f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com if (uA.negative() != uB.negative()) 582e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com { 592e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com // Check for equality to make sure +0==-0 602e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com return A == B; 612e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com } 62d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 632e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com // Find the difference in ULPs. 642e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com int ulpsDiff = abs(uA.i - uB.i); 650b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com return ulpsDiff <= UlpsEpsilon; 662e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com} 672e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com 680b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com// FIXME: obsolete, delete 690b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com#if 1 70d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comint UlpsDiff(float A, float B) 712e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com{ 722e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com Float_t uA(A); 732e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com Float_t uB(B); 742e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com 752e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com return abs(uA.i - uB.i); 762e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com} 770b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com#endif 785e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com 795e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com#if SK_DEBUG 805e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.comvoid mathematica_ize(char* str, size_t bufferLen) { 815e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com size_t len = strlen(str); 825e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com bool num = false; 835e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com for (size_t idx = 0; idx < len; ++idx) { 845e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com if (num && str[idx] == 'e') { 855e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com if (len + 2 >= bufferLen) { 865e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com return; 875e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com } 885e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com memmove(&str[idx + 2], &str[idx + 1], len - idx); 895e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com str[idx] = '*'; 905e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com str[idx + 1] = '^'; 915e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com ++len; 925e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com } 935e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com num = str[idx] >= '0' && str[idx] <= '9'; 945e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com } 955e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com} 96c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com 97c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.combool valid_wind(int wind) { 98c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; 99c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com} 100c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com 101c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.comvoid winding_printf(int wind) { 102c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com if (wind == SK_MinS32) { 103c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com SkDebugf("?"); 104c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com } else { 105c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com SkDebugf("%d", wind); 106c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com } 107c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com} 1085e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com#endif 109