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
14class SkTextMapStateProc {
15public:
16    SkTextMapStateProc(const SkMatrix& matrix, SkScalar y, int scalarsPerPosition)
17        : fMatrix(matrix)
18        , fProc(matrix.getMapXYProc())
19        , fY(y)
20        , fScaleX(fMatrix.getScaleX())
21        , fTransX(fMatrix.getTranslateX()) {
22        SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
23        if (1 == scalarsPerPosition) {
24            unsigned mtype = fMatrix.getType();
25            if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
26                fMapCase = kX;
27            } else {
28                fY = SkScalarMul(y, fMatrix.getScaleY()) +
29                    fMatrix.getTranslateY();
30                if (mtype & SkMatrix::kScale_Mask) {
31                    fMapCase = kOnlyScaleX;
32                } else {
33                    fMapCase = kOnlyTransX;
34                }
35            }
36        } else {
37            fMapCase = kXY;
38        }
39    }
40
41    void operator()(const SkScalar pos[], SkPoint* loc) const;
42
43private:
44    const SkMatrix& fMatrix;
45    enum {
46        kXY,
47        kOnlyScaleX,
48        kOnlyTransX,
49        kX
50    } fMapCase;
51    const SkMatrix::MapXYProc fProc;
52    SkScalar fY; // Ignored by kXY case.
53    SkScalar fScaleX, fTransX; // These are only used by Only... cases.
54};
55
56inline void SkTextMapStateProc::operator()(const SkScalar pos[], SkPoint* loc) const {
57    switch(fMapCase) {
58    case kXY:
59        fProc(fMatrix, pos[0], pos[1], loc);
60        break;
61    case kOnlyScaleX:
62        loc->set(SkScalarMul(fScaleX, *pos) + fTransX, fY);
63        break;
64    case kOnlyTransX:
65        loc->set(*pos + fTransX, fY);
66        break;
67    default:
68        SkASSERT(false);
69    case kX:
70        fProc(fMatrix, *pos, fY, loc);
71        break;
72    }
73}
74
75#endif
76
77