Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2013 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 SkBitmapProcState_MatrixTemplates_DEFINED
      9 #define SkBitmapProcState_MatrixTemplates_DEFINED
     10 
     11 #include "SkMath.h"
     12 #include "SkMathPriv.h"
     13 
     14 template <typename TileProc, bool tryDecal>
     15 void NoFilterProc_Scale(const SkBitmapProcState& s, uint32_t xy[],
     16                         int count, int x, int y) {
     17     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
     18                              SkMatrix::kScale_Mask)) == 0);
     19 
     20     // we store y, x, x, x, x, x
     21 
     22     const unsigned maxX = s.fBitmap->width() - 1;
     23     SkFractionalInt fx;
     24     {
     25         SkPoint pt;
     26         s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
     27                                   SkIntToScalar(y) + SK_ScalarHalf, &pt);
     28         fx = SkScalarToFractionalInt(pt.fY);
     29         const unsigned maxY = s.fBitmap->height() - 1;
     30         *xy++ = TileProc::Y(s, SkFractionalIntToFixed(fx), maxY);
     31         fx = SkScalarToFractionalInt(pt.fX);
     32     }
     33 
     34     if (0 == maxX) {
     35         // all of the following X values must be 0
     36         memset(xy, 0, count * sizeof(uint16_t));
     37         return;
     38     }
     39 
     40     const SkFractionalInt dx = s.fInvSxFractionalInt;
     41 
     42     if (tryDecal && can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
     43         decal_nofilter_scale(xy, SkFractionalIntToFixed(fx),
     44                              SkFractionalIntToFixed(dx), count);
     45     } else {
     46         int i;
     47         for (i = (count >> 2); i > 0; --i) {
     48             unsigned a, b;
     49             a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
     50             b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
     51 #ifdef SK_CPU_BENDIAN
     52             *xy++ = (a << 16) | b;
     53 #else
     54             *xy++ = (b << 16) | a;
     55 #endif
     56             a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
     57             b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
     58 #ifdef SK_CPU_BENDIAN
     59             *xy++ = (a << 16) | b;
     60 #else
     61             *xy++ = (b << 16) | a;
     62 #endif
     63         }
     64         uint16_t* xx = (uint16_t*)xy;
     65         for (i = (count & 3); i > 0; --i) {
     66             *xx++ = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
     67         }
     68     }
     69 }
     70 
     71 // note: we could special-case on a matrix which is skewed in X but not Y.
     72 // this would require a more general setup thatn SCALE does, but could use
     73 // SCALE's inner loop that only looks at dx
     74 
     75 template <typename TileProc>
     76 void NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[],
     77                          int count, int x, int y) {
     78     SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
     79     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
     80                              SkMatrix::kScale_Mask |
     81                              SkMatrix::kAffine_Mask)) == 0);
     82 
     83     SkPoint srcPt;
     84     s.fInvProc(s.fInvMatrix,
     85                SkIntToScalar(x) + SK_ScalarHalf,
     86                SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
     87 
     88     SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX);
     89     SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY);
     90     SkFractionalInt dx = s.fInvSxFractionalInt;
     91     SkFractionalInt dy = s.fInvKyFractionalInt;
     92     int maxX = s.fBitmap->width() - 1;
     93     int maxY = s.fBitmap->height() - 1;
     94 
     95     for (int i = count; i > 0; --i) {
     96         *xy++ = (TileProc::Y(s, SkFractionalIntToFixed(fy), maxY) << 16) |
     97                  TileProc::X(s, SkFractionalIntToFixed(fx), maxX);
     98         fx += dx; fy += dy;
     99     }
    100 }
    101 
    102 template <typename TileProc>
    103 void NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy,
    104                         int count, int x, int y) {
    105     SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
    106 
    107     int maxX = s.fBitmap->width() - 1;
    108     int maxY = s.fBitmap->height() - 1;
    109 
    110     SkPerspIter   iter(s.fInvMatrix,
    111                        SkIntToScalar(x) + SK_ScalarHalf,
    112                        SkIntToScalar(y) + SK_ScalarHalf, count);
    113 
    114     while ((count = iter.next()) != 0) {
    115         const SkFixed* SK_RESTRICT srcXY = iter.getXY();
    116         while (--count >= 0) {
    117             *xy++ = (TileProc::Y(s, srcXY[1], maxY) << 16) |
    118                      TileProc::X(s, srcXY[0], maxX);
    119             srcXY += 2;
    120         }
    121     }
    122 }
    123 
    124 #endif
    125