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