aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkTextMapStateProc.h
blob: 39897061a439b13edfecc191b3489580f2f31e26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkTextMapStateProc_DEFINED
#define SkTextMapStateProc_DEFINED

#include "SkPoint.h"
#include "SkMatrixPriv.h"

class SkTextMapStateProc {
public:
    SkTextMapStateProc(const SkMatrix& matrix, const SkPoint& offset, int scalarsPerPosition)
        : fMatrix(matrix)
        , fProc(SkMatrixPriv::GetMapXYProc(matrix))
        , fOffset(offset)
        , fScaleX(fMatrix.getScaleX()) {
        SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
        if (1 == scalarsPerPosition) {
            unsigned mtype = fMatrix.getType();
            if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
                fMapCase = kX;
            } else {
                // Bake the matrix scale/translation components into fOffset,
                // to expedite proc computations.
                fOffset.set(offset.x() * fMatrix.getScaleX() + fMatrix.getTranslateX(),
                            offset.y() * fMatrix.getScaleY() + fMatrix.getTranslateY());

                if (mtype & SkMatrix::kScale_Mask) {
                    fMapCase = kOnlyScaleX;
                } else {
                    fMapCase = kOnlyTransX;
                }
            }
        } else {
            fMapCase = kXY;
        }
    }

    void operator()(const SkScalar pos[], SkPoint* loc) const;

private:
    const SkMatrix& fMatrix;
    enum {
        kXY,
        kOnlyScaleX,
        kOnlyTransX,
        kX
    } fMapCase;
    const SkMatrixPriv::MapXYProc fProc;
    SkPoint  fOffset; // In kOnly* mode, this includes the matrix translation component.
    SkScalar fScaleX; // This is only used by kOnly... cases.
};

inline void SkTextMapStateProc::operator()(const SkScalar pos[], SkPoint* loc) const {
    switch(fMapCase) {
    case kXY:
        fProc(fMatrix, pos[0] + fOffset.x(), pos[1] + fOffset.y(), loc);
        break;
    case kOnlyScaleX:
        loc->set(fScaleX * *pos + fOffset.x(), fOffset.y());
        break;
    case kOnlyTransX:
        loc->set(*pos + fOffset.x(), fOffset.y());
        break;
    default:
        SkASSERT(false);
    case kX:
        fProc(fMatrix, *pos + fOffset.x(), fOffset.y(), loc);
        break;
    }
}

#endif