1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
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 :
10 : #ifndef SkBitmapSampler_DEFINED
11 : #define SkBitmapSampler_DEFINED
12 :
13 : #include "SkBitmap.h"
14 : #include "SkPaint.h"
15 : #include "SkShader.h"
16 :
17 : typedef int (*SkTileModeProc)(int value, unsigned max);
18 :
19 : class SkBitmapSampler {
20 : public:
21 : SkBitmapSampler(const SkBitmap&, bool filter, SkShader::TileMode tmx, SkShader::TileMode tmy);
22 0 : virtual ~SkBitmapSampler() {}
23 :
24 : const SkBitmap& getBitmap() const { return fBitmap; }
25 : bool getFilterBitmap() const { return fFilterBitmap; }
26 : SkShader::TileMode getTileModeX() const { return fTileModeX; }
27 : SkShader::TileMode getTileModeY() const { return fTileModeY; }
28 :
29 : /** Given a pixel center at [x,y], return the color sample
30 : */
31 : virtual SkPMColor sample(SkFixed x, SkFixed y) const = 0;
32 :
33 : virtual void setPaint(const SkPaint& paint);
34 :
35 : // This is the factory for finding an optimal subclass
36 : static SkBitmapSampler* Create(const SkBitmap&, bool filter,
37 : SkShader::TileMode tmx, SkShader::TileMode tmy);
38 :
39 : protected:
40 : const SkBitmap& fBitmap;
41 : uint16_t fMaxX, fMaxY;
42 : bool fFilterBitmap;
43 : SkShader::TileMode fTileModeX;
44 : SkShader::TileMode fTileModeY;
45 : SkTileModeProc fTileProcX;
46 : SkTileModeProc fTileProcY;
47 :
48 : // illegal
49 : SkBitmapSampler& operator=(const SkBitmapSampler&);
50 : };
51 :
52 : static inline int fixed_clamp(SkFixed x)
53 : {
54 : #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
55 : if (x >> 16)
56 : x = 0xFFFF;
57 : if (x < 0)
58 : x = 0;
59 : #else
60 : if (x >> 16)
61 : {
62 : if (x < 0)
63 : x = 0;
64 : else
65 : x = 0xFFFF;
66 : }
67 : #endif
68 : return x;
69 : }
70 :
71 : //////////////////////////////////////////////////////////////////////////////////////
72 :
73 : static inline int fixed_repeat(SkFixed x)
74 : {
75 : return x & 0xFFFF;
76 : }
77 :
78 : static inline int fixed_mirror(SkFixed x)
79 : {
80 : SkFixed s = x << 15 >> 31;
81 : // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval
82 : return (x ^ s) & 0xFFFF;
83 : }
84 :
85 0 : static inline bool is_pow2(int count)
86 : {
87 0 : SkASSERT(count > 0);
88 0 : return (count & (count - 1)) == 0;
89 : }
90 :
91 0 : static inline int do_clamp(int index, unsigned max)
92 : {
93 0 : SkASSERT((int)max >= 0);
94 :
95 : #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
96 : if (index > (int)max)
97 : index = max;
98 : if (index < 0)
99 : index = 0;
100 : #else
101 0 : if ((unsigned)index > max)
102 : {
103 0 : if (index < 0)
104 0 : index = 0;
105 : else
106 0 : index = max;
107 : }
108 : #endif
109 0 : return index;
110 : }
111 :
112 0 : static inline int do_repeat_mod(int index, unsigned max)
113 : {
114 0 : SkASSERT((int)max >= 0);
115 :
116 0 : if ((unsigned)index > max)
117 : {
118 0 : if (index < 0)
119 0 : index = max - (~index % (max + 1));
120 : else
121 0 : index = index % (max + 1);
122 : }
123 0 : return index;
124 : }
125 :
126 0 : static inline int do_repeat_pow2(int index, unsigned max)
127 : {
128 0 : SkASSERT((int)max >= 0 && is_pow2(max + 1));
129 :
130 0 : return index & max;
131 : }
132 :
133 0 : static inline int do_mirror_mod(int index, unsigned max)
134 : {
135 0 : SkASSERT((int)max >= 0);
136 :
137 : // have to handle negatives so that
138 : // -1 -> 0, -2 -> 1, -3 -> 2, etc.
139 : // so we can't just cal abs
140 0 : index ^= index >> 31;
141 :
142 0 : if ((unsigned)index > max)
143 : {
144 0 : int mod = (max + 1) << 1;
145 0 : index = index % mod;
146 0 : if ((unsigned)index > max)
147 0 : index = mod - index - 1;
148 : }
149 0 : return index;
150 : }
151 :
152 0 : static inline int do_mirror_pow2(int index, unsigned max)
153 : {
154 0 : SkASSERT((int)max >= 0 && is_pow2(max + 1));
155 :
156 0 : int s = (index & (max + 1)) - 1;
157 0 : s = ~(s >> 31);
158 : // at this stage, s is FFFFFFFF if we're on an odd interval, or 0 if an even interval
159 0 : return (index ^ s) & max;
160 : }
161 :
162 : #endif
|