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 17typedef int (*SkTileModeProc)(int value, unsigned max); 18 19class SkBitmapSampler { 20public: 21 SkBitmapSampler(const SkBitmap&, bool filter, SkShader::TileMode tmx, SkShader::TileMode tmy); 22 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 39protected: 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 52static 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 73static inline int fixed_repeat(SkFixed x) 74{ 75 return x & 0xFFFF; 76} 77 78static 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 85static inline bool is_pow2(int count) 86{ 87 SkASSERT(count > 0); 88 return (count & (count - 1)) == 0; 89} 90 91static 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 112static 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 126static 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 133static 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 152static 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