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 
13 #define PACK_FILTER_X_NAME  MAKENAME(_pack_filter_x)
14 #define PACK_FILTER_Y_NAME  MAKENAME(_pack_filter_y)
15 
16 #ifndef PREAMBLE
17     #define PREAMBLE(state)
18     #define PREAMBLE_PARAM_X
19     #define PREAMBLE_PARAM_Y
20     #define PREAMBLE_ARG_X
21     #define PREAMBLE_ARG_Y
22 #endif
23 
24 // declare functions externally to suppress warnings.
25 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
26                               uint32_t xy[], int count, int x, int y);
27 
28 static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
29                                           SkFixed one PREAMBLE_PARAM_Y) {
30     unsigned i = TILEY_PROCF(f, max);
31     i = (i << 4) | EXTRACT_LOW_BITS(f, max);
32     return (i << 14) | (TILEY_PROCF((f + one), max));
33 }
34 
35 static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
36                                           SkFixed one PREAMBLE_PARAM_X) {
37     unsigned i = TILEX_PROCF(f, max);
38     i = (i << 4) | EXTRACT_LOW_BITS(f, max);
39     return (i << 14) | (TILEX_PROCF((f + one), max));
40 }
41 
42 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
43                               uint32_t xy[], int count, int x, int y) {
44     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
45                              SkMatrix::kScale_Mask)) == 0);
46     SkASSERT(s.fInvKy == 0);
47 
48     PREAMBLE(s);
49 
50     const unsigned maxX = s.fPixmap.width() - 1;
51     const SkFixed one = s.fFilterOneX;
52     const SkFractionalInt dx = s.fInvSxFractionalInt;
53     SkFractionalInt fx;
54 
55     {
56         const SkBitmapProcStateAutoMapper mapper(s, x, y);
57         const SkFixed fy = mapper.fixedY();
58         const unsigned maxY = s.fPixmap.height() - 1;
59         // compute our two Y values up front
60         *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
61         // now initialize fx
62         fx = mapper.fractionalIntX();
63     }
64 
65 #ifdef CHECK_FOR_DECAL
66     const SkFixed fixedFx = SkFractionalIntToFixed(fx);
67     const SkFixed fixedDx = SkFractionalIntToFixed(dx);
68     if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) {
69         decal_filter_scale(xy, fixedFx, fixedDx, count);
70     } else
71 #endif
72     {
73         do {
74             SkFixed fixedFx = SkFractionalIntToFixed(fx);
75             *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X);
76             fx += dx;
77         } while (--count != 0);
78     }
79 }
80 
81 #undef MAKENAME
82 #undef TILEX_PROCF
83 #undef TILEY_PROCF
84 #ifdef CHECK_FOR_DECAL
85     #undef CHECK_FOR_DECAL
86 #endif
87 
88 #undef SCALE_FILTER_NAME
89 
90 #undef PREAMBLE
91 #undef PREAMBLE_PARAM_X
92 #undef PREAMBLE_PARAM_Y
93 #undef PREAMBLE_ARG_X
94 #undef PREAMBLE_ARG_Y
95 
96 #undef EXTRACT_LOW_BITS
97