• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
~SkBitmapSampler()22     virtual ~SkBitmapSampler() {}
23 
getBitmap()24     const SkBitmap&     getBitmap() const { return fBitmap; }
getFilterBitmap()25     bool                getFilterBitmap() const { return fFilterBitmap; }
getTileModeX()26     SkShader::TileMode  getTileModeX() const { return fTileModeX; }
getTileModeY()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 
fixed_clamp(SkFixed x)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 
fixed_repeat(SkFixed x)73 static inline int fixed_repeat(SkFixed x)
74 {
75     return x & 0xFFFF;
76 }
77 
fixed_mirror(SkFixed x)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 
is_pow2(int count)85 static inline bool is_pow2(int count)
86 {
87     SkASSERT(count > 0);
88     return (count & (count - 1)) == 0;
89 }
90 
do_clamp(int index,unsigned max)91 static inline int do_clamp(int index, unsigned max)
92 {
93     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     if ((unsigned)index > max)
102     {
103         if (index < 0)
104             index = 0;
105         else
106             index = max;
107     }
108 #endif
109     return index;
110 }
111 
do_repeat_mod(int index,unsigned max)112 static inline int do_repeat_mod(int index, unsigned max)
113 {
114     SkASSERT((int)max >= 0);
115 
116     if ((unsigned)index > max)
117     {
118         if (index < 0)
119             index = max - (~index % (max + 1));
120         else
121             index = index % (max + 1);
122     }
123     return index;
124 }
125 
do_repeat_pow2(int index,unsigned max)126 static inline int do_repeat_pow2(int index, unsigned max)
127 {
128     SkASSERT((int)max >= 0 && is_pow2(max + 1));
129 
130     return index & max;
131 }
132 
do_mirror_mod(int index,unsigned max)133 static inline int do_mirror_mod(int index, unsigned max)
134 {
135     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     index ^= index >> 31;
141 
142     if ((unsigned)index > max)
143     {
144         int mod = (max + 1) << 1;
145         index = index % mod;
146         if ((unsigned)index > max)
147             index = mod - index - 1;
148     }
149     return index;
150 }
151 
do_mirror_pow2(int index,unsigned max)152 static inline int do_mirror_pow2(int index, unsigned max)
153 {
154     SkASSERT((int)max >= 0 && is_pow2(max + 1));
155 
156     int s = (index & (max + 1)) - 1;
157     s = ~(s >> 31);
158     // at this stage, s is FFFFFFFF if we're on an odd interval, or 0 if an even interval
159     return (index ^ s) & max;
160 }
161 
162 #endif
163