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