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