SkScalar.h revision 95dd17737d0fa0401782f7fa72e5d69bb5686f67
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkScalar_DEFINED
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkScalar_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFixed.h"
1295dd17737d0fa0401782f7fa72e5d69bb5686f67reed#include "../private/SkFloatingPoint.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14bd1605905b1ce165e6b5891547c2b612358b47a8reed// TODO: move this sort of check into SkPostConfig.h
15bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_SCALAR_IS_DOUBLE 0
16bd1605905b1ce165e6b5891547c2b612358b47a8reed#undef SK_SCALAR_IS_FLOAT
17bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_SCALAR_IS_FLOAT  1
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20bd1605905b1ce165e6b5891547c2b612358b47a8reed#if SK_SCALAR_IS_FLOAT
211b20280f9b2e95fdcf4a2ee6f7f9d5a92c5b94c2reed@google.com
22bd1605905b1ce165e6b5891547c2b612358b47a8reedtypedef float SkScalar;
23bd1605905b1ce165e6b5891547c2b612358b47a8reed
24bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_Scalar1                  1.0f
25bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarHalf               0.5f
26bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarSqrt2              1.41421356f
27bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarPI                 3.14159265f
28bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarTanPIOver8         0.414213562f
29bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarRoot2Over2         0.707106781f
30bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarMax                3.402823466e+38f
31bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarInfinity           SK_FloatInfinity
32bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarNegativeInfinity   SK_FloatNegativeInfinity
33bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarNaN                SK_FloatNaN
34bd1605905b1ce165e6b5891547c2b612358b47a8reed
35bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkFixedToScalar(x)          SkFixedToFloat(x)
36bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarToFixed(x)          SkFloatToFixed(x)
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
388f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarFloorToScalar(x)    sk_float_floor(x)
398f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarCeilToScalar(x)     sk_float_ceil(x)
408f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarRoundToScalar(x)    sk_float_floor((x) + 0.5f)
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarFloorToInt(x)       sk_float_floor2int(x)
438f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarCeilToInt(x)        sk_float_ceil2int(x)
448f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarRoundToInt(x)       sk_float_round2int(x)
45bd1605905b1ce165e6b5891547c2b612358b47a8reed
46bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarAbs(x)              sk_float_abs(x)
47bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarCopySign(x, y)      sk_float_copysign(x, y)
48bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarMod(x, y)           sk_float_mod(x,y)
49bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarFraction(x)         sk_float_mod(x, 1.0f)
50bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarSqrt(x)             sk_float_sqrt(x)
51bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarPow(b, e)           sk_float_pow(b, e)
52bd1605905b1ce165e6b5891547c2b612358b47a8reed
53bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarSin(radians)        (float)sk_float_sin(radians)
54bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarCos(radians)        (float)sk_float_cos(radians)
55bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarTan(radians)        (float)sk_float_tan(radians)
56bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarASin(val)           (float)sk_float_asin(val)
57bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarACos(val)           (float)sk_float_acos(val)
58bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarATan2(y, x)         (float)sk_float_atan2(y,x)
59bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarExp(x)              (float)sk_float_exp(x)
60bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarLog(x)              (float)sk_float_log(x)
617729e56a29a44bd47c69c8dc3247421595940accreed#define SkScalarLog2(x)             (float)sk_float_log2(x)
62bd1605905b1ce165e6b5891547c2b612358b47a8reed
63bd1605905b1ce165e6b5891547c2b612358b47a8reed#else   // SK_SCALAR_IS_DOUBLE
64bd1605905b1ce165e6b5891547c2b612358b47a8reed
65bd1605905b1ce165e6b5891547c2b612358b47a8reedtypedef double SkScalar;
66bd1605905b1ce165e6b5891547c2b612358b47a8reed
67bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_Scalar1                  1.0
68bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarHalf               0.5
69bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarSqrt2              1.414213562373095
70bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarPI                 3.141592653589793
71bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarTanPIOver8         0.4142135623731
72bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarRoot2Over2         0.70710678118655
73bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarMax                1.7976931348623157+308
74bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarInfinity           SK_DoubleInfinity
75bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarNegativeInfinity   SK_DoubleNegativeInfinity
76bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarNaN                SK_DoubleNaN
77bd1605905b1ce165e6b5891547c2b612358b47a8reed
78bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkFixedToScalar(x)          SkFixedToDouble(x)
79bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarToFixed(x)          SkDoubleToFixed(x)
80bd1605905b1ce165e6b5891547c2b612358b47a8reed
81bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarFloorToScalar(x)    floor(x)
82bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarCeilToScalar(x)     ceil(x)
83bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarRoundToScalar(x)    floor((x) + 0.5)
84bd1605905b1ce165e6b5891547c2b612358b47a8reed
85bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarFloorToInt(x)       (int)floor(x)
86bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarCeilToInt(x)        (int)ceil(x)
87bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarRoundToInt(x)       (int)floor((x) + 0.5)
88bd1605905b1ce165e6b5891547c2b612358b47a8reed
89bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarAbs(x)              abs(x)
90bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarCopySign(x, y)      copysign(x, y)
91bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarMod(x, y)           fmod(x,y)
92bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarFraction(x)         fmod(x, 1.0)
93bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarSqrt(x)             sqrt(x)
94bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarPow(b, e)           pow(b, e)
95bd1605905b1ce165e6b5891547c2b612358b47a8reed
96bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarSin(radians)        sin(radians)
97bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarCos(radians)        cos(radians)
98bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarTan(radians)        tan(radians)
99bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarASin(val)           asin(val)
100bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarACos(val)           acos(val)
101bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarATan2(y, x)         atan2(y,x)
102bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarExp(x)              exp(x)
103bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarLog(x)              log(x)
1047729e56a29a44bd47c69c8dc3247421595940accreed#define SkScalarLog2(x)             log2(x)
105bd1605905b1ce165e6b5891547c2b612358b47a8reed
106bd1605905b1ce165e6b5891547c2b612358b47a8reed#endif
107bd1605905b1ce165e6b5891547c2b612358b47a8reed
108bd1605905b1ce165e6b5891547c2b612358b47a8reed//////////////////////////////////////////////////////////////////////////////////////////////////
109bd1605905b1ce165e6b5891547c2b612358b47a8reed
110bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkIntToScalar(x)        static_cast<SkScalar>(x)
111bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarTruncToInt(x)   static_cast<int>(x)
112bd1605905b1ce165e6b5891547c2b612358b47a8reed
113bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarToFloat(x)      static_cast<float>(x)
114bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkFloatToScalar(x)      static_cast<SkScalar>(x)
115bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarToDouble(x)     static_cast<double>(x)
116bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkDoubleToScalar(x)     static_cast<SkScalar>(x)
117bd1605905b1ce165e6b5891547c2b612358b47a8reed
118bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SK_ScalarMin            (-SK_ScalarMax)
119bd1605905b1ce165e6b5891547c2b612358b47a8reed
120bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline bool SkScalarIsNaN(SkScalar x) { return x != x; }
121bd1605905b1ce165e6b5891547c2b612358b47a8reed
122bd1605905b1ce165e6b5891547c2b612358b47a8reed/** Returns true if x is not NaN and not infinite
123bd1605905b1ce165e6b5891547c2b612358b47a8reed */
124bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline bool SkScalarIsFinite(SkScalar x) {
125bd1605905b1ce165e6b5891547c2b612358b47a8reed    // We rely on the following behavior of infinities and nans
126bd1605905b1ce165e6b5891547c2b612358b47a8reed    // 0 * finite --> 0
127bd1605905b1ce165e6b5891547c2b612358b47a8reed    // 0 * infinity --> NaN
128bd1605905b1ce165e6b5891547c2b612358b47a8reed    // 0 * NaN --> NaN
129bd1605905b1ce165e6b5891547c2b612358b47a8reed    SkScalar prod = x * 0;
130bd1605905b1ce165e6b5891547c2b612358b47a8reed    // At this point, prod will either be NaN or 0
131454fa71cc31bf45c14e4c0b25502d5332d76c51creed    return !SkScalarIsNaN(prod);
132454fa71cc31bf45c14e4c0b25502d5332d76c51creed}
133454fa71cc31bf45c14e4c0b25502d5332d76c51creed
134454fa71cc31bf45c14e4c0b25502d5332d76c51creedstatic inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) {
135454fa71cc31bf45c14e4c0b25502d5332d76c51creed    SkScalar prod = 0;
136454fa71cc31bf45c14e4c0b25502d5332d76c51creed    prod *= a;
137454fa71cc31bf45c14e4c0b25502d5332d76c51creed    prod *= b;
138454fa71cc31bf45c14e4c0b25502d5332d76c51creed    // At this point, prod will either be NaN or 0
139454fa71cc31bf45c14e4c0b25502d5332d76c51creed    return !SkScalarIsNaN(prod);
140454fa71cc31bf45c14e4c0b25502d5332d76c51creed}
141454fa71cc31bf45c14e4c0b25502d5332d76c51creed
142454fa71cc31bf45c14e4c0b25502d5332d76c51creedstatic inline bool SkScalarsAreFinite(const SkScalar array[], int count) {
143454fa71cc31bf45c14e4c0b25502d5332d76c51creed    SkScalar prod = 0;
144454fa71cc31bf45c14e4c0b25502d5332d76c51creed    for (int i = 0; i < count; ++i) {
145454fa71cc31bf45c14e4c0b25502d5332d76c51creed        prod *= array[i];
146454fa71cc31bf45c14e4c0b25502d5332d76c51creed    }
147454fa71cc31bf45c14e4c0b25502d5332d76c51creed    // At this point, prod will either be NaN or 0
1486f90475632b0ff8e9e83916ee6373d3c26cc9284ehsan.akhgari    return !SkScalarIsNaN(prod);
149bd1605905b1ce165e6b5891547c2b612358b47a8reed}
150185d3d016d1e493694e9aaf45b070f34ba456983reed@google.com
1514e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org/**
1524e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *  Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using
1534e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *  double, to avoid possibly losing the low bit(s) of the answer before calling floor().
1544e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *
1554e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *  This routine will likely be slower than SkScalarRoundToInt(), and should only be used when the
1564e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *  extra precision is known to be valuable.
1574e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *
1584e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *  In particular, this catches the following case:
1594e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *      SkScalar x = 0.49999997;
1604e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *      int ix = SkScalarRoundToInt(x);
1614e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *      SkASSERT(0 == ix);    // <--- fails
1624e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *      ix = SkDScalarRoundToInt(x);
1634e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org *      SkASSERT(0 == ix);    // <--- succeeds
1644e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org */
1654e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.orgstatic inline int SkDScalarRoundToInt(SkScalar x) {
1664e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org    double xx = x;
1674e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org    xx += 0.5;
1684e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org    return (int)floor(xx);
1694e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org}
1704e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org
171bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
172167eb17cd6654a0ab6f7c544441a0defa88e3827bungeman    x = SkTMin(x, max);
173167eb17cd6654a0ab6f7c544441a0defa88e3827bungeman    x = SkTMax<SkScalar>(x, 0);
174167eb17cd6654a0ab6f7c544441a0defa88e3827bungeman    return x;
1758f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com}
176bd1605905b1ce165e6b5891547c2b612358b47a8reed
177bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
178fd0ecf46ce7736a86dd38d8cfc96078e588d10a3bungeman    return SkTPin(x, min, max);
1798f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com}
180bd1605905b1ce165e6b5891547c2b612358b47a8reed
181bd1605905b1ce165e6b5891547c2b612358b47a8reedSkScalar SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
182bd1605905b1ce165e6b5891547c2b612358b47a8reed
183bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
184bd1605905b1ce165e6b5891547c2b612358b47a8reed
185bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarMul(a, b)       ((SkScalar)(a) * (b))
186bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarMulAdd(a, b, c) ((SkScalar)(a) * (b) + (c))
187bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarMulDiv(a, b, c) ((SkScalar)(a) * (b) / (c))
1888f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarInvert(x)       (SK_Scalar1 / (x))
1898f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarFastInvert(x)   (SK_Scalar1 / (x))
190bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarAve(a, b)       (((a) + (b)) * SK_ScalarHalf)
191bd1605905b1ce165e6b5891547c2b612358b47a8reed#define SkScalarHalf(a)         ((a) * SK_ScalarHalf)
1928f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com
1938f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
194c8d732800e1a660fca6d2478fc24d6e6935ef8adcommit-bot@chromium.org#define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI))
195bd1605905b1ce165e6b5891547c2b612358b47a8reed
196bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
197bd1605905b1ce165e6b5891547c2b612358b47a8reedstatic inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
1988f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com
1998f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comstatic inline bool SkScalarIsInt(SkScalar x) {
200bd1605905b1ce165e6b5891547c2b612358b47a8reed    return x == (SkScalar)(int)x;
2018f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com}
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
203647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com/**
204647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com *  Returns -1 || 0 || 1 depending on the sign of value:
205647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com *  -1 if x < 0
206647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com *   0 if x == 0
207647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com *   1 if x > 0
208647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */
209647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.comstatic inline int SkScalarSignAsInt(SkScalar x) {
210647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    return x < 0 ? -1 : (x > 0);
211647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com}
212647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com
213647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com// Scalar result version of above
214647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.comstatic inline SkScalar SkScalarSignAsScalar(SkScalar x) {
215647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
216647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com}
2171b20280f9b2e95fdcf4a2ee6f7f9d5a92c5b94c2reed@google.com
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_ScalarNearlyZero         (SK_Scalar1 / (1 << 12))
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
220187d5595901d1120d9425851e5afdd773f574502reed@android.comstatic inline bool SkScalarNearlyZero(SkScalar x,
2211fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com                                    SkScalar tolerance = SK_ScalarNearlyZero) {
2229b5ca29af81b93faea040daa25a620bee99d6c38reed@google.com    SkASSERT(tolerance >= 0);
2239b5ca29af81b93faea040daa25a620bee99d6c38reed@google.com    return SkScalarAbs(x) <= tolerance;
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2261fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.comstatic inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
2271fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com                                     SkScalar tolerance = SK_ScalarNearlyZero) {
2289b5ca29af81b93faea040daa25a620bee99d6c38reed@google.com    SkASSERT(tolerance >= 0);
2299b5ca29af81b93faea040daa25a620bee99d6c38reed@google.com    return SkScalarAbs(x-y) <= tolerance;
2301fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com}
2311fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Linearly interpolate between A and B, based on t.
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If t is 0, return A
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If t is 1, return B
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    else interpolate.
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    t must be [0..SK_Scalar1]
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
238187d5595901d1120d9425851e5afdd773f574502reed@android.comstatic inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) {
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(t >= 0 && t <= SK_Scalar1);
2401a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com    return A + (B - A) * t;
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org/** Interpolate along the function described by (keys[length], values[length])
24428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    for the passed searchKey.  SearchKeys outside the range keys[0]-keys[Length]
24528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    clamp to the min or max value.  This function was inspired by a desire
24628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    to change the multiplier for thickness in fakeBold; therefore it assumes
24728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    the number of pairs (length) will be small, and a linear search is used.
24828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    Repeated keys are allowed for discontinuous functions (so long as keys is
24928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    monotonically increasing), and if key is the value of a repeated scalar in
25028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    keys, the first one will be used.  However, that may change if a binary
25128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    search is used.
25228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org*/
25328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgSkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[],
25428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org                            const SkScalar values[], int length);
25528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
256e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com/*
257e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com *  Helper to compare an array of scalars.
258e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com */
259e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.comstatic inline bool SkScalarsEqual(const SkScalar a[], const SkScalar b[], int n) {
260e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com    SkASSERT(n >= 0);
261e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com    for (int i = 0; i < n; ++i) {
262e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com        if (a[i] != b[i]) {
263e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com            return false;
264e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com        }
265e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com    }
266e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com    return true;
267e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com}
268e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
270