2011-07-28 14:26:00 +00:00
|
|
|
|
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
|
|
|
*/
|
|
|
|
|
2011-07-28 14:26:00 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#ifndef SkScalar_DEFINED
|
|
|
|
#define SkScalar_DEFINED
|
|
|
|
|
|
|
|
#include "SkFixed.h"
|
2011-06-09 22:16:28 +00:00
|
|
|
#include "SkFloatingPoint.h"
|
2008-12-17 15:59:43 +00:00
|
|
|
|
|
|
|
/** \file SkScalar.h
|
|
|
|
|
|
|
|
Types and macros for the data type SkScalar. This is the fractional numeric type
|
|
|
|
that, depending on the compile-time flag SK_SCALAR_IS_FLOAT, may be implemented
|
|
|
|
either as an IEEE float, or as a 16.16 SkFixed. The macros in this file are written
|
|
|
|
to allow the calling code to manipulate SkScalar values without knowing which representation
|
|
|
|
is in effect.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef SK_SCALAR_IS_FLOAT
|
|
|
|
|
|
|
|
/** SkScalar is our type for fractional values and coordinates. Depending on
|
|
|
|
compile configurations, it is either represented as an IEEE float, or
|
|
|
|
as a 16.16 fixed point integer.
|
|
|
|
*/
|
|
|
|
typedef float SkScalar;
|
|
|
|
extern const uint32_t gIEEENotANumber;
|
|
|
|
extern const uint32_t gIEEEInfinity;
|
|
|
|
|
|
|
|
/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar
|
|
|
|
*/
|
|
|
|
#define SK_Scalar1 (1.0f)
|
|
|
|
/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar
|
|
|
|
*/
|
|
|
|
#define SK_ScalarHalf (0.5f)
|
|
|
|
/** SK_ScalarInfinity is defined to be infinity as an SkScalar
|
|
|
|
*/
|
|
|
|
#define SK_ScalarInfinity (*(const float*)&gIEEEInfinity)
|
|
|
|
/** SK_ScalarMax is defined to be the largest value representable as an SkScalar
|
|
|
|
*/
|
2011-03-18 14:29:44 +00:00
|
|
|
#define SK_ScalarMax (3.402823466e+38f)
|
2008-12-17 15:59:43 +00:00
|
|
|
/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar
|
|
|
|
*/
|
2011-05-09 22:32:52 +00:00
|
|
|
#define SK_ScalarMin (-SK_ScalarMax)
|
2008-12-17 15:59:43 +00:00
|
|
|
/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar
|
|
|
|
*/
|
|
|
|
#define SK_ScalarNaN (*(const float*)(const void*)&gIEEENotANumber)
|
|
|
|
/** SkScalarIsNaN(n) returns true if argument is not a number
|
|
|
|
*/
|
|
|
|
static inline bool SkScalarIsNaN(float x) { return x != x; }
|
2011-02-08 21:56:39 +00:00
|
|
|
/** Returns true if x is not NaN and not infinite */
|
|
|
|
static inline bool SkScalarIsFinite(float x) {
|
|
|
|
uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
|
|
|
|
int exponent = bits << 1 >> 24;
|
|
|
|
return exponent != 0xFF;
|
|
|
|
}
|
2011-05-24 14:51:57 +00:00
|
|
|
#ifdef SK_DEBUG
|
|
|
|
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
|
|
|
*
|
|
|
|
* If we're compiling in DEBUG mode, and can thus afford some extra runtime
|
|
|
|
* cycles, check to make sure that the parameter passed in has not already
|
|
|
|
* been converted to SkScalar. (A double conversion like this is harmless
|
|
|
|
* for SK_SCALAR_IS_FLOAT, but for SK_SCALAR_IS_FIXED this causes trouble.)
|
|
|
|
*
|
|
|
|
* Note that we need all of these method signatures to properly handle the
|
|
|
|
* various types that we pass into SkIntToScalar() to date:
|
|
|
|
* int, size_t, U8CPU, etc., even though what we really mean is "anything
|
|
|
|
* but a float".
|
|
|
|
*/
|
|
|
|
static inline float SkIntToScalar(signed int param) {
|
|
|
|
return (float)param;
|
|
|
|
}
|
|
|
|
static inline float SkIntToScalar(unsigned int param) {
|
|
|
|
return (float)param;
|
|
|
|
}
|
|
|
|
static inline float SkIntToScalar(signed long param) {
|
|
|
|
return (float)param;
|
|
|
|
}
|
|
|
|
static inline float SkIntToScalar(unsigned long param) {
|
|
|
|
return (float)param;
|
|
|
|
}
|
|
|
|
static inline float SkIntToScalar(float param) {
|
|
|
|
/* If the parameter passed into SkIntToScalar is a float,
|
|
|
|
* one of two things has happened:
|
|
|
|
* 1. the parameter was an SkScalar (which is typedef'd to float)
|
|
|
|
* 2. the parameter was a float instead of an int
|
|
|
|
*
|
|
|
|
* Either way, it's not good.
|
|
|
|
*/
|
|
|
|
SkASSERT(!"looks like you passed an SkScalar into SkIntToScalar");
|
|
|
|
return (float)0;
|
|
|
|
}
|
|
|
|
#else // not SK_DEBUG
|
2008-12-17 15:59:43 +00:00
|
|
|
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
|
|
|
*/
|
|
|
|
#define SkIntToScalar(n) ((float)(n))
|
2011-05-24 14:51:57 +00:00
|
|
|
#endif // not SK_DEBUG
|
2008-12-17 15:59:43 +00:00
|
|
|
/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
|
|
|
|
*/
|
|
|
|
#define SkFixedToScalar(x) SkFixedToFloat(x)
|
|
|
|
/** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed
|
|
|
|
*/
|
|
|
|
#define SkScalarToFixed(x) SkFloatToFixed(x)
|
|
|
|
|
|
|
|
#define SkScalarToFloat(n) (n)
|
|
|
|
#define SkFloatToScalar(n) (n)
|
|
|
|
|
|
|
|
#define SkScalarToDouble(n) (double)(n)
|
|
|
|
#define SkDoubleToScalar(n) (float)(n)
|
|
|
|
|
|
|
|
/** SkScalarFraction(x) returns the signed fractional part of the argument
|
|
|
|
*/
|
|
|
|
#define SkScalarFraction(x) sk_float_mod(x, 1.0f)
|
2011-08-01 20:49:45 +00:00
|
|
|
|
|
|
|
#define SkScalarFloorToScalar(x) sk_float_floor(x)
|
|
|
|
#define SkScalarCeilToScalar(x) sk_float_ceil(x)
|
|
|
|
#define SkScalarRoundToScalar(x) sk_float_round(x)
|
|
|
|
|
|
|
|
#define SkScalarFloorToInt(x) sk_float_floor2int(x)
|
|
|
|
#define SkScalarCeilToInt(x) sk_float_ceil2int(x)
|
|
|
|
#define SkScalarRoundToInt(x) sk_float_round2int(x)
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
/** Returns the absolute value of the specified SkScalar
|
|
|
|
*/
|
|
|
|
#define SkScalarAbs(x) sk_float_abs(x)
|
2010-02-09 18:30:59 +00:00
|
|
|
/** Return x with the sign of y
|
|
|
|
*/
|
|
|
|
#define SkScalarCopySign(x, y) sk_float_copysign(x, y)
|
2008-12-17 15:59:43 +00:00
|
|
|
/** Returns the value pinned between 0 and max inclusive
|
|
|
|
*/
|
|
|
|
inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
|
|
|
|
return x < 0 ? 0 : x > max ? max : x;
|
|
|
|
}
|
|
|
|
/** Returns the value pinned between min and max inclusive
|
|
|
|
*/
|
|
|
|
inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
|
|
|
|
return x < min ? min : x > max ? max : x;
|
|
|
|
}
|
|
|
|
/** Returns the specified SkScalar squared (x*x)
|
|
|
|
*/
|
|
|
|
inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
|
|
|
|
/** Returns the product of two SkScalars
|
|
|
|
*/
|
|
|
|
#define SkScalarMul(a, b) ((float)(a) * (b))
|
|
|
|
/** Returns the product of two SkScalars plus a third SkScalar
|
|
|
|
*/
|
|
|
|
#define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c))
|
|
|
|
/** Returns the product of a SkScalar and an int rounded to the nearest integer value
|
|
|
|
*/
|
|
|
|
#define SkScalarMulRound(a, b) SkScalarRound((float)(a) * (b))
|
|
|
|
/** Returns the product of a SkScalar and an int promoted to the next larger int
|
|
|
|
*/
|
|
|
|
#define SkScalarMulCeil(a, b) SkScalarCeil((float)(a) * (b))
|
|
|
|
/** Returns the product of a SkScalar and an int truncated to the next smaller int
|
|
|
|
*/
|
|
|
|
#define SkScalarMulFloor(a, b) SkScalarFloor((float)(a) * (b))
|
|
|
|
/** Returns the quotient of two SkScalars (a/b)
|
|
|
|
*/
|
|
|
|
#define SkScalarDiv(a, b) ((float)(a) / (b))
|
|
|
|
/** Returns the mod of two SkScalars (a mod b)
|
|
|
|
*/
|
|
|
|
#define SkScalarMod(x,y) sk_float_mod(x,y)
|
|
|
|
/** Returns the product of the first two arguments, divided by the third argument
|
|
|
|
*/
|
|
|
|
#define SkScalarMulDiv(a, b, c) ((float)(a) * (b) / (c))
|
|
|
|
/** Returns the multiplicative inverse of the SkScalar (1/x)
|
|
|
|
*/
|
|
|
|
#define SkScalarInvert(x) (SK_Scalar1 / (x))
|
|
|
|
#define SkScalarFastInvert(x) (SK_Scalar1 / (x))
|
|
|
|
/** Returns the square root of the SkScalar
|
|
|
|
*/
|
|
|
|
#define SkScalarSqrt(x) sk_float_sqrt(x)
|
|
|
|
/** Returns the average of two SkScalars (a+b)/2
|
|
|
|
*/
|
|
|
|
#define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
|
|
|
|
/** Returns the geometric mean of two SkScalars
|
|
|
|
*/
|
|
|
|
#define SkScalarMean(a, b) sk_float_sqrt((float)(a) * (b))
|
|
|
|
/** Returns one half of the specified SkScalar
|
|
|
|
*/
|
|
|
|
#define SkScalarHalf(a) ((a) * 0.5f)
|
|
|
|
|
|
|
|
#define SK_ScalarSqrt2 1.41421356f
|
|
|
|
#define SK_ScalarPI 3.14159265f
|
|
|
|
#define SK_ScalarTanPIOver8 0.414213562f
|
|
|
|
#define SK_ScalarRoot2Over2 0.707106781f
|
|
|
|
|
|
|
|
#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
|
|
|
|
float SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
|
|
|
|
#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)
|
|
|
|
|
|
|
|
inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
|
|
|
|
inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
|
|
|
|
|
2011-05-06 12:18:08 +00:00
|
|
|
static inline bool SkScalarIsInt(SkScalar x) {
|
|
|
|
return x == (float)(int)x;
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
#else
|
|
|
|
typedef SkFixed SkScalar;
|
|
|
|
|
|
|
|
#define SK_Scalar1 SK_Fixed1
|
|
|
|
#define SK_ScalarHalf SK_FixedHalf
|
|
|
|
#define SK_ScalarInfinity SK_FixedMax
|
|
|
|
#define SK_ScalarMax SK_FixedMax
|
|
|
|
#define SK_ScalarMin SK_FixedMin
|
|
|
|
#define SK_ScalarNaN SK_FixedNaN
|
|
|
|
#define SkScalarIsNaN(x) ((x) == SK_FixedNaN)
|
2011-02-08 21:56:39 +00:00
|
|
|
#define SkScalarIsFinite(x) ((x) != SK_FixedNaN)
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#define SkIntToScalar(n) SkIntToFixed(n)
|
|
|
|
#define SkFixedToScalar(x) (x)
|
|
|
|
#define SkScalarToFixed(x) (x)
|
|
|
|
#ifdef SK_CAN_USE_FLOAT
|
|
|
|
#define SkScalarToFloat(n) SkFixedToFloat(n)
|
|
|
|
#define SkFloatToScalar(n) SkFloatToFixed(n)
|
|
|
|
|
|
|
|
#define SkScalarToDouble(n) SkFixedToDouble(n)
|
|
|
|
#define SkDoubleToScalar(n) SkDoubleToFixed(n)
|
|
|
|
#endif
|
|
|
|
#define SkScalarFraction(x) SkFixedFraction(x)
|
2011-08-01 20:49:45 +00:00
|
|
|
|
|
|
|
#define SkScalarFloorToScalar(x) SkFixedFloorToFixed(x)
|
|
|
|
#define SkScalarCeilToScalar(x) SkFixedCeilToFixed(x)
|
|
|
|
#define SkScalarRoundToScalar(x) SkFixedRoundToFixed(x)
|
|
|
|
|
|
|
|
#define SkScalarFloorToInt(x) SkFixedFloorToInt(x)
|
|
|
|
#define SkScalarCeilToInt(x) SkFixedCeilToInt(x)
|
|
|
|
#define SkScalarRoundToInt(x) SkFixedRoundToInt(x)
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#define SkScalarAbs(x) SkFixedAbs(x)
|
2010-02-09 18:30:59 +00:00
|
|
|
#define SkScalarCopySign(x, y) SkCopySign32(x, y)
|
2008-12-17 15:59:43 +00:00
|
|
|
#define SkScalarClampMax(x, max) SkClampMax(x, max)
|
|
|
|
#define SkScalarPin(x, min, max) SkPin32(x, min, max)
|
|
|
|
#define SkScalarSquare(x) SkFixedSquare(x)
|
|
|
|
#define SkScalarMul(a, b) SkFixedMul(a, b)
|
|
|
|
#define SkScalarMulAdd(a, b, c) SkFixedMulAdd(a, b, c)
|
|
|
|
#define SkScalarMulRound(a, b) SkFixedMulCommon(a, b, SK_FixedHalf)
|
|
|
|
#define SkScalarMulCeil(a, b) SkFixedMulCommon(a, b, SK_Fixed1 - 1)
|
|
|
|
#define SkScalarMulFloor(a, b) SkFixedMulCommon(a, b, 0)
|
|
|
|
#define SkScalarDiv(a, b) SkFixedDiv(a, b)
|
|
|
|
#define SkScalarMod(a, b) SkFixedMod(a, b)
|
|
|
|
#define SkScalarMulDiv(a, b, c) SkMulDiv(a, b, c)
|
|
|
|
#define SkScalarInvert(x) SkFixedInvert(x)
|
|
|
|
#define SkScalarFastInvert(x) SkFixedFastInvert(x)
|
|
|
|
#define SkScalarSqrt(x) SkFixedSqrt(x)
|
|
|
|
#define SkScalarAve(a, b) SkFixedAve(a, b)
|
|
|
|
#define SkScalarMean(a, b) SkFixedMean(a, b)
|
|
|
|
#define SkScalarHalf(a) ((a) >> 1)
|
|
|
|
|
|
|
|
#define SK_ScalarSqrt2 SK_FixedSqrt2
|
|
|
|
#define SK_ScalarPI SK_FixedPI
|
|
|
|
#define SK_ScalarTanPIOver8 SK_FixedTanPIOver8
|
|
|
|
#define SK_ScalarRoot2Over2 SK_FixedRoot2Over2
|
|
|
|
|
|
|
|
#define SkDegreesToRadians(degrees) SkFractMul(degrees, SK_FractPIOver180)
|
|
|
|
#define SkScalarSinCos(radians, cosPtr) SkFixedSinCos(radians, cosPtr)
|
|
|
|
#define SkScalarSin(radians) SkFixedSin(radians)
|
|
|
|
#define SkScalarCos(radians) SkFixedCos(radians)
|
|
|
|
#define SkScalarTan(val) SkFixedTan(val)
|
|
|
|
#define SkScalarASin(val) SkFixedASin(val)
|
|
|
|
#define SkScalarACos(val) SkFixedACos(val)
|
|
|
|
#define SkScalarATan2(y, x) SkFixedATan2(y,x)
|
|
|
|
#define SkScalarExp(x) SkFixedExp(x)
|
|
|
|
#define SkScalarLog(x) SkFixedLog(x)
|
|
|
|
|
|
|
|
#define SkMaxScalar(a, b) SkMax32(a, b)
|
|
|
|
#define SkMinScalar(a, b) SkMin32(a, b)
|
2011-05-06 12:18:08 +00:00
|
|
|
|
|
|
|
static inline bool SkScalarIsInt(SkFixed x) {
|
|
|
|
return 0 == (x & 0xffff);
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
#endif
|
|
|
|
|
2011-08-01 20:49:45 +00:00
|
|
|
// DEPRECATED : use ToInt or ToScalar variant
|
|
|
|
#define SkScalarFloor(x) SkScalarFloorToInt(x)
|
|
|
|
#define SkScalarCeil(x) SkScalarCeilToInt(x)
|
|
|
|
#define SkScalarRound(x) SkScalarRoundToInt(x)
|
|
|
|
|
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))
|
|
|
|
|
|
|
|
/* <= is slower than < for floats, so we use < for our tolerance test
|
|
|
|
*/
|
|
|
|
|
2009-07-08 14:03:56 +00:00
|
|
|
static inline bool SkScalarNearlyZero(SkScalar x,
|
2011-06-15 18:04:58 +00:00
|
|
|
SkScalar tolerance = SK_ScalarNearlyZero) {
|
2008-12-17 15:59:43 +00:00
|
|
|
SkASSERT(tolerance > 0);
|
|
|
|
return SkScalarAbs(x) < tolerance;
|
|
|
|
}
|
|
|
|
|
2011-06-15 18:04:58 +00:00
|
|
|
static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
|
|
|
|
SkScalar tolerance = SK_ScalarNearlyZero) {
|
|
|
|
SkASSERT(tolerance > 0);
|
|
|
|
return SkScalarAbs(x-y) < tolerance;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
return A + SkScalarMul(B - A, t);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#endif
|