1 /*
2 * Copyright 2011 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 #include "SkMath.h"
9 #include "SkMathPriv.h"
10
11 #define SCALE_FILTER_NAME MAKENAME(_filter_scale)
12 #define AFFINE_FILTER_NAME MAKENAME(_filter_affine)
13
14 #define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x)
15 #define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y)
16
17 #ifndef PREAMBLE
18 #define PREAMBLE(state)
19 #define PREAMBLE_PARAM_X
20 #define PREAMBLE_PARAM_Y
21 #define PREAMBLE_ARG_X
22 #define PREAMBLE_ARG_Y
23 #endif
24
25 // declare functions externally to suppress warnings.
26 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
27 uint32_t xy[], int count, int x, int y);
28 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
29 uint32_t xy[], int count, int x, int y);
30
PACK_FILTER_Y_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_Y)31 static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
32 SkFixed one PREAMBLE_PARAM_Y) {
33 unsigned i = TILEY_PROCF(f, max);
34 i = (i << 4) | EXTRACT_LOW_BITS(f, max);
35 return (i << 14) | (TILEY_PROCF((f + one), max));
36 }
37
PACK_FILTER_X_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_X)38 static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
39 SkFixed one PREAMBLE_PARAM_X) {
40 unsigned i = TILEX_PROCF(f, max);
41 i = (i << 4) | EXTRACT_LOW_BITS(f, max);
42 return (i << 14) | (TILEX_PROCF((f + one), max));
43 }
44
SCALE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)45 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
46 uint32_t xy[], int count, int x, int y) {
47 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
48 SkMatrix::kScale_Mask)) == 0);
49 SkASSERT(s.fInvKy == 0);
50
51 PREAMBLE(s);
52
53 const unsigned maxX = s.fPixmap.width() - 1;
54 const SkFixed one = s.fFilterOneX;
55 const SkFractionalInt dx = s.fInvSxFractionalInt;
56 SkFractionalInt fx;
57
58 {
59 const SkBitmapProcStateAutoMapper mapper(s, x, y);
60 const SkFixed fy = mapper.fixedY();
61 const unsigned maxY = s.fPixmap.height() - 1;
62 // compute our two Y values up front
63 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
64 // now initialize fx
65 fx = mapper.fractionalIntX();
66 }
67
68 #ifdef CHECK_FOR_DECAL
69 const SkFixed fixedFx = SkFractionalIntToFixed(fx);
70 const SkFixed fixedDx = SkFractionalIntToFixed(dx);
71 if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) {
72 decal_filter_scale(xy, fixedFx, fixedDx, count);
73 } else
74 #endif
75 {
76 do {
77 SkFixed fixedFx = SkFractionalIntToFixed(fx);
78 *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X);
79 fx += dx;
80 } while (--count != 0);
81 }
82 }
83
AFFINE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)84 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
85 uint32_t xy[], int count, int x, int y) {
86 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
87 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
88 SkMatrix::kScale_Mask |
89 SkMatrix::kAffine_Mask)) == 0);
90
91 PREAMBLE(s);
92 const SkBitmapProcStateAutoMapper mapper(s, x, y);
93
94 SkFixed oneX = s.fFilterOneX;
95 SkFixed oneY = s.fFilterOneY;
96 SkFixed fx = mapper.fixedX();
97 SkFixed fy = mapper.fixedY();
98 SkFixed dx = s.fInvSx;
99 SkFixed dy = s.fInvKy;
100 unsigned maxX = s.fPixmap.width() - 1;
101 unsigned maxY = s.fPixmap.height() - 1;
102
103 do {
104 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
105 fy += dy;
106 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
107 fx += dx;
108 } while (--count != 0);
109 }
110
111 #undef MAKENAME
112 #undef TILEX_PROCF
113 #undef TILEY_PROCF
114 #ifdef CHECK_FOR_DECAL
115 #undef CHECK_FOR_DECAL
116 #endif
117
118 #undef SCALE_FILTER_NAME
119 #undef AFFINE_FILTER_NAME
120
121 #undef PREAMBLE
122 #undef PREAMBLE_PARAM_X
123 #undef PREAMBLE_PARAM_Y
124 #undef PREAMBLE_ARG_X
125 #undef PREAMBLE_ARG_Y
126
127 #undef EXTRACT_LOW_BITS
128