Home | History | Annotate | Download | only in core
      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