1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "SkDisplayMath.h"
11
12enum SkDisplayMath_Properties {
13    SK_PROPERTY(E),
14    SK_PROPERTY(LN10),
15    SK_PROPERTY(LN2),
16    SK_PROPERTY(LOG10E),
17    SK_PROPERTY(LOG2E),
18    SK_PROPERTY(PI),
19    SK_PROPERTY(SQRT1_2),
20    SK_PROPERTY(SQRT2)
21};
22
23const SkScalar SkDisplayMath::gConstants[] = {
24    2.718281828f,   // E
25    2.302585093f,   // LN10
26    0.693147181f,   // LN2
27    0.434294482f,   // LOG10E
28    1.442695041f,   // LOG2E
29    3.141592654f,   // PI
30    0.707106781f,   // SQRT1_2
31    1.414213562f        // SQRT2
32};
33
34enum SkDisplayMath_Functions {
35    SK_FUNCTION(abs),
36    SK_FUNCTION(acos),
37    SK_FUNCTION(asin),
38    SK_FUNCTION(atan),
39    SK_FUNCTION(atan2),
40    SK_FUNCTION(ceil),
41    SK_FUNCTION(cos),
42    SK_FUNCTION(exp),
43    SK_FUNCTION(floor),
44    SK_FUNCTION(log),
45    SK_FUNCTION(max),
46    SK_FUNCTION(min),
47    SK_FUNCTION(pow),
48    SK_FUNCTION(random),
49    SK_FUNCTION(round),
50    SK_FUNCTION(sin),
51    SK_FUNCTION(sqrt),
52    SK_FUNCTION(tan)
53};
54
55const SkFunctionParamType SkDisplayMath::fFunctionParameters[] = {
56    (SkFunctionParamType) SkType_Float, // abs
57    (SkFunctionParamType) 0,
58    (SkFunctionParamType) SkType_Float, // acos
59    (SkFunctionParamType) 0,
60    (SkFunctionParamType) SkType_Float, // asin
61    (SkFunctionParamType) 0,
62    (SkFunctionParamType) SkType_Float, // atan
63    (SkFunctionParamType) 0,
64    (SkFunctionParamType) SkType_Float, // atan2
65    (SkFunctionParamType) SkType_Float,
66    (SkFunctionParamType) 0,
67    (SkFunctionParamType) SkType_Float, // ceil
68    (SkFunctionParamType) 0,
69    (SkFunctionParamType) SkType_Float, // cos
70    (SkFunctionParamType) 0,
71    (SkFunctionParamType) SkType_Float, // exp
72    (SkFunctionParamType) 0,
73    (SkFunctionParamType) SkType_Float, // floor
74    (SkFunctionParamType) 0,
75    (SkFunctionParamType) SkType_Float, // log
76    (SkFunctionParamType) 0,
77    (SkFunctionParamType) SkType_Array, // max
78    (SkFunctionParamType) 0,
79    (SkFunctionParamType) SkType_Array, // min
80    (SkFunctionParamType) 0,
81    (SkFunctionParamType) SkType_Float, // pow
82    (SkFunctionParamType) SkType_Float,
83    (SkFunctionParamType) 0,
84    (SkFunctionParamType) SkType_Float, // random
85    (SkFunctionParamType) 0,
86    (SkFunctionParamType) SkType_Float, // round
87    (SkFunctionParamType) 0,
88    (SkFunctionParamType) SkType_Float, // sin
89    (SkFunctionParamType) 0,
90    (SkFunctionParamType) SkType_Float, // sqrt
91    (SkFunctionParamType) 0,
92    (SkFunctionParamType) SkType_Float, // tan
93    (SkFunctionParamType) 0
94};
95
96#if SK_USE_CONDENSED_INFO == 0
97
98const SkMemberInfo SkDisplayMath::fInfo[] = {
99    SK_MEMBER_PROPERTY(E, Float),
100    SK_MEMBER_PROPERTY(LN10, Float),
101    SK_MEMBER_PROPERTY(LN2, Float),
102    SK_MEMBER_PROPERTY(LOG10E, Float),
103    SK_MEMBER_PROPERTY(LOG2E, Float),
104    SK_MEMBER_PROPERTY(PI, Float),
105    SK_MEMBER_PROPERTY(SQRT1_2, Float),
106    SK_MEMBER_PROPERTY(SQRT2, Float),
107    SK_MEMBER_FUNCTION(abs, Float),
108    SK_MEMBER_FUNCTION(acos, Float),
109    SK_MEMBER_FUNCTION(asin, Float),
110    SK_MEMBER_FUNCTION(atan, Float),
111    SK_MEMBER_FUNCTION(atan2, Float),
112    SK_MEMBER_FUNCTION(ceil, Float),
113    SK_MEMBER_FUNCTION(cos, Float),
114    SK_MEMBER_FUNCTION(exp, Float),
115    SK_MEMBER_FUNCTION(floor, Float),
116    SK_MEMBER_FUNCTION(log, Float),
117    SK_MEMBER_FUNCTION(max, Float),
118    SK_MEMBER_FUNCTION(min, Float),
119    SK_MEMBER_FUNCTION(pow, Float),
120    SK_MEMBER_FUNCTION(random, Float),
121    SK_MEMBER_FUNCTION(round, Float),
122    SK_MEMBER_FUNCTION(sin, Float),
123    SK_MEMBER_FUNCTION(sqrt, Float),
124    SK_MEMBER_FUNCTION(tan, Float)
125};
126
127#endif
128
129DEFINE_GET_MEMBER(SkDisplayMath);
130
131void SkDisplayMath::executeFunction(SkDisplayable* target, int index,
132        SkTDArray<SkScriptValue>& parameters, SkDisplayTypes type,
133        SkScriptValue* scriptValue) {
134    if (scriptValue == NULL)
135        return;
136    SkASSERT(target == this);
137    SkScriptValue* array = parameters.begin();
138    SkScriptValue* end = parameters.end();
139    SkScalar input = parameters[0].fOperand.fScalar;
140    SkScalar scalarResult;
141    switch (index) {
142        case SK_FUNCTION(abs):
143            scalarResult = SkScalarAbs(input);
144            break;
145        case SK_FUNCTION(acos):
146            scalarResult = SkScalarACos(input);
147            break;
148        case SK_FUNCTION(asin):
149            scalarResult = SkScalarASin(input);
150            break;
151        case SK_FUNCTION(atan):
152            scalarResult = SkScalarATan2(input, SK_Scalar1);
153            break;
154        case SK_FUNCTION(atan2):
155            scalarResult = SkScalarATan2(input, parameters[1].fOperand.fScalar);
156            break;
157        case SK_FUNCTION(ceil):
158            scalarResult = SkScalarCeilToScalar(input);
159            break;
160        case SK_FUNCTION(cos):
161            scalarResult = SkScalarCos(input);
162            break;
163        case SK_FUNCTION(exp):
164            scalarResult = SkScalarExp(input);
165            break;
166        case SK_FUNCTION(floor):
167            scalarResult = SkScalarFloorToScalar(input);
168            break;
169        case SK_FUNCTION(log):
170            scalarResult = SkScalarLog(input);
171            break;
172        case SK_FUNCTION(max):
173            scalarResult = -SK_ScalarMax;
174            while (array < end) {
175                scalarResult = SkMaxScalar(scalarResult, array->fOperand.fScalar);
176                array++;
177            }
178            break;
179        case SK_FUNCTION(min):
180            scalarResult = SK_ScalarMax;
181            while (array < end) {
182                scalarResult = SkMinScalar(scalarResult, array->fOperand.fScalar);
183                array++;
184            }
185            break;
186        case SK_FUNCTION(pow):
187            // not the greatest -- but use x^y = e^(y * ln(x))
188            scalarResult = SkScalarLog(input);
189            scalarResult = SkScalarMul(parameters[1].fOperand.fScalar, scalarResult);
190            scalarResult = SkScalarExp(scalarResult);
191            break;
192        case SK_FUNCTION(random):
193            scalarResult = fRandom.nextUScalar1();
194            break;
195        case SK_FUNCTION(round):
196            scalarResult = SkScalarRoundToScalar(input);
197            break;
198        case SK_FUNCTION(sin):
199            scalarResult = SkScalarSin(input);
200            break;
201        case SK_FUNCTION(sqrt): {
202            SkASSERT(parameters.count() == 1);
203            SkASSERT(type == SkType_Float);
204            scalarResult = SkScalarSqrt(input);
205            } break;
206        case SK_FUNCTION(tan):
207            scalarResult = SkScalarTan(input);
208            break;
209        default:
210            SkASSERT(0);
211            scalarResult = SK_ScalarNaN;
212    }
213    scriptValue->fOperand.fScalar = scalarResult;
214    scriptValue->fType = SkType_Float;
215}
216
217const SkFunctionParamType* SkDisplayMath::getFunctionsParameters() {
218    return fFunctionParameters;
219}
220
221bool SkDisplayMath::getProperty(int index, SkScriptValue* value) const {
222    if ((unsigned)index < SK_ARRAY_COUNT(gConstants)) {
223        value->fOperand.fScalar = gConstants[index];
224        value->fType = SkType_Float;
225        return true;
226    }
227    SkASSERT(0);
228    return false;
229}
230