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 
12 enum 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 
23 const 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 
34 enum 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 
55 const 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 
98 const 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 
129 DEFINE_GET_MEMBER(SkDisplayMath);
130 
executeFunction(SkDisplayable * target,int index,SkTDArray<SkScriptValue> & parameters,SkDisplayTypes type,SkScriptValue * scriptValue)131 void SkDisplayMath::executeFunction(SkDisplayable* target, int index,
132         SkTDArray<SkScriptValue>& parameters, SkDisplayTypes type,
133         SkScriptValue* scriptValue) {
134     if (scriptValue == nullptr)
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 
getFunctionsParameters()217 const SkFunctionParamType* SkDisplayMath::getFunctionsParameters() {
218     return fFunctionParameters;
219 }
220 
getProperty(int index,SkScriptValue * value) const221 bool 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