1 /* libs/graphics/sgl/SkBitmapSampler.h
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #ifndef SkBitmapSampler_DEFINED
19 #define SkBitmapSampler_DEFINED
20
21 #include "SkBitmap.h"
22 #include "SkPaint.h"
23 #include "SkShader.h"
24
25 typedef int (*SkTileModeProc)(int value, unsigned max);
26
27 class SkBitmapSampler {
28 public:
29 SkBitmapSampler(const SkBitmap&, bool filter, SkShader::TileMode tmx, SkShader::TileMode tmy);
~SkBitmapSampler()30 virtual ~SkBitmapSampler() {}
31
getBitmap()32 const SkBitmap& getBitmap() const { return fBitmap; }
getFilterBitmap()33 bool getFilterBitmap() const { return fFilterBitmap; }
getTileModeX()34 SkShader::TileMode getTileModeX() const { return fTileModeX; }
getTileModeY()35 SkShader::TileMode getTileModeY() const { return fTileModeY; }
36
37 /** Given a pixel center at [x,y], return the color sample
38 */
39 virtual SkPMColor sample(SkFixed x, SkFixed y) const = 0;
40
41 virtual void setPaint(const SkPaint& paint);
42
43 // This is the factory for finding an optimal subclass
44 static SkBitmapSampler* Create(const SkBitmap&, bool filter,
45 SkShader::TileMode tmx, SkShader::TileMode tmy);
46
47 protected:
48 const SkBitmap& fBitmap;
49 uint16_t fMaxX, fMaxY;
50 bool fFilterBitmap;
51 SkShader::TileMode fTileModeX;
52 SkShader::TileMode fTileModeY;
53 SkTileModeProc fTileProcX;
54 SkTileModeProc fTileProcY;
55
56 // illegal
57 SkBitmapSampler& operator=(const SkBitmapSampler&);
58 };
59
fixed_clamp(SkFixed x)60 static inline int fixed_clamp(SkFixed x)
61 {
62 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
63 if (x >> 16)
64 x = 0xFFFF;
65 if (x < 0)
66 x = 0;
67 #else
68 if (x >> 16)
69 {
70 if (x < 0)
71 x = 0;
72 else
73 x = 0xFFFF;
74 }
75 #endif
76 return x;
77 }
78
79 //////////////////////////////////////////////////////////////////////////////////////
80
fixed_repeat(SkFixed x)81 static inline int fixed_repeat(SkFixed x)
82 {
83 return x & 0xFFFF;
84 }
85
fixed_mirror(SkFixed x)86 static inline int fixed_mirror(SkFixed x)
87 {
88 SkFixed s = x << 15 >> 31;
89 // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval
90 return (x ^ s) & 0xFFFF;
91 }
92
is_pow2(int count)93 static inline bool is_pow2(int count)
94 {
95 SkASSERT(count > 0);
96 return (count & (count - 1)) == 0;
97 }
98
do_clamp(int index,unsigned max)99 static inline int do_clamp(int index, unsigned max)
100 {
101 SkASSERT((int)max >= 0);
102
103 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
104 if (index > (int)max)
105 index = max;
106 if (index < 0)
107 index = 0;
108 #else
109 if ((unsigned)index > max)
110 {
111 if (index < 0)
112 index = 0;
113 else
114 index = max;
115 }
116 #endif
117 return index;
118 }
119
do_repeat_mod(int index,unsigned max)120 static inline int do_repeat_mod(int index, unsigned max)
121 {
122 SkASSERT((int)max >= 0);
123
124 if ((unsigned)index > max)
125 {
126 if (index < 0)
127 index = max - (~index % (max + 1));
128 else
129 index = index % (max + 1);
130 }
131 return index;
132 }
133
do_repeat_pow2(int index,unsigned max)134 static inline int do_repeat_pow2(int index, unsigned max)
135 {
136 SkASSERT((int)max >= 0 && is_pow2(max + 1));
137
138 return index & max;
139 }
140
do_mirror_mod(int index,unsigned max)141 static inline int do_mirror_mod(int index, unsigned max)
142 {
143 SkASSERT((int)max >= 0);
144
145 // have to handle negatives so that
146 // -1 -> 0, -2 -> 1, -3 -> 2, etc.
147 // so we can't just cal abs
148 index ^= index >> 31;
149
150 if ((unsigned)index > max)
151 {
152 int mod = (max + 1) << 1;
153 index = index % mod;
154 if ((unsigned)index > max)
155 index = mod - index - 1;
156 }
157 return index;
158 }
159
do_mirror_pow2(int index,unsigned max)160 static inline int do_mirror_pow2(int index, unsigned max)
161 {
162 SkASSERT((int)max >= 0 && is_pow2(max + 1));
163
164 int s = (index & (max + 1)) - 1;
165 s = ~(s >> 31);
166 // at this stage, s is FFFFFFFF if we're on an odd interval, or 0 if an even interval
167 return (index ^ s) & max;
168 }
169
170 #endif
171