/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkMatrixPriv_DEFINE #define SkMatrixPriv_DEFINE #include "SkMatrix.h" #include "SkNx.h" class SkMatrixPriv { public: /** * Attempt to map the rect through the inverse of the matrix. If it is not invertible, * then this returns false and dst is unchanged. */ static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx, SkRect* dst, const SkRect& src) { if (mx.getType() <= SkMatrix::kTranslate_Mask) { SkScalar tx = mx.getTranslateX(); SkScalar ty = mx.getTranslateY(); Sk4f trans(tx, ty, tx, ty); (Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft); return true; } // Insert other special-cases here (e.g. scale+translate) // general case SkMatrix inverse; if (mx.invert(&inverse)) { inverse.mapRect(dst, src); return true; } return false; } static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) { SkASSERT(stride >= sizeof(SkPoint)); SkASSERT(0 == stride % sizeof(SkScalar)); SkMatrix::TypeMask tm = mx.getType(); if (SkMatrix::kIdentity_Mask == tm) { return; } if (SkMatrix::kTranslate_Mask == tm) { const SkScalar tx = mx.getTranslateX(); const SkScalar ty = mx.getTranslateY(); Sk2s trans(tx, ty); for (int i = 0; i < count; ++i) { (Sk2s::Load(&pts->fX) + trans).store(&pts->fX); pts = (SkPoint*)((intptr_t)pts + stride); } return; } // Insert other special-cases here (e.g. scale+translate) // general case SkMatrix::MapXYProc proc = mx.getMapXYProc(); for (int i = 0; i < count; ++i) { proc(mx, pts->fX, pts->fY, pts); pts = (SkPoint*)((intptr_t)pts + stride); } } }; #endif