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); 30 virtual ~SkBitmapSampler() {} 31 32 const SkBitmap& getBitmap() const { return fBitmap; } 33 bool getFilterBitmap() const { return fFilterBitmap; } 34 SkShader::TileMode getTileModeX() const { return fTileModeX; } 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 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 81 static inline int fixed_repeat(SkFixed x) 82 { 83 return x & 0xFFFF; 84 } 85 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 93 static inline bool is_pow2(int count) 94 { 95 SkASSERT(count > 0); 96 return (count & (count - 1)) == 0; 97 } 98 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 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 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 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 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