Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "SkMath.h"
     10 #include "SkMathPriv.h"
     11 
     12 #define SCALE_FILTER_NAME       MAKENAME(_filter_scale)
     13 #define AFFINE_FILTER_NAME      MAKENAME(_filter_affine)
     14 #define PERSP_FILTER_NAME       MAKENAME(_filter_persp)
     15 
     16 #define PACK_FILTER_X_NAME  MAKENAME(_pack_filter_x)
     17 #define PACK_FILTER_Y_NAME  MAKENAME(_pack_filter_y)
     18 
     19 #ifndef PREAMBLE
     20     #define PREAMBLE(state)
     21     #define PREAMBLE_PARAM_X
     22     #define PREAMBLE_PARAM_Y
     23     #define PREAMBLE_ARG_X
     24     #define PREAMBLE_ARG_Y
     25 #endif
     26 
     27 // declare functions externally to suppress warnings.
     28 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
     29                               uint32_t xy[], int count, int x, int y);
     30 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
     31                                uint32_t xy[], int count, int x, int y);
     32 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
     33                               uint32_t* SK_RESTRICT xy, int count,
     34                               int x, int y);
     35 
     36 static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
     37                                           SkFixed one PREAMBLE_PARAM_Y) {
     38     unsigned i = TILEY_PROCF(f, max);
     39     i = (i << 4) | TILEY_LOW_BITS(f, max);
     40     return (i << 14) | (TILEY_PROCF((f + one), max));
     41 }
     42 
     43 static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
     44                                           SkFixed one PREAMBLE_PARAM_X) {
     45     unsigned i = TILEX_PROCF(f, max);
     46     i = (i << 4) | TILEX_LOW_BITS(f, max);
     47     return (i << 14) | (TILEX_PROCF((f + one), max));
     48 }
     49 
     50 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
     51                               uint32_t xy[], int count, int x, int y) {
     52     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
     53                              SkMatrix::kScale_Mask)) == 0);
     54     SkASSERT(s.fInvKy == 0);
     55 
     56     PREAMBLE(s);
     57 
     58     const unsigned maxX = s.fBitmap->width() - 1;
     59     const SkFixed one = s.fFilterOneX;
     60     const SkFractionalInt dx = s.fInvSxFractionalInt;
     61     SkFractionalInt fx;
     62 
     63     {
     64         SkPoint pt;
     65         s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
     66                                   SkIntToScalar(y) + SK_ScalarHalf, &pt);
     67         const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1);
     68         const unsigned maxY = s.fBitmap->height() - 1;
     69         // compute our two Y values up front
     70         *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
     71         // now initialize fx
     72         fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1);
     73     }
     74 
     75 #ifdef CHECK_FOR_DECAL
     76     if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
     77         decal_filter_scale(xy, SkFractionalIntToFixed(fx),
     78                            SkFractionalIntToFixed(dx), count);
     79     } else
     80 #endif
     81     {
     82         do {
     83             SkFixed fixedFx = SkFractionalIntToFixed(fx);
     84             *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X);
     85             fx += dx;
     86         } while (--count != 0);
     87     }
     88 }
     89 
     90 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
     91                                uint32_t xy[], int count, int x, int y) {
     92     SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
     93     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
     94                              SkMatrix::kScale_Mask |
     95                              SkMatrix::kAffine_Mask)) == 0);
     96 
     97     PREAMBLE(s);
     98     SkPoint srcPt;
     99     s.fInvProc(s.fInvMatrix,
    100                SkIntToScalar(x) + SK_ScalarHalf,
    101                SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
    102 
    103     SkFixed oneX = s.fFilterOneX;
    104     SkFixed oneY = s.fFilterOneY;
    105     SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
    106     SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
    107     SkFixed dx = s.fInvSx;
    108     SkFixed dy = s.fInvKy;
    109     unsigned maxX = s.fBitmap->width() - 1;
    110     unsigned maxY = s.fBitmap->height() - 1;
    111 
    112     do {
    113         *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
    114         fy += dy;
    115         *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
    116         fx += dx;
    117     } while (--count != 0);
    118 }
    119 
    120 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
    121                               uint32_t* SK_RESTRICT xy, int count,
    122                               int x, int y) {
    123     SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
    124 
    125     PREAMBLE(s);
    126     unsigned maxX = s.fBitmap->width() - 1;
    127     unsigned maxY = s.fBitmap->height() - 1;
    128     SkFixed oneX = s.fFilterOneX;
    129     SkFixed oneY = s.fFilterOneY;
    130 
    131     SkPerspIter   iter(s.fInvMatrix,
    132                        SkIntToScalar(x) + SK_ScalarHalf,
    133                        SkIntToScalar(y) + SK_ScalarHalf, count);
    134 
    135     while ((count = iter.next()) != 0) {
    136         const SkFixed* SK_RESTRICT srcXY = iter.getXY();
    137         do {
    138             *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY,
    139                                        oneY PREAMBLE_ARG_Y);
    140             *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX,
    141                                        oneX PREAMBLE_ARG_X);
    142             srcXY += 2;
    143         } while (--count != 0);
    144     }
    145 }
    146 
    147 #undef MAKENAME
    148 #undef TILEX_PROCF
    149 #undef TILEY_PROCF
    150 #ifdef CHECK_FOR_DECAL
    151     #undef CHECK_FOR_DECAL
    152 #endif
    153 
    154 #undef SCALE_FILTER_NAME
    155 #undef AFFINE_FILTER_NAME
    156 #undef PERSP_FILTER_NAME
    157 
    158 #undef PREAMBLE
    159 #undef PREAMBLE_PARAM_X
    160 #undef PREAMBLE_PARAM_Y
    161 #undef PREAMBLE_ARG_X
    162 #undef PREAMBLE_ARG_Y
    163 
    164 #undef TILEX_LOW_BITS
    165 #undef TILEY_LOW_BITS
    166