/*
 * 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
