Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: src/core/SkMatrix.cpp

Issue 150493002: remove unnecessary SkScalar macros (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkMatrix.h" 8 #include "SkMatrix.h"
9 #include "SkFloatBits.h" 9 #include "SkFloatBits.h"
10 #include "SkOnce.h" 10 #include "SkOnce.h"
11 #include "SkString.h" 11 #include "SkString.h"
12 12
13 #define kMatrix22Elem SK_Scalar1 13 // In a few places, we performed the following
14 // a * b + c * d + e
15 // as
16 // a * b + (c * d + e)
17 //
18 // sdot and scross are indended to capture these compound operations into a
19 // function, with an eye toward considering upscaling the intermediates to
20 // doubles for more precision (as we do in concat and invert).
21 //
22 // However, these few lines that performed the last add before the "dot", cause
23 // tiny image differences, so we guard that change until we see the impact on
24 // chrome's layouttests.
25 //
26 #define SK_LEGACY_MATRIX_MATH_ORDER
14 27
15 static inline float SkDoubleToFloat(double x) { 28 static inline float SkDoubleToFloat(double x) {
16 return static_cast<float>(x); 29 return static_cast<float>(x);
17 } 30 }
18 31
19 /* [scale-x skew-x trans-x] [X] [X'] 32 /* [scale-x skew-x trans-x] [X] [X']
20 [skew-y scale-y trans-y] * [Y] = [Y'] 33 [skew-y scale-y trans-y] * [Y] = [Y']
21 [persp-0 persp-1 persp-2] [1] [1 ] 34 [persp-0 persp-1 persp-2] [1] [1 ]
22 */ 35 */
23 36
24 void SkMatrix::reset() { 37 void SkMatrix::reset() {
25 fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; 38 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1;
26 fMat[kMSkewX] = fMat[kMSkewY] = 39 fMat[kMSkewX] = fMat[kMSkewY] =
27 fMat[kMTransX] = fMat[kMTransY] = 40 fMat[kMTransX] = fMat[kMTransY] =
28 fMat[kMPersp0] = fMat[kMPersp1] = 0; 41 fMat[kMPersp0] = fMat[kMPersp1] = 0;
29 fMat[kMPersp2] = kMatrix22Elem;
30 42
31 this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask); 43 this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask);
32 } 44 }
33 45
34 // this guy aligns with the masks, so we can compute a mask from a varaible 0/1 46 // this guy aligns with the masks, so we can compute a mask from a varaible 0/1
35 enum { 47 enum {
36 kTranslate_Shift, 48 kTranslate_Shift,
37 kScale_Shift, 49 kScale_Shift,
38 kAffine_Shift, 50 kAffine_Shift,
39 kPerspective_Shift, 51 kPerspective_Shift,
40 kRectStaysRect_Shift 52 kRectStaysRect_Shift
41 }; 53 };
42 54
43 static const int32_t kScalar1Int = 0x3f800000; 55 static const int32_t kScalar1Int = 0x3f800000;
44 56
45 uint8_t SkMatrix::computePerspectiveTypeMask() const { 57 uint8_t SkMatrix::computePerspectiveTypeMask() const {
46 // Benchmarking suggests that replacing this set of SkScalarAs2sCompliment 58 // Benchmarking suggests that replacing this set of SkScalarAs2sCompliment
47 // is a win, but replacing those below is not. We don't yet understand 59 // is a win, but replacing those below is not. We don't yet understand
48 // that result. 60 // that result.
49 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || 61 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || fMat[kMPersp2] != 1) {
50 fMat[kMPersp2] != kMatrix22Elem) {
51 // If this is a perspective transform, we return true for all other 62 // If this is a perspective transform, we return true for all other
52 // transform flags - this does not disable any optimizations, respects 63 // transform flags - this does not disable any optimizations, respects
53 // the rule that the type mask must be conservative, and speeds up 64 // the rule that the type mask must be conservative, and speeds up
54 // type mask computation. 65 // type mask computation.
55 return SkToU8(kORableMasks); 66 return SkToU8(kORableMasks);
56 } 67 }
57 68
58 return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask); 69 return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask);
59 } 70 }
60 71
61 uint8_t SkMatrix::computeTypeMask() const { 72 uint8_t SkMatrix::computeTypeMask() const {
62 unsigned mask = 0; 73 unsigned mask = 0;
63 74
64 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || 75 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || fMat[kMPersp2] != 1) {
65 fMat[kMPersp2] != kMatrix22Elem) {
66 // Once it is determined that that this is a perspective transform, 76 // Once it is determined that that this is a perspective transform,
67 // all other flags are moot as far as optimizations are concerned. 77 // all other flags are moot as far as optimizations are concerned.
68 return SkToU8(kORableMasks); 78 return SkToU8(kORableMasks);
69 } 79 }
70 80
71 if (fMat[kMTransX] != 0 || fMat[kMTransY] != 0) { 81 if (fMat[kMTransX] != 0 || fMat[kMTransY] != 0) {
72 mask |= kTranslate_Mask; 82 mask |= kTranslate_Mask;
73 } 83 }
74 84
75 int m00 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleX]); 85 int m00 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleX]);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 vec[0].set(mx, sx); 212 vec[0].set(mx, sx);
203 vec[1].set(sy, my); 213 vec[1].set(sy, my);
204 214
205 return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && 215 return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) &&
206 SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), 216 SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(),
207 SkScalarSquare(tol)); 217 SkScalarSquare(tol));
208 } 218 }
209 219
210 /////////////////////////////////////////////////////////////////////////////// 220 ///////////////////////////////////////////////////////////////////////////////
211 221
222 static inline SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d) {
223 return a * b + c * d;
224 }
225
226 static inline SkScalar sdot3(SkScalar a, SkScalar b, SkScalar c, SkScalar d,
mtklein 2014/01/30 19:14:55 Don't think calling this sdot would hurt if you're
reed1 2014/01/30 20:53:48 Done.
227 SkScalar e, SkScalar f) {
228 return a * b + c * d + e * f;
229 }
230
231 static inline SkScalar scross(SkScalar a, SkScalar b, SkScalar c, SkScalar d) {
232 return a * b - c * d;
233 }
234
212 void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) { 235 void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {
213 if (dx || dy) { 236 if (dx || dy) {
214 fMat[kMTransX] = dx; 237 fMat[kMTransX] = dx;
215 fMat[kMTransY] = dy; 238 fMat[kMTransY] = dy;
216 239
217 fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; 240 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1;
218 fMat[kMSkewX] = fMat[kMSkewY] = 241 fMat[kMSkewX] = fMat[kMSkewY] =
219 fMat[kMPersp0] = fMat[kMPersp1] = 0; 242 fMat[kMPersp0] = fMat[kMPersp1] = 0;
220 fMat[kMPersp2] = kMatrix22Elem;
221 243
222 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); 244 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask);
223 } else { 245 } else {
224 this->reset(); 246 this->reset();
225 } 247 }
226 } 248 }
227 249
228 bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { 250 bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {
229 if (this->hasPerspective()) { 251 if (this->hasPerspective()) {
230 SkMatrix m; 252 SkMatrix m;
231 m.setTranslate(dx, dy); 253 m.setTranslate(dx, dy);
232 return this->preConcat(m); 254 return this->preConcat(m);
233 } 255 }
234 256
235 if (dx || dy) { 257 if (dx || dy) {
236 fMat[kMTransX] += SkScalarMul(fMat[kMScaleX], dx) + 258 fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy);
237 SkScalarMul(fMat[kMSkewX], dy); 259 fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy);
238 fMat[kMTransY] += SkScalarMul(fMat[kMSkewY], dx) +
239 SkScalarMul(fMat[kMScaleY], dy);
240 260
241 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 261 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
242 } 262 }
243 return true; 263 return true;
244 } 264 }
245 265
246 bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { 266 bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) {
247 if (this->hasPerspective()) { 267 if (this->hasPerspective()) {
248 SkMatrix m; 268 SkMatrix m;
249 m.setTranslate(dx, dy); 269 m.setTranslate(dx, dy);
250 return this->postConcat(m); 270 return this->postConcat(m);
251 } 271 }
252 272
253 if (dx || dy) { 273 if (dx || dy) {
254 fMat[kMTransX] += dx; 274 fMat[kMTransX] += dx;
255 fMat[kMTransY] += dy; 275 fMat[kMTransY] += dy;
256 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 276 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
257 } 277 }
258 return true; 278 return true;
259 } 279 }
260 280
261 /////////////////////////////////////////////////////////////////////////////// 281 ///////////////////////////////////////////////////////////////////////////////
262 282
263 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 283 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
264 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 284 if (1 == sx && 1 == sy) {
265 this->reset(); 285 this->reset();
266 } else { 286 } else {
267 fMat[kMScaleX] = sx; 287 fMat[kMScaleX] = sx;
268 fMat[kMScaleY] = sy; 288 fMat[kMScaleY] = sy;
269 fMat[kMTransX] = px - SkScalarMul(sx, px); 289 fMat[kMTransX] = px - sx * px;
270 fMat[kMTransY] = py - SkScalarMul(sy, py); 290 fMat[kMTransY] = py - sy * py;
271 fMat[kMPersp2] = kMatrix22Elem; 291 fMat[kMPersp2] = 1;
272 292
273 fMat[kMSkewX] = fMat[kMSkewY] = 293 fMat[kMSkewX] = fMat[kMSkewY] =
274 fMat[kMPersp0] = fMat[kMPersp1] = 0; 294 fMat[kMPersp0] = fMat[kMPersp1] = 0;
275 295
276 this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask); 296 this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask);
277 } 297 }
278 } 298 }
279 299
280 void SkMatrix::setScale(SkScalar sx, SkScalar sy) { 300 void SkMatrix::setScale(SkScalar sx, SkScalar sy) {
281 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 301 if (1 == sx && 1 == sy) {
282 this->reset(); 302 this->reset();
283 } else { 303 } else {
284 fMat[kMScaleX] = sx; 304 fMat[kMScaleX] = sx;
285 fMat[kMScaleY] = sy; 305 fMat[kMScaleY] = sy;
286 fMat[kMPersp2] = kMatrix22Elem; 306 fMat[kMPersp2] = 1;
287 307
288 fMat[kMTransX] = fMat[kMTransY] = 308 fMat[kMTransX] = fMat[kMTransY] =
289 fMat[kMSkewX] = fMat[kMSkewY] = 309 fMat[kMSkewX] = fMat[kMSkewY] =
290 fMat[kMPersp0] = fMat[kMPersp1] = 0; 310 fMat[kMPersp0] = fMat[kMPersp1] = 0;
291 311
292 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); 312 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask);
293 } 313 }
294 } 314 }
295 315
296 bool SkMatrix::setIDiv(int divx, int divy) { 316 bool SkMatrix::setIDiv(int divx, int divy) {
297 if (!divx || !divy) { 317 if (!divx || !divy) {
298 return false; 318 return false;
299 } 319 }
300 this->setScale(SK_Scalar1 / divx, SK_Scalar1 / divy); 320 this->setScale(SkScalarInvert(divx), SkScalarInvert(divy));
caryclark 2014/01/30 21:19:10 This makes me think that SkScalarInvert is special
reed1 2014/01/30 21:38:52 1. I always imaging that we could somehow be faste
301 return true; 321 return true;
302 } 322 }
303 323
304 bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 324 bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
305 SkMatrix m; 325 SkMatrix m;
306 m.setScale(sx, sy, px, py); 326 m.setScale(sx, sy, px, py);
307 return this->preConcat(m); 327 return this->preConcat(m);
308 } 328 }
309 329
310 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { 330 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) {
311 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 331 if (1 == sx && 1 == sy) {
312 return true; 332 return true;
313 } 333 }
314 334
315 // the assumption is that these multiplies are very cheap, and that 335 // the assumption is that these multiplies are very cheap, and that
316 // a full concat and/or just computing the matrix type is more expensive. 336 // a full concat and/or just computing the matrix type is more expensive.
317 // Also, the fixed-point case checks for overflow, but the float doesn't, 337 // Also, the fixed-point case checks for overflow, but the float doesn't,
318 // so we can get away with these blind multiplies. 338 // so we can get away with these blind multiplies.
319 339
320 fMat[kMScaleX] = SkScalarMul(fMat[kMScaleX], sx); 340 fMat[kMScaleX] *= sx;
321 fMat[kMSkewY] = SkScalarMul(fMat[kMSkewY], sx); 341 fMat[kMSkewY] *= sx;
322 fMat[kMPersp0] = SkScalarMul(fMat[kMPersp0], sx); 342 fMat[kMPersp0] *= sx;
323 343
324 fMat[kMSkewX] = SkScalarMul(fMat[kMSkewX], sy); 344 fMat[kMSkewX] *= sy;
325 fMat[kMScaleY] = SkScalarMul(fMat[kMScaleY], sy); 345 fMat[kMScaleY] *= sy;
326 fMat[kMPersp1] = SkScalarMul(fMat[kMPersp1], sy); 346 fMat[kMPersp1] *= sy;
327 347
328 this->orTypeMask(kScale_Mask); 348 this->orTypeMask(kScale_Mask);
329 return true; 349 return true;
330 } 350 }
331 351
332 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 352 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
333 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 353 if (1 == sx && 1 == sy) {
334 return true; 354 return true;
335 } 355 }
336 SkMatrix m; 356 SkMatrix m;
337 m.setScale(sx, sy, px, py); 357 m.setScale(sx, sy, px, py);
338 return this->postConcat(m); 358 return this->postConcat(m);
339 } 359 }
340 360
341 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { 361 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) {
342 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 362 if (1 == sx && 1 == sy) {
343 return true; 363 return true;
344 } 364 }
345 SkMatrix m; 365 SkMatrix m;
346 m.setScale(sx, sy); 366 m.setScale(sx, sy);
347 return this->postConcat(m); 367 return this->postConcat(m);
348 } 368 }
349 369
350 // this guy perhaps can go away, if we have a fract/high-precision way to 370 // this guy perhaps can go away, if we have a fract/high-precision way to
351 // scale matrices 371 // scale matrices
352 bool SkMatrix::postIDiv(int divx, int divy) { 372 bool SkMatrix::postIDiv(int divx, int divy) {
(...skipping 13 matching lines...) Expand all
366 fMat[kMTransY] *= invY; 386 fMat[kMTransY] *= invY;
367 387
368 this->setTypeMask(kUnknown_Mask); 388 this->setTypeMask(kUnknown_Mask);
369 return true; 389 return true;
370 } 390 }
371 391
372 //////////////////////////////////////////////////////////////////////////////// //// 392 //////////////////////////////////////////////////////////////////////////////// ////
373 393
374 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, 394 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV,
375 SkScalar px, SkScalar py) { 395 SkScalar px, SkScalar py) {
376 const SkScalar oneMinusCosV = SK_Scalar1 - cosV; 396 const SkScalar oneMinusCosV = 1 - cosV;
377 397
378 fMat[kMScaleX] = cosV; 398 fMat[kMScaleX] = cosV;
379 fMat[kMSkewX] = -sinV; 399 fMat[kMSkewX] = -sinV;
380 fMat[kMTransX] = SkScalarMul(sinV, py) + SkScalarMul(oneMinusCosV, px); 400 fMat[kMTransX] = sdot(sinV, py, oneMinusCosV, px);
381 401
382 fMat[kMSkewY] = sinV; 402 fMat[kMSkewY] = sinV;
383 fMat[kMScaleY] = cosV; 403 fMat[kMScaleY] = cosV;
384 fMat[kMTransY] = SkScalarMul(-sinV, px) + SkScalarMul(oneMinusCosV, py); 404 fMat[kMTransY] = sdot(-sinV, px, oneMinusCosV, py);
385 405
386 fMat[kMPersp0] = fMat[kMPersp1] = 0; 406 fMat[kMPersp0] = fMat[kMPersp1] = 0;
387 fMat[kMPersp2] = kMatrix22Elem; 407 fMat[kMPersp2] = 1;
388 408
389 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 409 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
390 } 410 }
391 411
392 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) { 412 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) {
393 fMat[kMScaleX] = cosV; 413 fMat[kMScaleX] = cosV;
394 fMat[kMSkewX] = -sinV; 414 fMat[kMSkewX] = -sinV;
395 fMat[kMTransX] = 0; 415 fMat[kMTransX] = 0;
396 416
397 fMat[kMSkewY] = sinV; 417 fMat[kMSkewY] = sinV;
398 fMat[kMScaleY] = cosV; 418 fMat[kMScaleY] = cosV;
399 fMat[kMTransY] = 0; 419 fMat[kMTransY] = 0;
400 420
401 fMat[kMPersp0] = fMat[kMPersp1] = 0; 421 fMat[kMPersp0] = fMat[kMPersp1] = 0;
402 fMat[kMPersp2] = kMatrix22Elem; 422 fMat[kMPersp2] = 1;
403 423
404 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 424 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
405 } 425 }
406 426
407 void SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) { 427 void SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) {
408 SkScalar sinV, cosV; 428 SkScalar sinV, cosV;
409 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); 429 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV);
410 this->setSinCos(sinV, cosV, px, py); 430 this->setSinCos(sinV, cosV, px, py);
411 } 431 }
412 432
(...skipping 23 matching lines...) Expand all
436 456
437 bool SkMatrix::postRotate(SkScalar degrees) { 457 bool SkMatrix::postRotate(SkScalar degrees) {
438 SkMatrix m; 458 SkMatrix m;
439 m.setRotate(degrees); 459 m.setRotate(degrees);
440 return this->postConcat(m); 460 return this->postConcat(m);
441 } 461 }
442 462
443 //////////////////////////////////////////////////////////////////////////////// //// 463 //////////////////////////////////////////////////////////////////////////////// ////
444 464
445 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 465 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
446 fMat[kMScaleX] = SK_Scalar1; 466 fMat[kMScaleX] = 1;
447 fMat[kMSkewX] = sx; 467 fMat[kMSkewX] = sx;
448 fMat[kMTransX] = SkScalarMul(-sx, py); 468 fMat[kMTransX] = -sx * py;
449 469
450 fMat[kMSkewY] = sy; 470 fMat[kMSkewY] = sy;
451 fMat[kMScaleY] = SK_Scalar1; 471 fMat[kMScaleY] = 1;
452 fMat[kMTransY] = SkScalarMul(-sy, px); 472 fMat[kMTransY] = -sy * px;
453 473
454 fMat[kMPersp0] = fMat[kMPersp1] = 0; 474 fMat[kMPersp0] = fMat[kMPersp1] = 0;
455 fMat[kMPersp2] = kMatrix22Elem; 475 fMat[kMPersp2] = 1;
mtklein 2014/01/30 19:14:55 Is there no value in keeping a name on this to ind
reed1 2014/01/30 20:53:48 The perspective column used to be special, when we
456 476
457 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 477 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
458 } 478 }
459 479
460 void SkMatrix::setSkew(SkScalar sx, SkScalar sy) { 480 void SkMatrix::setSkew(SkScalar sx, SkScalar sy) {
461 fMat[kMScaleX] = SK_Scalar1; 481 fMat[kMScaleX] = 1;
462 fMat[kMSkewX] = sx; 482 fMat[kMSkewX] = sx;
463 fMat[kMTransX] = 0; 483 fMat[kMTransX] = 0;
464 484
465 fMat[kMSkewY] = sy; 485 fMat[kMSkewY] = sy;
466 fMat[kMScaleY] = SK_Scalar1; 486 fMat[kMScaleY] = 1;
467 fMat[kMTransY] = 0; 487 fMat[kMTransY] = 0;
468 488
469 fMat[kMPersp0] = fMat[kMPersp1] = 0; 489 fMat[kMPersp0] = fMat[kMPersp1] = 0;
470 fMat[kMPersp2] = kMatrix22Elem; 490 fMat[kMPersp2] = 1;
471 491
472 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 492 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
473 } 493 }
474 494
475 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 495 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
476 SkMatrix m; 496 SkMatrix m;
477 m.setSkew(sx, sy, px, py); 497 m.setSkew(sx, sy, px, py);
478 return this->preConcat(m); 498 return this->preConcat(m);
479 } 499 }
480 500
(...skipping 22 matching lines...) Expand all
503 { 523 {
504 if (src.isEmpty()) { 524 if (src.isEmpty()) {
505 this->reset(); 525 this->reset();
506 return false; 526 return false;
507 } 527 }
508 528
509 if (dst.isEmpty()) { 529 if (dst.isEmpty()) {
510 sk_bzero(fMat, 8 * sizeof(SkScalar)); 530 sk_bzero(fMat, 8 * sizeof(SkScalar));
511 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); 531 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask);
512 } else { 532 } else {
513 SkScalar tx, sx = SkScalarDiv(dst.width(), src.width()); 533 SkScalar tx, sx = dst.width() / src.width();
514 SkScalar ty, sy = SkScalarDiv(dst.height(), src.height()); 534 SkScalar ty, sy = dst.height() / src.height();
515 bool xLarger = false; 535 bool xLarger = false;
516 536
517 if (align != kFill_ScaleToFit) { 537 if (align != kFill_ScaleToFit) {
518 if (sx > sy) { 538 if (sx > sy) {
519 xLarger = true; 539 xLarger = true;
520 sx = sy; 540 sx = sy;
521 } else { 541 } else {
522 sy = sx; 542 sy = sx;
523 } 543 }
524 } 544 }
525 545
526 tx = dst.fLeft - SkScalarMul(src.fLeft, sx); 546 tx = dst.fLeft - src.fLeft * sx;
527 ty = dst.fTop - SkScalarMul(src.fTop, sy); 547 ty = dst.fTop - src.fTop * sy;
528 if (align == kCenter_ScaleToFit || align == kEnd_ScaleToFit) { 548 if (align == kCenter_ScaleToFit || align == kEnd_ScaleToFit) {
529 SkScalar diff; 549 SkScalar diff;
530 550
531 if (xLarger) { 551 if (xLarger) {
532 diff = dst.width() - SkScalarMul(src.width(), sy); 552 diff = dst.width() - src.width() * sy;
533 } else { 553 } else {
534 diff = dst.height() - SkScalarMul(src.height(), sy); 554 diff = dst.height() - src.height() * sy;
535 } 555 }
536 556
537 if (align == kCenter_ScaleToFit) { 557 if (align == kCenter_ScaleToFit) {
538 diff = SkScalarHalf(diff); 558 diff = SkScalarHalf(diff);
539 } 559 }
540 560
541 if (xLarger) { 561 if (xLarger) {
542 tx += diff; 562 tx += diff;
543 } else { 563 } else {
544 ty += diff; 564 ty += diff;
545 } 565 }
546 } 566 }
547 567
548 fMat[kMScaleX] = sx; 568 fMat[kMScaleX] = sx;
549 fMat[kMScaleY] = sy; 569 fMat[kMScaleY] = sy;
550 fMat[kMTransX] = tx; 570 fMat[kMTransX] = tx;
551 fMat[kMTransY] = ty; 571 fMat[kMTransY] = ty;
552 fMat[kMSkewX] = fMat[kMSkewY] = 572 fMat[kMSkewX] = fMat[kMSkewY] =
553 fMat[kMPersp0] = fMat[kMPersp1] = 0; 573 fMat[kMPersp0] = fMat[kMPersp1] = 0;
554 574
555 unsigned mask = kRectStaysRect_Mask; 575 unsigned mask = kRectStaysRect_Mask;
556 if (sx != SK_Scalar1 || sy != SK_Scalar1) { 576 if (sx != 1 || sy != 1) {
557 mask |= kScale_Mask; 577 mask |= kScale_Mask;
558 } 578 }
559 if (tx || ty) { 579 if (tx || ty) {
560 mask |= kTranslate_Mask; 580 mask |= kTranslate_Mask;
561 } 581 }
562 this->setTypeMask(mask); 582 this->setTypeMask(mask);
563 } 583 }
564 // shared cleanup 584 // shared cleanup
565 fMat[kMPersp2] = kMatrix22Elem; 585 fMat[kMPersp2] = 1;
566 return true; 586 return true;
567 } 587 }
568 588
569 /////////////////////////////////////////////////////////////////////////////// 589 ///////////////////////////////////////////////////////////////////////////////
570 590
571 static inline int fixmuladdmul(float a, float b, float c, float d, 591 static inline int fixmuladdmul(float a, float b, float c, float d,
572 float* result) { 592 float* result) {
573 *result = SkDoubleToFloat((double)a * b + (double)c * d); 593 *result = SkDoubleToFloat((double)a * b + (double)c * d);
574 return true; 594 return true;
575 } 595 }
576 596
577 static inline bool rowcol3(const float row[], const float col[], 597 static inline bool rowcol3(const float row[], const float col[],
578 float* result) { 598 float* result) {
579 *result = row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; 599 *result = row[0] * col[0] + row[1] * col[3] + row[2] * col[6];
580 return true; 600 return true;
581 } 601 }
582 602
583 static inline int negifaddoverflows(float& result, float a, float b) { 603 static inline int negifaddoverflows(float& result, float a, float b) {
584 result = a + b; 604 result = a + b;
585 return 0; 605 return 0;
586 } 606 }
587 607
588 static void normalize_perspective(SkScalar mat[9]) { 608 static void normalize_perspective(SkScalar mat[9]) {
589 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > kMatrix22Elem) { 609 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) {
590 for (int i = 0; i < 9; i++) 610 for (int i = 0; i < 9; i++)
591 mat[i] = SkScalarHalf(mat[i]); 611 mat[i] = SkScalarHalf(mat[i]);
592 } 612 }
593 } 613 }
594 614
595 bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { 615 bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
596 TypeMask aType = a.getPerspectiveTypeMaskOnly(); 616 TypeMask aType = a.getPerspectiveTypeMaskOnly();
597 TypeMask bType = b.getPerspectiveTypeMaskOnly(); 617 TypeMask bType = b.getPerspectiveTypeMaskOnly();
598 618
599 if (a.isTriviallyIdentity()) { 619 if (a.isTriviallyIdentity()) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX], 685 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX],
666 a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) { 686 a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) {
667 return false; 687 return false;
668 } 688 }
669 if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY], 689 if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY],
670 a.fMat[kMTransY]) < 0) { 690 a.fMat[kMTransY]) < 0) {
671 return false; 691 return false;
672 } 692 }
673 693
674 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; 694 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0;
675 tmp.fMat[kMPersp2] = kMatrix22Elem; 695 tmp.fMat[kMPersp2] = 1;
676 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); 696 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType());
677 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); 697 //SkASSERT(!(tmp.getType() & kPerspective_Mask));
678 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 698 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
679 } 699 }
680 *this = tmp; 700 *this = tmp;
681 } 701 }
682 return true; 702 return true;
683 } 703 }
684 704
685 bool SkMatrix::preConcat(const SkMatrix& mat) { 705 bool SkMatrix::preConcat(const SkMatrix& mat) {
686 // check for identity first, so we don't do a needless copy of ourselves 706 // check for identity first, so we don't do a needless copy of ourselves
687 // to ourselves inside setConcat() 707 // to ourselves inside setConcat()
688 return mat.isIdentity() || this->setConcat(*this, mat); 708 return mat.isIdentity() || this->setConcat(*this, mat);
689 } 709 }
690 710
691 bool SkMatrix::postConcat(const SkMatrix& mat) { 711 bool SkMatrix::postConcat(const SkMatrix& mat) {
692 // check for identity first, so we don't do a needless copy of ourselves 712 // check for identity first, so we don't do a needless copy of ourselves
693 // to ourselves inside setConcat() 713 // to ourselves inside setConcat()
694 return mat.isIdentity() || this->setConcat(mat, *this); 714 return mat.isIdentity() || this->setConcat(mat, *this);
695 } 715 }
696 716
697 /////////////////////////////////////////////////////////////////////////////// 717 ///////////////////////////////////////////////////////////////////////////////
698 718
699 /* Matrix inversion is very expensive, but also the place where keeping 719 /* Matrix inversion is very expensive, but also the place where keeping
700 precision may be most important (here and matrix concat). Hence to avoid 720 precision may be most important (here and matrix concat). Hence to avoid
701 bitmap blitting artifacts when walking the inverse, we use doubles for 721 bitmap blitting artifacts when walking the inverse, we use doubles for
702 the intermediate math, even though we know that is more expensive. 722 the intermediate math, even though we know that is more expensive.
703 */ 723 */
704 724
705 typedef double SkDetScalar; 725 static inline double dcross(double a, double b, double c, double d) {
706 #define SkPerspMul(a, b) SkScalarMul(a, b) 726 return a * b - c * d;
707 #define SkScalarMulShift(a, b, s) SkDoubleToFloat((a) * (b)) 727 }
708 static double sk_inv_determinant(const float mat[9], int isPerspective, 728
709 int* /* (only used in Fixed case) */) { 729 static double sk_inv_determinant(const float mat[9], int isPerspective) {
710 double det; 730 double det;
711 731
712 if (isPerspective) { 732 if (isPerspective) {
713 det = mat[SkMatrix::kMScaleX] * ((double)mat[SkMatrix::kMScaleY] * mat [SkMatrix::kMPersp2] - (double)mat[SkMatrix::kMTransY] * mat[SkMatrix::kMPersp1] ) + 733 det = mat[SkMatrix::kMScaleX] * dcross(mat[SkMatrix::kMScaleY], mat[SkMa trix::kMPersp2], mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp1]) +
mtklein 2014/01/30 19:14:55 These lines are pretty hard to parse (they were be
reed1 2014/01/30 20:53:48 Done.
caryclark 2014/01/30 21:19:10 Or, if this was a member of SkMatrix, it would be
reed1 2014/01/30 21:38:52 My rewrite address the 100 chars, but I agree that
714 mat[SkMatrix::kMSkewX] * ((double)mat[SkMatrix::kMTransY] * mat[ SkMatrix::kMPersp0] - (double)mat[SkMatrix::kMSkewY] * mat[SkMatrix::kMPersp2]) + 734 mat[SkMatrix::kMSkewX] * dcross(mat[SkMatrix::kMTransY], mat[SkMa trix::kMPersp0], mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp2]) +
715 mat[SkMatrix::kMTransX] * ((double)mat[SkMatrix::kMSkewY] * mat[ SkMatrix::kMPersp1] - (double)mat[SkMatrix::kMScaleY] * mat[SkMatrix::kMPersp0]) ; 735 mat[SkMatrix::kMTransX] * dcross(mat[SkMatrix::kMSkewY], mat[SkMa trix::kMPersp1], mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp0]);
716 } else { 736 } else {
717 det = (double)mat[SkMatrix::kMScaleX] * mat[SkMatrix::kMScaleY] - (dou ble)mat[SkMatrix::kMSkewX] * mat[SkMatrix::kMSkewY]; 737 det = dcross(mat[SkMatrix::kMScaleX], mat[SkMatrix::kMScaleY], mat[SkMa trix::kMSkewX], mat[SkMatrix::kMSkewY]);
718 } 738 }
719 739
720 // Since the determinant is on the order of the cube of the matrix members, 740 // Since the determinant is on the order of the cube of the matrix members,
721 // compare to the cube of the default nearly-zero constant (although an 741 // compare to the cube of the default nearly-zero constant (although an
722 // estimate of the condition number would be better if it wasn't so expensiv e). 742 // estimate of the condition number would be better if it wasn't so expensiv e).
723 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero * SK_ScalarNearlyZero)) { 743 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero * SK_ScalarNearlyZero)) {
724 return 0; 744 return 0;
725 } 745 }
726 return 1.0 / det; 746 return 1.0 / det;
727 } 747 }
728 // we declar a,b,c,d to all be doubles, because we want to perform 748 // we declar a,b,c,d to all be doubles, because we want to perform
729 // double-precision muls and subtract, even though the original values are 749 // double-precision muls and subtract, even though the original values are
730 // from the matrix, which are floats. 750 // from the matrix, which are floats.
731 static float inline mul_diff_scale(double a, double b, double c, double d, 751 static SkScalar inline mul_diff_scale(double a, double b, double c, double d,
mtklein 2014/01/30 19:14:55 mul_diff_scale might be better named dcross_scale?
reed1 2014/01/30 20:53:48 That guy is now unused. deleting.
732 double scale) { 752 double scale) {
733 return SkDoubleToFloat((a * b - c * d) * scale); 753 return SkDoubleToScalar(dcross(a, b, c, d) * scale);
734 } 754 }
735 755
736 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { 756 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) {
737 affine[kAScaleX] = SK_Scalar1; 757 affine[kAScaleX] = 1;
738 affine[kASkewY] = 0; 758 affine[kASkewY] = 0;
739 affine[kASkewX] = 0; 759 affine[kASkewX] = 0;
740 affine[kAScaleY] = SK_Scalar1; 760 affine[kAScaleY] = 1;
741 affine[kATransX] = 0; 761 affine[kATransX] = 0;
742 affine[kATransY] = 0; 762 affine[kATransY] = 0;
743 } 763 }
744 764
745 bool SkMatrix::asAffine(SkScalar affine[6]) const { 765 bool SkMatrix::asAffine(SkScalar affine[6]) const {
746 if (this->hasPerspective()) { 766 if (this->hasPerspective()) {
747 return false; 767 return false;
748 } 768 }
749 if (affine) { 769 if (affine) {
750 affine[kAScaleX] = this->fMat[kMScaleX]; 770 affine[kAScaleX] = this->fMat[kMScaleX];
(...skipping 24 matching lines...) Expand all
775 invY = SkScalarInvert(invY); 795 invY = SkScalarInvert(invY);
776 796
777 // Must be careful when writing to inv, since it may be the 797 // Must be careful when writing to inv, since it may be the
778 // same memory as this. 798 // same memory as this.
779 799
780 inv->fMat[kMSkewX] = inv->fMat[kMSkewY] = 800 inv->fMat[kMSkewX] = inv->fMat[kMSkewY] =
781 inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0; 801 inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0;
782 802
783 inv->fMat[kMScaleX] = invX; 803 inv->fMat[kMScaleX] = invX;
784 inv->fMat[kMScaleY] = invY; 804 inv->fMat[kMScaleY] = invY;
785 inv->fMat[kMPersp2] = kMatrix22Elem; 805 inv->fMat[kMPersp2] = 1;
786 inv->fMat[kMTransX] = -SkScalarMul(fMat[kMTransX], invX); 806 inv->fMat[kMTransX] = -fMat[kMTransX] * invX;
787 inv->fMat[kMTransY] = -SkScalarMul(fMat[kMTransY], invY); 807 inv->fMat[kMTransY] = -fMat[kMTransY] * invY;
788 808
789 inv->setTypeMask(mask | kRectStaysRect_Mask); 809 inv->setTypeMask(mask | kRectStaysRect_Mask);
790 } else { 810 } else {
791 // translate only 811 // translate only
792 inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]); 812 inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]);
793 } 813 }
794 } else { // inv is NULL, just check if we're invertible 814 } else { // inv is NULL, just check if we're invertible
795 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { 815 if (!fMat[kMScaleX] || !fMat[kMScaleY]) {
796 invertible = false; 816 invertible = false;
797 } 817 }
798 } 818 }
799 return invertible; 819 return invertible;
800 } 820 }
801 821
802 int isPersp = mask & kPerspective_Mask; 822 int isPersp = mask & kPerspective_Mask;
803 int shift; 823 double scale = sk_inv_determinant(fMat, isPersp);
804 SkDetScalar scale = sk_inv_determinant(fMat, isPersp, &shift);
805 824
806 if (scale == 0) { // underflow 825 if (scale == 0) { // underflow
807 return false; 826 return false;
808 } 827 }
809 828
810 if (inv) { 829 if (inv) {
811 SkMatrix tmp; 830 SkMatrix tmp;
812 if (inv == this) { 831 if (inv == this) {
813 inv = &tmp; 832 inv = &tmp;
814 } 833 }
815 834
816 if (isPersp) { 835 if (isPersp) {
817 shift = 61 - shift; 836 inv->fMat[kMScaleX] = SkDoubleToScalar(scross(fMat[kMScaleY], fMat[k MPersp2], fMat[kMTransY], fMat[kMPersp1]) * scale);
mtklein 2014/01/30 19:14:55 This part is also pretty hard to parse. could be
818 inv->fMat[kMScaleX] = SkScalarMulShift(SkPerspMul(fMat[kMScaleY], fM at[kMPersp2]) - SkPerspMul(fMat[kMTransY], fMat[kMPersp1]), scale, shift); 837 inv->fMat[kMSkewX] = SkDoubleToScalar(scross(fMat[kMTransX], fMat[k MPersp1], fMat[kMSkewX], fMat[kMPersp2]) * scale);
819 inv->fMat[kMSkewX] = SkScalarMulShift(SkPerspMul(fMat[kMTransX], fM at[kMPersp1]) - SkPerspMul(fMat[kMSkewX], fMat[kMPersp2]), scale, shift); 838 inv->fMat[kMTransX] = SkDoubleToScalar(scross(fMat[kMSkewX], fMat[k MTransY], fMat[kMTransX], fMat[kMScaleY]) * scale);
820 inv->fMat[kMTransX] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM at[kMTransY]) - SkScalarMul(fMat[kMTransX], fMat[kMScaleY]), scale, shift);
821 839
822 inv->fMat[kMSkewY] = SkScalarMulShift(SkPerspMul(fMat[kMTransY], fM at[kMPersp0]) - SkPerspMul(fMat[kMSkewY], fMat[kMPersp2]), scale, shift); 840 inv->fMat[kMSkewY] = SkDoubleToScalar(scross(fMat[kMTransY], fMat[k MPersp0], fMat[kMSkewY], fMat[kMPersp2]) * scale);
823 inv->fMat[kMScaleY] = SkScalarMulShift(SkPerspMul(fMat[kMScaleX], fM at[kMPersp2]) - SkPerspMul(fMat[kMTransX], fMat[kMPersp0]), scale, shift); 841 inv->fMat[kMScaleY] = SkDoubleToScalar(scross(fMat[kMScaleX], fMat[k MPersp2], fMat[kMTransX], fMat[kMPersp0]) * scale);
824 inv->fMat[kMTransY] = SkScalarMulShift(SkScalarMul(fMat[kMTransX], f Mat[kMSkewY]) - SkScalarMul(fMat[kMScaleX], fMat[kMTransY]), scale, shift); 842 inv->fMat[kMTransY] = SkDoubleToScalar(scross(fMat[kMTransX], fMat[k MSkewY], fMat[kMScaleX], fMat[kMTransY]) * scale);
825 843
826 inv->fMat[kMPersp0] = SkScalarMulShift(SkScalarMul(fMat[kMSkewY], fM at[kMPersp1]) - SkScalarMul(fMat[kMScaleY], fMat[kMPersp0]), scale, shift); 844 inv->fMat[kMPersp0] = SkDoubleToScalar(scross(fMat[kMSkewY], fMat[k MPersp1], fMat[kMScaleY], fMat[kMPersp0]) * scale);
827 inv->fMat[kMPersp1] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM at[kMPersp0]) - SkScalarMul(fMat[kMScaleX], fMat[kMPersp1]), scale, shift); 845 inv->fMat[kMPersp1] = SkDoubleToScalar(scross(fMat[kMSkewX], fMat[k MPersp0], fMat[kMScaleX], fMat[kMPersp1]) * scale);
828 inv->fMat[kMPersp2] = SkScalarMulShift(SkScalarMul(fMat[kMScaleX], f Mat[kMScaleY]) - SkScalarMul(fMat[kMSkewX], fMat[kMSkewY]), scale, shift); 846 inv->fMat[kMPersp2] = SkDoubleToScalar(scross(fMat[kMScaleX], fMat[k MScaleY], fMat[kMSkewX], fMat[kMSkewY]) * scale);
829 } else { // not perspective 847 } else { // not perspective
830 inv->fMat[kMScaleX] = SkDoubleToFloat(fMat[kMScaleY] * scale); 848 inv->fMat[kMScaleX] = SkDoubleToScalar(fMat[kMScaleY] * scale);
831 inv->fMat[kMSkewX] = SkDoubleToFloat(-fMat[kMSkewX] * scale); 849 inv->fMat[kMSkewX] = SkDoubleToScalar(-fMat[kMSkewX] * scale);
832 inv->fMat[kMTransX] = mul_diff_scale(fMat[kMSkewX], fMat[kMTransY], 850 inv->fMat[kMTransX] = SkDoubleToScalar(dcross(fMat[kMSkewX], fMat[kM TransY], fMat[kMScaleY], fMat[kMTransX]) * scale);
mtklein 2014/01/30 19:14:55 Why switch away from mul_diff_scale here?
reed1 2014/01/30 20:53:48 Done.
833 fMat[kMScaleY], fMat[kMTransX], scale);
834 851
835 inv->fMat[kMSkewY] = SkDoubleToFloat(-fMat[kMSkewY] * scale); 852 inv->fMat[kMSkewY] = SkDoubleToScalar(-fMat[kMSkewY] * scale);
836 inv->fMat[kMScaleY] = SkDoubleToFloat(fMat[kMScaleX] * scale); 853 inv->fMat[kMScaleY] = SkDoubleToScalar(fMat[kMScaleX] * scale);
837 inv->fMat[kMTransY] = mul_diff_scale(fMat[kMSkewY], fMat[kMTransX], 854 inv->fMat[kMTransY] = SkDoubleToScalar(dcross(fMat[kMSkewY], fMat[kM TransX], fMat[kMScaleX], fMat[kMTransY]) * scale);
mtklein 2014/01/30 19:14:55 Same?
reed1 2014/01/30 20:53:48 Done.
838 fMat[kMScaleX], fMat[kMTransY], scale);
839 855
840 inv->fMat[kMPersp0] = 0; 856 inv->fMat[kMPersp0] = 0;
841 inv->fMat[kMPersp1] = 0; 857 inv->fMat[kMPersp1] = 0;
842 inv->fMat[kMPersp2] = kMatrix22Elem; 858 inv->fMat[kMPersp2] = 1;
843 859
844 } 860 }
845 861
846 inv->setTypeMask(fTypeMask); 862 inv->setTypeMask(fTypeMask);
847 863
848 if (inv == &tmp) { 864 if (inv == &tmp) {
849 *(SkMatrix*)this = tmp; 865 *(SkMatrix*)this = tmp;
850 } 866 }
851 } 867 }
852 return true; 868 return true;
(...skipping 26 matching lines...) Expand all
879 } 895 }
880 896
881 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], 897 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[],
882 const SkPoint src[], int count) { 898 const SkPoint src[], int count) {
883 SkASSERT(m.getType() == kScale_Mask); 899 SkASSERT(m.getType() == kScale_Mask);
884 900
885 if (count > 0) { 901 if (count > 0) {
886 SkScalar mx = m.fMat[kMScaleX]; 902 SkScalar mx = m.fMat[kMScaleX];
887 SkScalar my = m.fMat[kMScaleY]; 903 SkScalar my = m.fMat[kMScaleY];
888 do { 904 do {
889 dst->fY = SkScalarMul(src->fY, my); 905 dst->fY = src->fY * my;
890 dst->fX = SkScalarMul(src->fX, mx); 906 dst->fX = src->fX * mx;
891 src += 1; 907 src += 1;
892 dst += 1; 908 dst += 1;
893 } while (--count); 909 } while (--count);
894 } 910 }
895 } 911 }
896 912
897 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], 913 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[],
898 const SkPoint src[], int count) { 914 const SkPoint src[], int count) {
899 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); 915 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask));
900 916
901 if (count > 0) { 917 if (count > 0) {
902 SkScalar mx = m.fMat[kMScaleX]; 918 SkScalar mx = m.fMat[kMScaleX];
903 SkScalar my = m.fMat[kMScaleY]; 919 SkScalar my = m.fMat[kMScaleY];
904 SkScalar tx = m.fMat[kMTransX]; 920 SkScalar tx = m.fMat[kMTransX];
905 SkScalar ty = m.fMat[kMTransY]; 921 SkScalar ty = m.fMat[kMTransY];
906 do { 922 do {
907 dst->fY = SkScalarMulAdd(src->fY, my, ty); 923 dst->fY = src->fY * my + ty;
908 dst->fX = SkScalarMulAdd(src->fX, mx, tx); 924 dst->fX = src->fX * mx + tx;
909 src += 1; 925 src += 1;
910 dst += 1; 926 dst += 1;
911 } while (--count); 927 } while (--count);
912 } 928 }
913 } 929 }
914 930
915 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], 931 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[],
916 const SkPoint src[], int count) { 932 const SkPoint src[], int count) {
917 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); 933 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0);
918 934
919 if (count > 0) { 935 if (count > 0) {
920 SkScalar mx = m.fMat[kMScaleX]; 936 SkScalar mx = m.fMat[kMScaleX];
921 SkScalar my = m.fMat[kMScaleY]; 937 SkScalar my = m.fMat[kMScaleY];
922 SkScalar kx = m.fMat[kMSkewX]; 938 SkScalar kx = m.fMat[kMSkewX];
923 SkScalar ky = m.fMat[kMSkewY]; 939 SkScalar ky = m.fMat[kMSkewY];
924 do { 940 do {
925 SkScalar sy = src->fY; 941 SkScalar sy = src->fY;
926 SkScalar sx = src->fX; 942 SkScalar sx = src->fX;
927 src += 1; 943 src += 1;
928 dst->fY = SkScalarMul(sx, ky) + SkScalarMul(sy, my); 944 dst->fY = sdot(sx, ky, sy, my);
929 dst->fX = SkScalarMul(sx, mx) + SkScalarMul(sy, kx); 945 dst->fX = sdot(sx, mx, sy, kx);
930 dst += 1; 946 dst += 1;
931 } while (--count); 947 } while (--count);
932 } 948 }
933 } 949 }
934 950
935 void SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[], 951 void SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[],
936 const SkPoint src[], int count) { 952 const SkPoint src[], int count) {
937 SkASSERT(!m.hasPerspective()); 953 SkASSERT(!m.hasPerspective());
938 954
939 if (count > 0) { 955 if (count > 0) {
940 SkScalar mx = m.fMat[kMScaleX]; 956 SkScalar mx = m.fMat[kMScaleX];
941 SkScalar my = m.fMat[kMScaleY]; 957 SkScalar my = m.fMat[kMScaleY];
942 SkScalar kx = m.fMat[kMSkewX]; 958 SkScalar kx = m.fMat[kMSkewX];
943 SkScalar ky = m.fMat[kMSkewY]; 959 SkScalar ky = m.fMat[kMSkewY];
944 SkScalar tx = m.fMat[kMTransX]; 960 SkScalar tx = m.fMat[kMTransX];
945 SkScalar ty = m.fMat[kMTransY]; 961 SkScalar ty = m.fMat[kMTransY];
946 do { 962 do {
947 SkScalar sy = src->fY; 963 SkScalar sy = src->fY;
948 SkScalar sx = src->fX; 964 SkScalar sx = src->fX;
949 src += 1; 965 src += 1;
950 dst->fY = SkScalarMul(sx, ky) + SkScalarMulAdd(sy, my, ty); 966 #ifdef SK_LEGACY_MATRIX_MATH_ORDER
951 dst->fX = SkScalarMul(sx, mx) + SkScalarMulAdd(sy, kx, tx); 967 dst->fY = sx * ky + (sy * my + ty);
968 dst->fX = sx * mx + (sy * kx + tx);
969 #else
970 dst->fY = sdot(sx, ky, sy, my) + ty;
971 dst->fX = sdot(sx, mx, sy, kx) + tx;
972 #endif
952 dst += 1; 973 dst += 1;
953 } while (--count); 974 } while (--count);
954 } 975 }
955 } 976 }
956 977
957 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], 978 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[],
958 const SkPoint src[], int count) { 979 const SkPoint src[], int count) {
959 SkASSERT(m.hasPerspective()); 980 SkASSERT(m.hasPerspective());
960 981
961 if (count > 0) { 982 if (count > 0) {
962 do { 983 do {
963 SkScalar sy = src->fY; 984 SkScalar sy = src->fY;
964 SkScalar sx = src->fX; 985 SkScalar sx = src->fX;
965 src += 1; 986 src += 1;
966 987
967 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + 988 SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fM at[kMTransX];
968 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; 989 SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fM at[kMTransY];
969 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + 990 #ifdef SK_LEGACY_MATRIX_MATH_ORDER
970 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; 991 SkScalar z = sx * m.fMat[kMPersp0] + (sy * m.fMat[kMPersp1] + m.fMat [kMPersp2]);
971 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) + 992 #else
972 SkScalarMulAdd(sy, m.fMat[kMPersp1], m.fMat[kMPersp2]); 993 SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fM at[kMPersp2];
994 #endif
973 if (z) { 995 if (z) {
974 z = SkScalarFastInvert(z); 996 z = SkScalarFastInvert(z);
975 } 997 }
976 998
977 dst->fY = SkScalarMul(y, z); 999 dst->fY = y * z;
978 dst->fX = SkScalarMul(x, z); 1000 dst->fX = x * z;
979 dst += 1; 1001 dst += 1;
980 } while (--count); 1002 } while (--count);
981 } 1003 }
982 } 1004 }
983 1005
984 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { 1006 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = {
985 SkMatrix::Identity_pts, SkMatrix::Trans_pts, 1007 SkMatrix::Identity_pts, SkMatrix::Trans_pts,
986 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, 1008 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts,
987 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, 1009 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts,
988 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, 1010 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts,
(...skipping 23 matching lines...) Expand all
1012 if (this->isIdentity()) { 1034 if (this->isIdentity()) {
1013 memcpy(dst, src, 3*count*sizeof(SkScalar)); 1035 memcpy(dst, src, 3*count*sizeof(SkScalar));
1014 return; 1036 return;
1015 } 1037 }
1016 do { 1038 do {
1017 SkScalar sx = src[0]; 1039 SkScalar sx = src[0];
1018 SkScalar sy = src[1]; 1040 SkScalar sy = src[1];
1019 SkScalar sw = src[2]; 1041 SkScalar sw = src[2];
1020 src += 3; 1042 src += 3;
1021 1043
1022 SkScalar x = SkScalarMul(sx, fMat[kMScaleX]) + 1044 SkScalar x = sdot3(sx, fMat[kMScaleX], sy, fMat[kMSkewX], sw, fMat[ kMTransX]);
1023 SkScalarMul(sy, fMat[kMSkewX]) + 1045 SkScalar y = sdot3(sx, fMat[kMSkewY], sy, fMat[kMScaleY], sw, fMat[ kMTransY]);
1024 SkScalarMul(sw, fMat[kMTransX]); 1046 SkScalar w = sdot3(sx, fMat[kMPersp0], sy, fMat[kMPersp1], sw, fMat[ kMPersp2]);
1025 SkScalar y = SkScalarMul(sx, fMat[kMSkewY]) +
1026 SkScalarMul(sy, fMat[kMScaleY]) +
1027 SkScalarMul(sw, fMat[kMTransY]);
1028 SkScalar w = SkScalarMul(sx, fMat[kMPersp0]) +
1029 SkScalarMul(sy, fMat[kMPersp1]) +
1030 SkScalarMul(sw, fMat[kMPersp2]);
1031 1047
1032 dst[0] = x; 1048 dst[0] = x;
1033 dst[1] = y; 1049 dst[1] = y;
1034 dst[2] = w; 1050 dst[2] = w;
1035 dst += 3; 1051 dst += 3;
1036 } while (--count); 1052 } while (--count);
1037 } 1053 }
1038 } 1054 }
1039 1055
1040 /////////////////////////////////////////////////////////////////////////////// 1056 ///////////////////////////////////////////////////////////////////////////////
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 // return geometric mean 1107 // return geometric mean
1092 return SkScalarSqrt(d0 * d1); 1108 return SkScalarSqrt(d0 * d1);
1093 } 1109 }
1094 1110
1095 /////////////////////////////////////////////////////////////////////////////// 1111 ///////////////////////////////////////////////////////////////////////////////
1096 1112
1097 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 1113 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
1098 SkPoint* pt) { 1114 SkPoint* pt) {
1099 SkASSERT(m.hasPerspective()); 1115 SkASSERT(m.hasPerspective());
1100 1116
1101 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + 1117 SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTra nsX];
1102 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; 1118 SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTra nsY];
1103 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + 1119 SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fMat[kMPer sp2];
1104 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY];
1105 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) +
1106 SkScalarMul(sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2];
1107 if (z) { 1120 if (z) {
1108 z = SkScalarFastInvert(z); 1121 z = SkScalarFastInvert(z);
1109 } 1122 }
1110 pt->fX = SkScalarMul(x, z); 1123 pt->fX = x * z;
1111 pt->fY = SkScalarMul(y, z); 1124 pt->fY = y * z;
1112 } 1125 }
1113 1126
1114 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 1127 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
1115 SkPoint* pt) { 1128 SkPoint* pt) {
1116 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask) ; 1129 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask) ;
1117 1130
1118 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + 1131 #ifdef SK_LEGACY_MATRIX_MATH_ORDER
1119 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); 1132 pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]) ;
1120 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + 1133 pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]);
1121 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); 1134 #else
1135 pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX] ;
1136 pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY] ;
1137 #endif
1122 } 1138 }
1123 1139
1124 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 1140 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
1125 SkPoint* pt) { 1141 SkPoint* pt) {
1126 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); 1142 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask);
1127 SkASSERT(0 == m.fMat[kMTransX]); 1143 SkASSERT(0 == m.fMat[kMTransX]);
1128 SkASSERT(0 == m.fMat[kMTransY]); 1144 SkASSERT(0 == m.fMat[kMTransY]);
1129 1145
1130 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + 1146 #ifdef SK_LEGACY_MATRIX_MATH_ORDER
1131 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); 1147 pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]);
1132 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + 1148 pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]);
1133 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); 1149 #else
1150 pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX] ;
1151 pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY] ;
1152 #endif
1134 } 1153 }
1135 1154
1136 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 1155 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
1137 SkPoint* pt) { 1156 SkPoint* pt) {
1138 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) 1157 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask))
1139 == kScale_Mask); 1158 == kScale_Mask);
1140 1159
1141 pt->fX = SkScalarMulAdd(sx, m.fMat[kMScaleX], m.fMat[kMTransX]); 1160 pt->fX = sx * m.fMat[kMScaleX] + m.fMat[kMTransX];
1142 pt->fY = SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); 1161 pt->fY = sy * m.fMat[kMScaleY] + m.fMat[kMTransY];
1143 } 1162 }
1144 1163
1145 void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 1164 void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
1146 SkPoint* pt) { 1165 SkPoint* pt) {
1147 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) 1166 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask))
1148 == kScale_Mask); 1167 == kScale_Mask);
1149 SkASSERT(0 == m.fMat[kMTransX]); 1168 SkASSERT(0 == m.fMat[kMTransX]);
1150 SkASSERT(0 == m.fMat[kMTransY]); 1169 SkASSERT(0 == m.fMat[kMTransY]);
1151 1170
1152 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]); 1171 pt->fX = sx * m.fMat[kMScaleX];
1153 pt->fY = SkScalarMul(sy, m.fMat[kMScaleY]); 1172 pt->fY = sy * m.fMat[kMScaleY];
1154 } 1173 }
1155 1174
1156 void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 1175 void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
1157 SkPoint* pt) { 1176 SkPoint* pt) {
1158 SkASSERT(m.getType() == kTranslate_Mask); 1177 SkASSERT(m.getType() == kTranslate_Mask);
1159 1178
1160 pt->fX = sx + m.fMat[kMTransX]; 1179 pt->fX = sx + m.fMat[kMTransX];
1161 pt->fY = sy + m.fMat[kMTransY]; 1180 pt->fY = sy + m.fMat[kMTransY];
1162 } 1181 }
1163 1182
(...skipping 19 matching lines...) Expand all
1183 1202
1184 /////////////////////////////////////////////////////////////////////////////// 1203 ///////////////////////////////////////////////////////////////////////////////
1185 1204
1186 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller) 1205 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller)
1187 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) 1206 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26)))
1188 1207
1189 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { 1208 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const {
1190 if (PerspNearlyZero(fMat[kMPersp0])) { 1209 if (PerspNearlyZero(fMat[kMPersp0])) {
1191 if (stepX || stepY) { 1210 if (stepX || stepY) {
1192 if (PerspNearlyZero(fMat[kMPersp1]) && 1211 if (PerspNearlyZero(fMat[kMPersp1]) &&
1193 PerspNearlyZero(fMat[kMPersp2] - kMatrix22Elem)) { 1212 PerspNearlyZero(fMat[kMPersp2] - 1)) {
1194 if (stepX) { 1213 if (stepX) {
1195 *stepX = SkScalarToFixed(fMat[kMScaleX]); 1214 *stepX = SkScalarToFixed(fMat[kMScaleX]);
1196 } 1215 }
1197 if (stepY) { 1216 if (stepY) {
1198 *stepY = SkScalarToFixed(fMat[kMSkewY]); 1217 *stepY = SkScalarToFixed(fMat[kMSkewY]);
1199 } 1218 }
1200 } else { 1219 } else {
1201 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2]; 1220 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2];
1202 if (stepX) { 1221 if (stepX) {
1203 *stepX = SkScalarToFixed(SkScalarDiv(fMat[kMScaleX], z)); 1222 *stepX = SkScalarToFixed(fMat[kMScaleX] / z);
1204 } 1223 }
1205 if (stepY) { 1224 if (stepY) {
1206 *stepY = SkScalarToFixed(SkScalarDiv(fMat[kMSkewY], z)); 1225 *stepY = SkScalarToFixed(fMat[kMSkewY] / z);
1207 } 1226 }
1208 } 1227 }
1209 } 1228 }
1210 return true; 1229 return true;
1211 } 1230 }
1212 return false; 1231 return false;
1213 } 1232 }
1214 1233
1215 /////////////////////////////////////////////////////////////////////////////// 1234 ///////////////////////////////////////////////////////////////////////////////
1216 1235
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 case 2: 1303 case 2:
1285 break; 1304 break;
1286 case 3: 1305 case 3:
1287 pt2.fX = poly[0].fY - poly[2].fY; 1306 pt2.fX = poly[0].fY - poly[2].fY;
1288 pt2.fY = poly[2].fX - poly[0].fX; 1307 pt2.fY = poly[2].fX - poly[0].fX;
1289 goto CALC_X; 1308 goto CALC_X;
1290 default: 1309 default:
1291 pt2.fX = poly[0].fY - poly[3].fY; 1310 pt2.fX = poly[0].fY - poly[3].fY;
1292 pt2.fY = poly[3].fX - poly[0].fX; 1311 pt2.fY = poly[3].fX - poly[0].fX;
1293 CALC_X: 1312 CALC_X:
1294 x = SkScalarDiv(SkScalarMul(pt1.fX, pt2.fX) + 1313 x = sdot(pt1.fX, pt2.fX, pt1.fY, pt2.fY) / y;
1295 SkScalarMul(pt1.fY, pt2.fY), y);
1296 break; 1314 break;
1297 } 1315 }
1298 } 1316 }
1299 pt->set(x, y); 1317 pt->set(x, y);
1300 return true; 1318 return true;
1301 } 1319 }
1302 1320
1303 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, 1321 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst,
1304 const SkPoint& scale) { 1322 const SkPoint& scale) {
1305 float invScale = 1 / scale.fY; 1323 float invScale = 1 / scale.fY;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 y1 = srcPt[2].fY - srcPt[1].fY; 1365 y1 = srcPt[2].fY - srcPt[1].fY;
1348 x2 = srcPt[2].fX - srcPt[3].fX; 1366 x2 = srcPt[2].fX - srcPt[3].fX;
1349 y2 = srcPt[2].fY - srcPt[3].fY; 1367 y2 = srcPt[2].fY - srcPt[3].fY;
1350 1368
1351 /* check if abs(x2) > abs(y2) */ 1369 /* check if abs(x2) > abs(y2) */
1352 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { 1370 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) {
1353 float denom = SkScalarMulDiv(x1, y2, x2) - y1; 1371 float denom = SkScalarMulDiv(x1, y2, x2) - y1;
1354 if (checkForZero(denom)) { 1372 if (checkForZero(denom)) {
1355 return false; 1373 return false;
1356 } 1374 }
1357 a1 = SkScalarDiv(SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1, denom); 1375 a1 = (SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1) / denom;
1358 } else { 1376 } else {
1359 float denom = x1 - SkScalarMulDiv(y1, x2, y2); 1377 float denom = x1 - SkScalarMulDiv(y1, x2, y2);
1360 if (checkForZero(denom)) { 1378 if (checkForZero(denom)) {
1361 return false; 1379 return false;
1362 } 1380 }
1363 a1 = SkScalarDiv(x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2), denom); 1381 a1 = (x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2)) / denom;
1364 } 1382 }
1365 1383
1366 /* check if abs(x1) > abs(y1) */ 1384 /* check if abs(x1) > abs(y1) */
1367 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { 1385 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) {
1368 float denom = y2 - SkScalarMulDiv(x2, y1, x1); 1386 float denom = y2 - SkScalarMulDiv(x2, y1, x1);
1369 if (checkForZero(denom)) { 1387 if (checkForZero(denom)) {
1370 return false; 1388 return false;
1371 } 1389 }
1372 a2 = SkScalarDiv(y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1), denom); 1390 a2 = (y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1)) / denom;
1373 } else { 1391 } else {
1374 float denom = SkScalarMulDiv(y2, x1, y1) - x2; 1392 float denom = SkScalarMulDiv(y2, x1, y1) - x2;
1375 if (checkForZero(denom)) { 1393 if (checkForZero(denom)) {
1376 return false; 1394 return false;
1377 } 1395 }
1378 a2 = SkScalarDiv(SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2, denom); 1396 a2 = (SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2) / denom;
1379 } 1397 }
1380 1398
1381 float invScale = 1 / scale.fX; 1399 float invScale = SkScalarInvert(scale.fX);
1382 dst->fMat[kMScaleX] = SkScalarMul(SkScalarMul(a2, srcPt[3].fX) + 1400 dst->fMat[kMScaleX] = (a2 * srcPt[3].fX + srcPt[3].fX - srcPt[0].fX) * invSc ale;
1383 srcPt[3].fX - srcPt[0].fX, invScale); 1401 dst->fMat[kMSkewY] = (a2 * srcPt[3].fY + srcPt[3].fY - srcPt[0].fY) * invSc ale;
1384 dst->fMat[kMSkewY] = SkScalarMul(SkScalarMul(a2, srcPt[3].fY) + 1402 dst->fMat[kMPersp0] = a2 * invScale;
1385 srcPt[3].fY - srcPt[0].fY, invScale); 1403
1386 dst->fMat[kMPersp0] = SkScalarMul(a2, invScale); 1404 invScale = SkScalarInvert(scale.fY);
1387 invScale = 1 / scale.fY; 1405 dst->fMat[kMSkewX] = (a1 * srcPt[1].fX + srcPt[1].fX - srcPt[0].fX) * invSc ale;
1388 dst->fMat[kMSkewX] = SkScalarMul(SkScalarMul(a1, srcPt[1].fX) + 1406 dst->fMat[kMScaleY] = (a1 * srcPt[1].fY + srcPt[1].fY - srcPt[0].fY) * invSc ale;
1389 srcPt[1].fX - srcPt[0].fX, invScale); 1407 dst->fMat[kMPersp1] = a1 * invScale;
1390 dst->fMat[kMScaleY] = SkScalarMul(SkScalarMul(a1, srcPt[1].fY) + 1408
1391 srcPt[1].fY - srcPt[0].fY, invScale);
1392 dst->fMat[kMPersp1] = SkScalarMul(a1, invScale);
1393 dst->fMat[kMTransX] = srcPt[0].fX; 1409 dst->fMat[kMTransX] = srcPt[0].fX;
1394 dst->fMat[kMTransY] = srcPt[0].fY; 1410 dst->fMat[kMTransY] = srcPt[0].fY;
1395 dst->fMat[kMPersp2] = 1; 1411 dst->fMat[kMPersp2] = 1;
1396 dst->setTypeMask(kUnknown_Mask); 1412 dst->setTypeMask(kUnknown_Mask);
1397 return true; 1413 return true;
1398 } 1414 }
1399 1415
1400 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); 1416 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&);
1401 1417
1402 /* Taken from Rob Johnson's original sample code in QuickDraw GX 1418 /* Taken from Rob Johnson's original sample code in QuickDraw GX
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 /////////////////////////////////////////////////////////////////////////////// 1467 ///////////////////////////////////////////////////////////////////////////////
1452 1468
1453 enum MinOrMax { 1469 enum MinOrMax {
1454 kMin_MinOrMax, 1470 kMin_MinOrMax,
1455 kMax_MinOrMax 1471 kMax_MinOrMax
1456 }; 1472 };
1457 1473
1458 template <MinOrMax MIN_OR_MAX> SkScalar get_stretch_factor(SkMatrix::TypeMask ty peMask, 1474 template <MinOrMax MIN_OR_MAX> SkScalar get_stretch_factor(SkMatrix::TypeMask ty peMask,
1459 const SkScalar m[9]) { 1475 const SkScalar m[9]) {
1460 if (typeMask & SkMatrix::kPerspective_Mask) { 1476 if (typeMask & SkMatrix::kPerspective_Mask) {
1461 return -SK_Scalar1; 1477 return -1;
1462 } 1478 }
1463 if (SkMatrix::kIdentity_Mask == typeMask) { 1479 if (SkMatrix::kIdentity_Mask == typeMask) {
1464 return SK_Scalar1; 1480 return 1;
1465 } 1481 }
1466 if (!(typeMask & SkMatrix::kAffine_Mask)) { 1482 if (!(typeMask & SkMatrix::kAffine_Mask)) {
1467 if (kMin_MinOrMax == MIN_OR_MAX) { 1483 if (kMin_MinOrMax == MIN_OR_MAX) {
1468 return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), 1484 return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
1469 SkScalarAbs(m[SkMatrix::kMScaleY])); 1485 SkScalarAbs(m[SkMatrix::kMScaleY]));
1470 } else { 1486 } else {
1471 return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), 1487 return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
1472 SkScalarAbs(m[SkMatrix::kMScaleY])); 1488 SkScalarAbs(m[SkMatrix::kMScaleY]));
1473 } 1489 }
1474 } 1490 }
1475 // ignore the translation part of the matrix, just look at 2x2 portion. 1491 // ignore the translation part of the matrix, just look at 2x2 portion.
1476 // compute singular values, take largest or smallest abs value. 1492 // compute singular values, take largest or smallest abs value.
1477 // [a b; b c] = A^T*A 1493 // [a b; b c] = A^T*A
1478 SkScalar a = SkScalarMul(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX]) + 1494 SkScalar a = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX], m[SkMatrix:: kMSkewY], m[SkMatrix::kMSkewY]);
mtklein 2014/01/30 19:14:55 Clearer back on two lines each?
reed1 2014/01/30 20:53:48 Done.
1479 SkScalarMul(m[SkMatrix::kMSkewY], m[SkMatrix::kMSkewY]); 1495 SkScalar b = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX], m[SkMatrix:: kMScaleY], m[SkMatrix::kMSkewY]);
1480 SkScalar b = SkScalarMul(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX]) + 1496 SkScalar c = sdot(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX], m[SkMatrix:: kMScaleY], m[SkMatrix::kMScaleY]);
1481 SkScalarMul(m[SkMatrix::kMScaleY], m[SkMatrix::kMSkewY]);
1482 SkScalar c = SkScalarMul(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX]) +
1483 SkScalarMul(m[SkMatrix::kMScaleY], m[SkMatrix::kMScaleY]);
1484 // eigenvalues of A^T*A are the squared singular values of A. 1497 // eigenvalues of A^T*A are the squared singular values of A.
1485 // characteristic equation is det((A^T*A) - l*I) = 0 1498 // characteristic equation is det((A^T*A) - l*I) = 0
1486 // l^2 - (a + c)l + (ac-b^2) 1499 // l^2 - (a + c)l + (ac-b^2)
1487 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff 1500 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
1488 // and roots are guaranteed to be pos and real). 1501 // and roots are guaranteed to be pos and real).
1489 SkScalar chosenRoot; 1502 SkScalar chosenRoot;
1490 SkScalar bSqd = SkScalarMul(b,b); 1503 SkScalar bSqd = b * b;
1491 // if upper left 2x2 is orthogonal save some math 1504 // if upper left 2x2 is orthogonal save some math
1492 if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) { 1505 if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) {
1493 if (kMin_MinOrMax == MIN_OR_MAX) { 1506 if (kMin_MinOrMax == MIN_OR_MAX) {
1494 chosenRoot = SkMinScalar(a, c); 1507 chosenRoot = SkMinScalar(a, c);
1495 } else { 1508 } else {
1496 chosenRoot = SkMaxScalar(a, c); 1509 chosenRoot = SkMaxScalar(a, c);
1497 } 1510 }
1498 } else { 1511 } else {
1499 SkScalar aminusc = a - c; 1512 SkScalar aminusc = a - c;
1500 SkScalar apluscdiv2 = SkScalarHalf(a + c); 1513 SkScalar apluscdiv2 = SkScalarHalf(a + c);
1501 SkScalar x = SkScalarHalf(SkScalarSqrt(SkScalarMul(aminusc, aminusc) + 4 * bSqd)); 1514 SkScalar x = SkScalarHalf(SkScalarSqrt(aminusc * aminusc + 4 * bSqd));
1502 if (kMin_MinOrMax == MIN_OR_MAX) { 1515 if (kMin_MinOrMax == MIN_OR_MAX) {
1503 chosenRoot = apluscdiv2 - x; 1516 chosenRoot = apluscdiv2 - x;
1504 } else { 1517 } else {
1505 chosenRoot = apluscdiv2 + x; 1518 chosenRoot = apluscdiv2 + x;
1506 } 1519 }
1507 } 1520 }
1508 SkASSERT(chosenRoot >= 0); 1521 SkASSERT(chosenRoot >= 0);
1509 return SkScalarSqrt(chosenRoot); 1522 return SkScalarSqrt(chosenRoot);
1510 } 1523 }
1511 1524
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 1667
1655 double w1, w2; 1668 double w1, w2;
1656 SkScalar cos1, sin1; 1669 SkScalar cos1, sin1;
1657 SkScalar cos2, sin2; 1670 SkScalar cos2, sin2;
1658 1671
1659 // do polar decomposition (M = Q*S) 1672 // do polar decomposition (M = Q*S)
1660 SkScalar cosQ, sinQ; 1673 SkScalar cosQ, sinQ;
1661 double Sa, Sb, Sd; 1674 double Sa, Sb, Sd;
1662 // if M is already symmetric (i.e., M = I*S) 1675 // if M is already symmetric (i.e., M = I*S)
1663 if (SkScalarNearlyEqual(B, C)) { 1676 if (SkScalarNearlyEqual(B, C)) {
1664 cosQ = SK_Scalar1; 1677 cosQ = 1;
1665 sinQ = 0; 1678 sinQ = 0;
1666 1679
1667 Sa = A; 1680 Sa = A;
1668 Sb = B; 1681 Sb = B;
1669 Sd = D; 1682 Sd = D;
1670 } else { 1683 } else {
1671 cosQ = A + D; 1684 cosQ = A + D;
1672 sinQ = C - B; 1685 sinQ = C - B;
1673 SkScalar reciplen = SK_Scalar1/SkScalarSqrt(cosQ*cosQ + sinQ*sinQ); 1686 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cosQ*cosQ + sinQ*sinQ));
1674 cosQ *= reciplen; 1687 cosQ *= reciplen;
1675 sinQ *= reciplen; 1688 sinQ *= reciplen;
1676 1689
1677 // S = Q^-1*M 1690 // S = Q^-1*M
1678 // we don't calc Sc since it's symmetric 1691 // we don't calc Sc since it's symmetric
1679 Sa = A*cosQ + C*sinQ; 1692 Sa = A*cosQ + C*sinQ;
1680 Sb = B*cosQ + D*sinQ; 1693 Sb = B*cosQ + D*sinQ;
1681 Sd = -B*sinQ + D*cosQ; 1694 Sd = -B*sinQ + D*cosQ;
1682 } 1695 }
1683 1696
1684 // Now we need to compute eigenvalues of S (our scale factors) 1697 // Now we need to compute eigenvalues of S (our scale factors)
1685 // and eigenvectors (bases for our rotation) 1698 // and eigenvectors (bases for our rotation)
1686 // From this, should be able to reconstruct S as U*W*U^T 1699 // From this, should be able to reconstruct S as U*W*U^T
1687 if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) { 1700 if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) {
1688 // already diagonalized 1701 // already diagonalized
1689 cos1 = SK_Scalar1; 1702 cos1 = 1;
1690 sin1 = 0; 1703 sin1 = 0;
1691 w1 = Sa; 1704 w1 = Sa;
1692 w2 = Sd; 1705 w2 = Sd;
1693 cos2 = cosQ; 1706 cos2 = cosQ;
1694 sin2 = sinQ; 1707 sin2 = sinQ;
1695 } else { 1708 } else {
1696 double diff = Sa - Sd; 1709 double diff = Sa - Sd;
1697 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb); 1710 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb);
1698 double trace = Sa + Sd; 1711 double trace = Sa + Sd;
1699 if (diff > 0) { 1712 if (diff > 0) {
1700 w1 = 0.5*(trace + discriminant); 1713 w1 = 0.5*(trace + discriminant);
1701 w2 = 0.5*(trace - discriminant); 1714 w2 = 0.5*(trace - discriminant);
1702 } else { 1715 } else {
1703 w1 = 0.5*(trace - discriminant); 1716 w1 = 0.5*(trace - discriminant);
1704 w2 = 0.5*(trace + discriminant); 1717 w2 = 0.5*(trace + discriminant);
1705 } 1718 }
1706 1719
1707 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa); 1720 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa);
1708 SkScalar reciplen = SK_Scalar1/SkScalarSqrt(cos1*cos1 + sin1*sin1); 1721 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cos1*cos1 + sin1*sin1));
1709 cos1 *= reciplen; 1722 cos1 *= reciplen;
1710 sin1 *= reciplen; 1723 sin1 *= reciplen;
1711 1724
1712 // rotation 2 is composition of Q and U 1725 // rotation 2 is composition of Q and U
1713 cos2 = cos1*cosQ - sin1*sinQ; 1726 cos2 = cos1*cosQ - sin1*sinQ;
1714 sin2 = sin1*cosQ + cos1*sinQ; 1727 sin2 = sin1*cosQ + cos1*sinQ;
1715 1728
1716 // rotation 1 is U^T 1729 // rotation 1 is U^T
1717 sin1 = -sin1; 1730 sin1 = -sin1;
1718 } 1731 }
1719 1732
1720 if (NULL != scale) { 1733 if (NULL != scale) {
1721 scale->fX = SkDoubleToScalar(w1); 1734 scale->fX = SkDoubleToScalar(w1);
1722 scale->fY = SkDoubleToScalar(w2); 1735 scale->fY = SkDoubleToScalar(w2);
1723 } 1736 }
1724 if (NULL != rotation1) { 1737 if (NULL != rotation1) {
1725 rotation1->fX = cos1; 1738 rotation1->fX = cos1;
1726 rotation1->fY = sin1; 1739 rotation1->fY = sin1;
1727 } 1740 }
1728 if (NULL != rotation2) { 1741 if (NULL != rotation2) {
1729 rotation2->fX = cos2; 1742 rotation2->fX = cos2;
1730 rotation2->fY = sin2; 1743 rotation2->fY = sin2;
1731 } 1744 }
1732 1745
1733 return true; 1746 return true;
1734 } 1747 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698