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