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