Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2016 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkMatrixPriv_DEFINE
      9 #define SkMatrixPriv_DEFINE
     10 
     11 #include "SkMatrix.h"
     12 #include "SkNx.h"
     13 
     14 class SkMatrixPriv {
     15 public:
     16     /**
     17      *  Attempt to map the rect through the inverse of the matrix. If it is not invertible,
     18      *  then this returns false and dst is unchanged.
     19      */
     20     static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx,
     21                                                      SkRect* dst, const SkRect& src) {
     22         if (mx.getType() <= SkMatrix::kTranslate_Mask) {
     23             SkScalar tx = mx.getTranslateX();
     24             SkScalar ty = mx.getTranslateY();
     25             Sk4f trans(tx, ty, tx, ty);
     26             (Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft);
     27             return true;
     28         }
     29         // Insert other special-cases here (e.g. scale+translate)
     30 
     31         // general case
     32         SkMatrix inverse;
     33         if (mx.invert(&inverse)) {
     34             inverse.mapRect(dst, src);
     35             return true;
     36         }
     37         return false;
     38     }
     39 
     40     static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) {
     41         SkASSERT(stride >= sizeof(SkPoint));
     42         SkASSERT(0 == stride % sizeof(SkScalar));
     43 
     44         SkMatrix::TypeMask tm = mx.getType();
     45 
     46         if (SkMatrix::kIdentity_Mask == tm) {
     47             return;
     48         }
     49         if (SkMatrix::kTranslate_Mask == tm) {
     50             const SkScalar tx = mx.getTranslateX();
     51             const SkScalar ty = mx.getTranslateY();
     52             Sk2s trans(tx, ty);
     53             for (int i = 0; i < count; ++i) {
     54                 (Sk2s::Load(&pts->fX) + trans).store(&pts->fX);
     55                 pts = (SkPoint*)((intptr_t)pts + stride);
     56             }
     57             return;
     58         }
     59         // Insert other special-cases here (e.g. scale+translate)
     60 
     61         // general case
     62         SkMatrix::MapXYProc proc = mx.getMapXYProc();
     63         for (int i = 0; i < count; ++i) {
     64             proc(mx, pts->fX, pts->fY, pts);
     65             pts = (SkPoint*)((intptr_t)pts + stride);
     66         }
     67     }
     68 
     69     static void SetMappedRectFan(const SkMatrix& mx, const SkRect& rect, SkPoint quad[4]) {
     70         SkMatrix::TypeMask tm = mx.getType();
     71         SkScalar l = rect.fLeft;
     72         SkScalar t = rect.fTop;
     73         SkScalar r = rect.fRight;
     74         SkScalar b = rect.fBottom;
     75         if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
     76             const SkScalar tx = mx.getTranslateX();
     77             const SkScalar ty = mx.getTranslateY();
     78             if (tm <= SkMatrix::kTranslate_Mask) {
     79                 l += tx;
     80                 t += ty;
     81                 r += tx;
     82                 b += ty;
     83             } else {
     84                 const SkScalar sx = mx.getScaleX();
     85                 const SkScalar sy = mx.getScaleY();
     86                 l = sx * l + tx;
     87                 t = sy * t + ty;
     88                 r = sx * r + tx;
     89                 b = sy * b + ty;
     90             }
     91             quad[0].set(l, t);
     92             quad[1].set(l, b);
     93             quad[2].set(r, b);
     94             quad[3].set(r, t);
     95         } else {
     96             quad[0].setRectFan(l, t, r, b);
     97             mx.mapPoints(quad, quad, 4);
     98         }
     99     }
    100 };
    101 
    102 #endif
    103