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.fPixmap.width() - 1; 59 const SkFixed one = s.fFilterOneX; 60 const SkFractionalInt dx = s.fInvSxFractionalInt; 61 SkFractionalInt fx; 62 63 { 64 const SkBitmapProcStateAutoMapper mapper(s, x, y); 65 const SkFixed fy = mapper.fixedY(); 66 const unsigned maxY = s.fPixmap.height() - 1; 67 // compute our two Y values up front 68 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); 69 // now initialize fx 70 fx = mapper.fractionalIntX(); 71 } 72 73 #ifdef CHECK_FOR_DECAL 74 if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { 75 decal_filter_scale(xy, SkFractionalIntToFixed(fx), 76 SkFractionalIntToFixed(dx), count); 77 } else 78 #endif 79 { 80 do { 81 SkFixed fixedFx = SkFractionalIntToFixed(fx); 82 *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X); 83 fx += dx; 84 } while (--count != 0); 85 } 86 } 87 88 void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 89 uint32_t xy[], int count, int x, int y) { 90 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); 91 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 92 SkMatrix::kScale_Mask | 93 SkMatrix::kAffine_Mask)) == 0); 94 95 PREAMBLE(s); 96 const SkBitmapProcStateAutoMapper mapper(s, x, y); 97 98 SkFixed oneX = s.fFilterOneX; 99 SkFixed oneY = s.fFilterOneY; 100 SkFixed fx = mapper.fixedX(); 101 SkFixed fy = mapper.fixedY(); 102 SkFixed dx = s.fInvSx; 103 SkFixed dy = s.fInvKy; 104 unsigned maxX = s.fPixmap.width() - 1; 105 unsigned maxY = s.fPixmap.height() - 1; 106 107 do { 108 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); 109 fy += dy; 110 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); 111 fx += dx; 112 } while (--count != 0); 113 } 114 115 void PERSP_FILTER_NAME(const SkBitmapProcState& s, 116 uint32_t* SK_RESTRICT xy, int count, 117 int x, int y) { 118 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 119 120 PREAMBLE(s); 121 unsigned maxX = s.fPixmap.width() - 1; 122 unsigned maxY = s.fPixmap.height() - 1; 123 SkFixed oneX = s.fFilterOneX; 124 SkFixed oneY = s.fFilterOneY; 125 126 SkPerspIter iter(s.fInvMatrix, 127 SkIntToScalar(x) + SK_ScalarHalf, 128 SkIntToScalar(y) + SK_ScalarHalf, count); 129 130 while ((count = iter.next()) != 0) { 131 const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 132 do { 133 *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY, 134 oneY PREAMBLE_ARG_Y); 135 *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX, 136 oneX PREAMBLE_ARG_X); 137 srcXY += 2; 138 } while (--count != 0); 139 } 140 } 141 142 #undef MAKENAME 143 #undef TILEX_PROCF 144 #undef TILEY_PROCF 145 #ifdef CHECK_FOR_DECAL 146 #undef CHECK_FOR_DECAL 147 #endif 148 149 #undef SCALE_FILTER_NAME 150 #undef AFFINE_FILTER_NAME 151 #undef PERSP_FILTER_NAME 152 153 #undef PREAMBLE 154 #undef PREAMBLE_PARAM_X 155 #undef PREAMBLE_PARAM_Y 156 #undef PREAMBLE_ARG_X 157 #undef PREAMBLE_ARG_Y 158 159 #undef TILEX_LOW_BITS 160 #undef TILEY_LOW_BITS 161