2008-12-17 15:59:43 +00:00
|
|
|
/*
|
2011-07-28 14:26:00 +00:00
|
|
|
* Copyright 2006 The Android Open Source Project
|
2008-12-17 15:59:43 +00:00
|
|
|
*
|
2011-07-28 14:26:00 +00:00
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2008-12-17 15:59:43 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SkScalar_DEFINED
|
|
|
|
#define SkScalar_DEFINED
|
|
|
|
|
2015-08-18 01:29:47 +00:00
|
|
|
#include "../private/SkFloatingPoint.h"
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-02-02 13:12:23 +00:00
|
|
|
#undef SK_SCALAR_IS_FLOAT
|
|
|
|
#define SK_SCALAR_IS_FLOAT 1
|
|
|
|
|
2014-10-31 13:55:41 +00:00
|
|
|
typedef float SkScalar;
|
|
|
|
|
|
|
|
#define SK_Scalar1 1.0f
|
|
|
|
#define SK_ScalarHalf 0.5f
|
|
|
|
#define SK_ScalarSqrt2 1.41421356f
|
|
|
|
#define SK_ScalarPI 3.14159265f
|
|
|
|
#define SK_ScalarTanPIOver8 0.414213562f
|
|
|
|
#define SK_ScalarRoot2Over2 0.707106781f
|
|
|
|
#define SK_ScalarMax 3.402823466e+38f
|
|
|
|
#define SK_ScalarInfinity SK_FloatInfinity
|
|
|
|
#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity
|
|
|
|
#define SK_ScalarNaN SK_FloatNaN
|
|
|
|
|
2013-12-17 16:44:46 +00:00
|
|
|
#define SkScalarFloorToScalar(x) sk_float_floor(x)
|
|
|
|
#define SkScalarCeilToScalar(x) sk_float_ceil(x)
|
|
|
|
#define SkScalarRoundToScalar(x) sk_float_floor((x) + 0.5f)
|
2016-03-10 21:39:30 +00:00
|
|
|
#define SkScalarTruncToScalar(x) sk_float_trunc(x)
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2013-12-17 16:44:46 +00:00
|
|
|
#define SkScalarFloorToInt(x) sk_float_floor2int(x)
|
|
|
|
#define SkScalarCeilToInt(x) sk_float_ceil2int(x)
|
|
|
|
#define SkScalarRoundToInt(x) sk_float_round2int(x)
|
2014-10-31 13:55:41 +00:00
|
|
|
|
|
|
|
#define SkScalarAbs(x) sk_float_abs(x)
|
|
|
|
#define SkScalarCopySign(x, y) sk_float_copysign(x, y)
|
|
|
|
#define SkScalarMod(x, y) sk_float_mod(x,y)
|
|
|
|
#define SkScalarSqrt(x) sk_float_sqrt(x)
|
|
|
|
#define SkScalarPow(b, e) sk_float_pow(b, e)
|
|
|
|
|
|
|
|
#define SkScalarSin(radians) (float)sk_float_sin(radians)
|
|
|
|
#define SkScalarCos(radians) (float)sk_float_cos(radians)
|
|
|
|
#define SkScalarTan(radians) (float)sk_float_tan(radians)
|
|
|
|
#define SkScalarASin(val) (float)sk_float_asin(val)
|
|
|
|
#define SkScalarACos(val) (float)sk_float_acos(val)
|
|
|
|
#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x)
|
|
|
|
#define SkScalarExp(x) (float)sk_float_exp(x)
|
|
|
|
#define SkScalarLog(x) (float)sk_float_log(x)
|
2015-01-16 16:35:09 +00:00
|
|
|
#define SkScalarLog2(x) (float)sk_float_log2(x)
|
2014-10-31 13:55:41 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#define SkIntToScalar(x) static_cast<SkScalar>(x)
|
2016-05-13 12:06:19 +00:00
|
|
|
#define SkIntToFloat(x) static_cast<float>(x)
|
2017-09-18 17:20:32 +00:00
|
|
|
#define SkScalarTruncToInt(x) sk_float_saturate2int(x)
|
2014-10-31 13:55:41 +00:00
|
|
|
|
|
|
|
#define SkScalarToFloat(x) static_cast<float>(x)
|
|
|
|
#define SkFloatToScalar(x) static_cast<SkScalar>(x)
|
|
|
|
#define SkScalarToDouble(x) static_cast<double>(x)
|
|
|
|
#define SkDoubleToScalar(x) static_cast<SkScalar>(x)
|
|
|
|
|
|
|
|
#define SK_ScalarMin (-SK_ScalarMax)
|
|
|
|
|
|
|
|
static inline bool SkScalarIsNaN(SkScalar x) { return x != x; }
|
|
|
|
|
|
|
|
/** Returns true if x is not NaN and not infinite
|
|
|
|
*/
|
|
|
|
static inline bool SkScalarIsFinite(SkScalar x) {
|
|
|
|
// We rely on the following behavior of infinities and nans
|
|
|
|
// 0 * finite --> 0
|
|
|
|
// 0 * infinity --> NaN
|
|
|
|
// 0 * NaN --> NaN
|
|
|
|
SkScalar prod = x * 0;
|
|
|
|
// At this point, prod will either be NaN or 0
|
2015-02-10 16:46:22 +00:00
|
|
|
return !SkScalarIsNaN(prod);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) {
|
|
|
|
SkScalar prod = 0;
|
|
|
|
prod *= a;
|
|
|
|
prod *= b;
|
|
|
|
// At this point, prod will either be NaN or 0
|
|
|
|
return !SkScalarIsNaN(prod);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool SkScalarsAreFinite(const SkScalar array[], int count) {
|
|
|
|
SkScalar prod = 0;
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
|
|
prod *= array[i];
|
|
|
|
}
|
|
|
|
// At this point, prod will either be NaN or 0
|
2014-12-15 20:08:47 +00:00
|
|
|
return !SkScalarIsNaN(prod);
|
2014-10-31 13:55:41 +00:00
|
|
|
}
|
2011-05-06 12:18:08 +00:00
|
|
|
|
2014-05-05 16:04:42 +00:00
|
|
|
/**
|
|
|
|
* Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using
|
|
|
|
* double, to avoid possibly losing the low bit(s) of the answer before calling floor().
|
|
|
|
*
|
|
|
|
* This routine will likely be slower than SkScalarRoundToInt(), and should only be used when the
|
|
|
|
* extra precision is known to be valuable.
|
|
|
|
*
|
|
|
|
* In particular, this catches the following case:
|
|
|
|
* SkScalar x = 0.49999997;
|
|
|
|
* int ix = SkScalarRoundToInt(x);
|
|
|
|
* SkASSERT(0 == ix); // <--- fails
|
|
|
|
* ix = SkDScalarRoundToInt(x);
|
|
|
|
* SkASSERT(0 == ix); // <--- succeeds
|
|
|
|
*/
|
|
|
|
static inline int SkDScalarRoundToInt(SkScalar x) {
|
|
|
|
double xx = x;
|
|
|
|
xx += 0.5;
|
|
|
|
return (int)floor(xx);
|
|
|
|
}
|
|
|
|
|
2016-03-10 21:39:30 +00:00
|
|
|
/** Returns the fractional part of the scalar. */
|
|
|
|
static inline SkScalar SkScalarFraction(SkScalar x) {
|
|
|
|
return x - SkScalarTruncToScalar(x);
|
|
|
|
}
|
|
|
|
|
2014-10-31 13:55:41 +00:00
|
|
|
static inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
|
2015-03-09 20:40:15 +00:00
|
|
|
x = SkTMin(x, max);
|
|
|
|
x = SkTMax<SkScalar>(x, 0);
|
|
|
|
return x;
|
2013-12-17 16:44:46 +00:00
|
|
|
}
|
2014-10-31 13:55:41 +00:00
|
|
|
|
|
|
|
static inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
|
2015-04-16 19:18:28 +00:00
|
|
|
return SkTPin(x, min, max);
|
2013-12-17 16:44:46 +00:00
|
|
|
}
|
2014-10-31 13:55:41 +00:00
|
|
|
|
|
|
|
SkScalar SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
|
|
|
|
|
|
|
|
static inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
|
|
|
|
|
2018-02-12 16:46:19 +00:00
|
|
|
#define SkScalarDiv(numer, denom) sk_ieee_float_divide(numer, denom)
|
|
|
|
#define SkScalarInvert(x) sk_ieee_float_divide(SK_Scalar1, (x))
|
|
|
|
#define SkScalarFastInvert(x) sk_ieee_float_divide(SK_Scalar1, (x))
|
|
|
|
#define SkScalarAve(a, b) (((a) + (b)) * SK_ScalarHalf)
|
|
|
|
#define SkScalarHalf(a) ((a) * SK_ScalarHalf)
|
2013-12-17 16:44:46 +00:00
|
|
|
|
|
|
|
#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
|
2014-01-06 18:17:24 +00:00
|
|
|
#define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI))
|
2014-10-31 13:55:41 +00:00
|
|
|
|
|
|
|
static inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
|
|
|
|
static inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
|
2013-12-17 16:44:46 +00:00
|
|
|
|
|
|
|
static inline bool SkScalarIsInt(SkScalar x) {
|
2017-08-28 19:32:01 +00:00
|
|
|
return x == SkScalarFloorToScalar(x);
|
2013-12-17 16:44:46 +00:00
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2011-08-23 14:39:01 +00:00
|
|
|
/**
|
|
|
|
* Returns -1 || 0 || 1 depending on the sign of value:
|
|
|
|
* -1 if x < 0
|
|
|
|
* 0 if x == 0
|
|
|
|
* 1 if x > 0
|
|
|
|
*/
|
|
|
|
static inline int SkScalarSignAsInt(SkScalar x) {
|
|
|
|
return x < 0 ? -1 : (x > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scalar result version of above
|
|
|
|
static inline SkScalar SkScalarSignAsScalar(SkScalar x) {
|
|
|
|
return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
|
|
|
|
}
|
2011-08-01 20:49:45 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
|
|
|
|
|
2009-07-08 14:03:56 +00:00
|
|
|
static inline bool SkScalarNearlyZero(SkScalar x,
|
2016-01-25 22:19:56 +00:00
|
|
|
SkScalar tolerance = SK_ScalarNearlyZero) {
|
2012-04-12 12:51:32 +00:00
|
|
|
SkASSERT(tolerance >= 0);
|
|
|
|
return SkScalarAbs(x) <= tolerance;
|
2008-12-17 15:59:43 +00:00
|
|
|
}
|
|
|
|
|
2011-06-15 18:04:58 +00:00
|
|
|
static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
|
2015-09-15 17:20:55 +00:00
|
|
|
SkScalar tolerance = SK_ScalarNearlyZero) {
|
2012-04-12 12:51:32 +00:00
|
|
|
SkASSERT(tolerance >= 0);
|
|
|
|
return SkScalarAbs(x-y) <= tolerance;
|
2011-06-15 18:04:58 +00:00
|
|
|
}
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
/** Linearly interpolate between A and B, based on t.
|
|
|
|
If t is 0, return A
|
|
|
|
If t is 1, return B
|
|
|
|
else interpolate.
|
|
|
|
t must be [0..SK_Scalar1]
|
|
|
|
*/
|
2009-07-08 14:03:56 +00:00
|
|
|
static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) {
|
2008-12-17 15:59:43 +00:00
|
|
|
SkASSERT(t >= 0 && t <= SK_Scalar1);
|
2014-01-27 13:41:02 +00:00
|
|
|
return A + (B - A) * t;
|
2008-12-17 15:59:43 +00:00
|
|
|
}
|
|
|
|
|
PDF: Add text support with a font framework (font embedding to come).
Supports fakeBold, underline, strikethrough, mode (fill, stroke, both), size, skew, alignment (left, center, right).
Missing is drawFontOnPath and font lookup and embedding.
Changed SkPDFString to support how it is used from drawText methods.
Moved compile assert into SkTypes.
Moved constants and utility function used to support fakeBold, underline, and strikethrough into higher level locations.
Review URL: http://codereview.appspot.com/2946041
git-svn-id: http://skia.googlecode.com/svn/trunk@624 2bbb7eff-a529-9590-31e7-b0007b416f81
2010-11-11 21:37:00 +00:00
|
|
|
/** Interpolate along the function described by (keys[length], values[length])
|
|
|
|
for the passed searchKey. SearchKeys outside the range keys[0]-keys[Length]
|
|
|
|
clamp to the min or max value. This function was inspired by a desire
|
|
|
|
to change the multiplier for thickness in fakeBold; therefore it assumes
|
|
|
|
the number of pairs (length) will be small, and a linear search is used.
|
|
|
|
Repeated keys are allowed for discontinuous functions (so long as keys is
|
|
|
|
monotonically increasing), and if key is the value of a repeated scalar in
|
|
|
|
keys, the first one will be used. However, that may change if a binary
|
|
|
|
search is used.
|
|
|
|
*/
|
|
|
|
SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[],
|
|
|
|
const SkScalar values[], int length);
|
|
|
|
|
2012-10-31 19:59:23 +00:00
|
|
|
/*
|
|
|
|
* Helper to compare an array of scalars.
|
|
|
|
*/
|
|
|
|
static inline bool SkScalarsEqual(const SkScalar a[], const SkScalar b[], int n) {
|
|
|
|
SkASSERT(n >= 0);
|
|
|
|
for (int i = 0; i < n; ++i) {
|
|
|
|
if (a[i] != b[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#endif
|