11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkBitmapSampler_DEFINED 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkBitmapSampler_DEFINED 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBitmap.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h" 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h" 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef int (*SkTileModeProc)(int value, unsigned max); 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkBitmapSampler { 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBitmapSampler(const SkBitmap&, bool filter, SkShader::TileMode tmx, SkShader::TileMode tmy); 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual ~SkBitmapSampler() {} 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkBitmap& getBitmap() const { return fBitmap; } 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool getFilterBitmap() const { return fFilterBitmap; } 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader::TileMode getTileModeX() const { return fTileModeX; } 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader::TileMode getTileModeY() const { return fTileModeY; } 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Given a pixel center at [x,y], return the color sample 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual SkPMColor sample(SkFixed x, SkFixed y) const = 0; 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void setPaint(const SkPaint& paint); 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // This is the factory for finding an optimal subclass 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkBitmapSampler* Create(const SkBitmap&, bool filter, 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader::TileMode tmx, SkShader::TileMode tmy); 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkBitmap& fBitmap; 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t fMaxX, fMaxY; 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fFilterBitmap; 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader::TileMode fTileModeX; 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader::TileMode fTileModeY; 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTileModeProc fTileProcX; 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTileModeProc fTileProcY; 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // illegal 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBitmapSampler& operator=(const SkBitmapSampler&); 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int fixed_clamp(SkFixed x) 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x >> 16) 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0xFFFF; 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x < 0) 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0; 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x >> 16) 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x < 0) 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0; 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0xFFFF; 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return x; 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////// 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int fixed_repeat(SkFixed x) 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return x & 0xFFFF; 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int fixed_mirror(SkFixed x) 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed s = x << 15 >> 31; 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (x ^ s) & 0xFFFF; 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool is_pow2(int count) 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count > 0); 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (count & (count - 1)) == 0; 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int do_clamp(int index, unsigned max) 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int)max >= 0); 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (index > (int)max) 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = max; 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (index < 0) 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = 0; 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if ((unsigned)index > max) 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (index < 0) 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = 0; 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = max; 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return index; 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int do_repeat_mod(int index, unsigned max) 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int)max >= 0); 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if ((unsigned)index > max) 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (index < 0) 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = max - (~index % (max + 1)); 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = index % (max + 1); 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return index; 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int do_repeat_pow2(int index, unsigned max) 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int)max >= 0 && is_pow2(max + 1)); 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return index & max; 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int do_mirror_mod(int index, unsigned max) 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int)max >= 0); 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // have to handle negatives so that 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // -1 -> 0, -2 -> 1, -3 -> 2, etc. 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // so we can't just cal abs 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index ^= index >> 31; 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if ((unsigned)index > max) 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int mod = (max + 1) << 1; 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = index % mod; 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if ((unsigned)index > max) 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = mod - index - 1; 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return index; 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int do_mirror_pow2(int index, unsigned max) 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int)max >= 0 && is_pow2(max + 1)); 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int s = (index & (max + 1)) - 1; 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project s = ~(s >> 31); 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // at this stage, s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (index ^ s) & max; 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 163