Home | History | Annotate | Download | only in core
      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     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 static inline bool is_pow2(int count)
     86 {
     87     SkASSERT(count > 0);
     88     return (count & (count - 1)) == 0;
     89 }
     90 
     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 
    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 
    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 
    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 
    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