1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/* 3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project 4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * 5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file. 7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */ 8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifndef SkBitmapSampler_DEFINED 11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#define SkBitmapSampler_DEFINED 12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkBitmap.h" 14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkPaint.h" 15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkShader.h" 16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergertypedef int (*SkTileModeProc)(int value, unsigned max); 18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkBitmapSampler { 20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkBitmapSampler(const SkBitmap&, bool filter, SkShader::TileMode tmx, SkShader::TileMode tmy); 22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual ~SkBitmapSampler() {} 23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkBitmap& getBitmap() const { return fBitmap; } 25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger bool getFilterBitmap() const { return fFilterBitmap; } 26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkShader::TileMode getTileModeX() const { return fTileModeX; } 27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkShader::TileMode getTileModeY() const { return fTileModeY; } 28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger /** Given a pixel center at [x,y], return the color sample 30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */ 31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual SkPMColor sample(SkFixed x, SkFixed y) const = 0; 32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void setPaint(const SkPaint& paint); 34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // This is the factory for finding an optimal subclass 36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static SkBitmapSampler* Create(const SkBitmap&, bool filter, 37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkShader::TileMode tmx, SkShader::TileMode tmy); 38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprotected: 40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkBitmap& fBitmap; 41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger uint16_t fMaxX, fMaxY; 42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger bool fFilterBitmap; 43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkShader::TileMode fTileModeX; 44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkShader::TileMode fTileModeY; 45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkTileModeProc fTileProcX; 46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkTileModeProc fTileProcY; 47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // illegal 49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkBitmapSampler& operator=(const SkBitmapSampler&); 50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int fixed_clamp(SkFixed x) 53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (x >> 16) 56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger x = 0xFFFF; 57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (x < 0) 58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger x = 0; 59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#else 60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (x >> 16) 61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (x < 0) 63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger x = 0; 64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger else 65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger x = 0xFFFF; 66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return x; 69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger////////////////////////////////////////////////////////////////////////////////////// 72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int fixed_repeat(SkFixed x) 74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return x & 0xFFFF; 76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int fixed_mirror(SkFixed x) 79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkFixed s = x << 15 >> 31; 81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return (x ^ s) & 0xFFFF; 83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline bool is_pow2(int count) 86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(count > 0); 88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return (count & (count - 1)) == 0; 89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int do_clamp(int index, unsigned max) 92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((int)max >= 0); 94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (index > (int)max) 97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = max; 98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (index < 0) 99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = 0; 100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#else 101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)index > max) 102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (index < 0) 104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = 0; 105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger else 106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = max; 107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return index; 110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int do_repeat_mod(int index, unsigned max) 113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((int)max >= 0); 115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)index > max) 117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (index < 0) 119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = max - (~index % (max + 1)); 120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger else 121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = index % (max + 1); 122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return index; 124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int do_repeat_pow2(int index, unsigned max) 127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((int)max >= 0 && is_pow2(max + 1)); 129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return index & max; 131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int do_mirror_mod(int index, unsigned max) 134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((int)max >= 0); 136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // have to handle negatives so that 138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // -1 -> 0, -2 -> 1, -3 -> 2, etc. 139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // so we can't just cal abs 140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index ^= index >> 31; 141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)index > max) 143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int mod = (max + 1) << 1; 145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = index % mod; 146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)index > max) 147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index = mod - index - 1; 148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return index; 150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int do_mirror_pow2(int index, unsigned max) 153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((int)max >= 0 && is_pow2(max + 1)); 155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int s = (index & (max + 1)) - 1; 157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger s = ~(s >> 31); 158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // at this stage, s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return (index ^ s) & max; 160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 163