/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkDisplayMath.h"
enum SkDisplayMath_Properties {
SK_PROPERTY(E),
SK_PROPERTY(LN10),
SK_PROPERTY(LN2),
SK_PROPERTY(LOG10E),
SK_PROPERTY(LOG2E),
SK_PROPERTY(PI),
SK_PROPERTY(SQRT1_2),
SK_PROPERTY(SQRT2)
};
const SkScalar SkDisplayMath::gConstants[] = {
#ifdef SK_SCALAR_IS_FLOAT
2.718281828f, // E
2.302585093f, // LN10
0.693147181f, // LN2
0.434294482f, // LOG10E
1.442695041f, // LOG2E
3.141592654f, // PI
0.707106781f, // SQRT1_2
1.414213562f // SQRT2
#else
0x2B7E1, // E
0x24D76, // LN10
0xB172, // LN2
0x6F2E, // LOG10E
0x17154, // LOG2E
0x3243F, // PI
0xB505, // SQRT1_2
0x16A0A // SQRT2
#endif
};
enum SkDisplayMath_Functions {
SK_FUNCTION(abs),
SK_FUNCTION(acos),
SK_FUNCTION(asin),
SK_FUNCTION(atan),
SK_FUNCTION(atan2),
SK_FUNCTION(ceil),
SK_FUNCTION(cos),
SK_FUNCTION(exp),
SK_FUNCTION(floor),
SK_FUNCTION(log),
SK_FUNCTION(max),
SK_FUNCTION(min),
SK_FUNCTION(pow),
SK_FUNCTION(random),
SK_FUNCTION(round),
SK_FUNCTION(sin),
SK_FUNCTION(sqrt),
SK_FUNCTION(tan)
};
const SkFunctionParamType SkDisplayMath::fFunctionParameters[] = {
(SkFunctionParamType) SkType_Float, // abs
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // acos
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // asin
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // atan
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // atan2
(SkFunctionParamType) SkType_Float,
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // ceil
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // cos
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // exp
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // floor
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // log
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Array, // max
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Array, // min
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // pow
(SkFunctionParamType) SkType_Float,
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // random
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // round
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // sin
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // sqrt
(SkFunctionParamType) 0,
(SkFunctionParamType) SkType_Float, // tan
(SkFunctionParamType) 0
};
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkDisplayMath::fInfo[] = {
SK_MEMBER_PROPERTY(E, Float),
SK_MEMBER_PROPERTY(LN10, Float),
SK_MEMBER_PROPERTY(LN2, Float),
SK_MEMBER_PROPERTY(LOG10E, Float),
SK_MEMBER_PROPERTY(LOG2E, Float),
SK_MEMBER_PROPERTY(PI, Float),
SK_MEMBER_PROPERTY(SQRT1_2, Float),
SK_MEMBER_PROPERTY(SQRT2, Float),
SK_MEMBER_FUNCTION(abs, Float),
SK_MEMBER_FUNCTION(acos, Float),
SK_MEMBER_FUNCTION(asin, Float),
SK_MEMBER_FUNCTION(atan, Float),
SK_MEMBER_FUNCTION(atan2, Float),
SK_MEMBER_FUNCTION(ceil, Float),
SK_MEMBER_FUNCTION(cos, Float),
SK_MEMBER_FUNCTION(exp, Float),
SK_MEMBER_FUNCTION(floor, Float),
SK_MEMBER_FUNCTION(log, Float),
SK_MEMBER_FUNCTION(max, Float),
SK_MEMBER_FUNCTION(min, Float),
SK_MEMBER_FUNCTION(pow, Float),
SK_MEMBER_FUNCTION(random, Float),
SK_MEMBER_FUNCTION(round, Float),
SK_MEMBER_FUNCTION(sin, Float),
SK_MEMBER_FUNCTION(sqrt, Float),
SK_MEMBER_FUNCTION(tan, Float)
};
#endif
DEFINE_GET_MEMBER(SkDisplayMath);
void SkDisplayMath::executeFunction(SkDisplayable* target, int index,
SkTDArray<SkScriptValue>& parameters, SkDisplayTypes type,
SkScriptValue* scriptValue) {
if (scriptValue == NULL)
return;
SkASSERT(target == this);
SkScriptValue* array = parameters.begin();
SkScriptValue* end = parameters.end();
SkScalar input = parameters[0].fOperand.fScalar;
SkScalar scalarResult;
switch (index) {
case SK_FUNCTION(abs):
scalarResult = SkScalarAbs(input);
break;
case SK_FUNCTION(acos):
scalarResult = SkScalarACos(input);
break;
case SK_FUNCTION(asin):
scalarResult = SkScalarASin(input);
break;
case SK_FUNCTION(atan):
scalarResult = SkScalarATan2(input, SK_Scalar1);
break;
case SK_FUNCTION(atan2):
scalarResult = SkScalarATan2(input, parameters[1].fOperand.fScalar);
break;
case SK_FUNCTION(ceil):
scalarResult = SkIntToScalar(SkScalarCeil(input));
break;
case SK_FUNCTION(cos):
scalarResult = SkScalarCos(input);
break;
case SK_FUNCTION(exp):
scalarResult = SkScalarExp(input);
break;
case SK_FUNCTION(floor):
scalarResult = SkIntToScalar(SkScalarFloor(input));
break;
case SK_FUNCTION(log):
scalarResult = SkScalarLog(input);
break;
case SK_FUNCTION(max):
scalarResult = -SK_ScalarMax;
while (array < end) {
scalarResult = SkMaxScalar(scalarResult, array->fOperand.fScalar);
array++;
}
break;
case SK_FUNCTION(min):
scalarResult = SK_ScalarMax;
while (array < end) {
scalarResult = SkMinScalar(scalarResult, array->fOperand.fScalar);
array++;
}
break;
case SK_FUNCTION(pow):
// not the greatest -- but use x^y = e^(y * ln(x))
scalarResult = SkScalarLog(input);
scalarResult = SkScalarMul(parameters[1].fOperand.fScalar, scalarResult);
scalarResult = SkScalarExp(scalarResult);
break;
case SK_FUNCTION(random):
scalarResult = fRandom.nextUScalar1();
break;
case SK_FUNCTION(round):
scalarResult = SkIntToScalar(SkScalarRound(input));
break;
case SK_FUNCTION(sin):
scalarResult = SkScalarSin(input);
break;
case SK_FUNCTION(sqrt): {
SkASSERT(parameters.count() == 1);
SkASSERT(type == SkType_Float);
scalarResult = SkScalarSqrt(input);
} break;
case SK_FUNCTION(tan):
scalarResult = SkScalarTan(input);
break;
default:
SkASSERT(0);
scalarResult = SK_ScalarNaN;
}
scriptValue->fOperand.fScalar = scalarResult;
scriptValue->fType = SkType_Float;
}
const SkFunctionParamType* SkDisplayMath::getFunctionsParameters() {
return fFunctionParameters;
}
bool SkDisplayMath::getProperty(int index, SkScriptValue* value) const {
if ((unsigned)index < SK_ARRAY_COUNT(gConstants)) {
value->fOperand.fScalar = gConstants[index];
value->fType = SkType_Float;
return true;
}
SkASSERT(0);
return false;
}