blob: ac2ba8bf249fb94c2924af1197aa0c3d094a2e14 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
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[] = {
reed@android.com8a1c16f2008-12-17 15:59:43 +000024 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
rmistry@google.comd6176b02012-08-23 18:14:13 +000031 1.414213562f // SQRT2
reed@android.com8a1c16f2008-12-17 15:59:43 +000032};
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
rmistry@google.comd6176b02012-08-23 18:14:13 +0000131void SkDisplayMath::executeFunction(SkDisplayable* target, int index,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000132 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):
rmistry@google.comd6176b02012-08-23 18:14:13 +0000143 scalarResult = SkScalarAbs(input);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000144 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):
rmistry@google.comd6176b02012-08-23 18:14:13 +0000158 scalarResult = SkIntToScalar(SkScalarCeil(input));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159 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):
rmistry@google.comd6176b02012-08-23 18:14:13 +0000167 scalarResult = SkIntToScalar(SkScalarFloor(input));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000168 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):
rmistry@google.comd6176b02012-08-23 18:14:13 +0000196 scalarResult = SkIntToScalar(SkScalarRound(input));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000197 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);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000204 scalarResult = SkScalarSqrt(input);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 } 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}