1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkTextMapStateProc_DEFINED
9 #define SkTextMapStateProc_DEFINED
10 
11 #include "SkPoint.h"
12 #include "SkMatrix.h"
13 
14 class SkTextMapStateProc {
15 public:
SkTextMapStateProc(const SkMatrix & matrix,const SkPoint & offset,int scalarsPerPosition)16     SkTextMapStateProc(const SkMatrix& matrix, const SkPoint& offset, int scalarsPerPosition)
17         : fMatrix(matrix)
18         , fProc(matrix.getMapXYProc())
19         , fOffset(offset)
20         , fScaleX(fMatrix.getScaleX()) {
21         SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
22         if (1 == scalarsPerPosition) {
23             unsigned mtype = fMatrix.getType();
24             if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
25                 fMapCase = kX;
26             } else {
27                 // Bake the matrix scale/translation components into fOffset,
28                 // to expedite proc computations.
29                 fOffset.set(SkScalarMul(offset.x(), fMatrix.getScaleX()) + fMatrix.getTranslateX(),
30                             SkScalarMul(offset.y(), fMatrix.getScaleY()) + fMatrix.getTranslateY());
31 
32                 if (mtype & SkMatrix::kScale_Mask) {
33                     fMapCase = kOnlyScaleX;
34                 } else {
35                     fMapCase = kOnlyTransX;
36                 }
37             }
38         } else {
39             fMapCase = kXY;
40         }
41     }
42 
43     void operator()(const SkScalar pos[], SkPoint* loc) const;
44 
45 private:
46     const SkMatrix& fMatrix;
47     enum {
48         kXY,
49         kOnlyScaleX,
50         kOnlyTransX,
51         kX
52     } fMapCase;
53     const SkMatrix::MapXYProc fProc;
54     SkPoint  fOffset; // In kOnly* mode, this includes the matrix translation component.
55     SkScalar fScaleX; // This is only used by kOnly... cases.
56 };
57 
operator()58 inline void SkTextMapStateProc::operator()(const SkScalar pos[], SkPoint* loc) const {
59     switch(fMapCase) {
60     case kXY:
61         fProc(fMatrix, pos[0] + fOffset.x(), pos[1] + fOffset.y(), loc);
62         break;
63     case kOnlyScaleX:
64         loc->set(SkScalarMul(fScaleX, *pos) + fOffset.x(), fOffset.y());
65         break;
66     case kOnlyTransX:
67         loc->set(*pos + fOffset.x(), fOffset.y());
68         break;
69     default:
70         SkASSERT(false);
71     case kX:
72         fProc(fMatrix, *pos + fOffset.x(), fOffset.y(), loc);
73         break;
74     }
75 }
76 
77 #endif
78 
79