| /* |
| * 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); |
| } |
| } |
| |
| static void SetMappedRectTriStrip(const SkMatrix& mx, const SkRect& rect, SkPoint quad[4]) { |
| SkMatrix::TypeMask tm = mx.getType(); |
| SkScalar l = rect.fLeft; |
| SkScalar t = rect.fTop; |
| SkScalar r = rect.fRight; |
| SkScalar b = rect.fBottom; |
| if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { |
| const SkScalar tx = mx.getTranslateX(); |
| const SkScalar ty = mx.getTranslateY(); |
| if (tm <= SkMatrix::kTranslate_Mask) { |
| l += tx; |
| t += ty; |
| r += tx; |
| b += ty; |
| } else { |
| const SkScalar sx = mx.getScaleX(); |
| const SkScalar sy = mx.getScaleY(); |
| l = sx * l + tx; |
| t = sy * t + ty; |
| r = sx * r + tx; |
| b = sy * b + ty; |
| } |
| quad[0].setRectTriStrip(l, t, r, b, sizeof(SkPoint)); |
| } else { |
| quad[0].setRectTriStrip(l, t, r, b, sizeof(SkPoint)); |
| mx.mapPoints(quad, quad, 4); |
| } |
| } |
| }; |
| |
| #endif |