~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to third_party/skia/src/core/SkAlphaRuns.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* libs/graphics/sgl/SkAlphaRuns.cpp
 
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
#include "SkAntiRun.h"
 
19
 
 
20
void SkAlphaRuns::reset(int width)
 
21
{
 
22
    SkASSERT(width > 0);
 
23
 
 
24
    fRuns[0] = SkToS16(width);
 
25
    fRuns[width] = 0;
 
26
    fAlpha[0] = 0;
 
27
 
 
28
    SkDEBUGCODE(fWidth = width;)
 
29
    SkDEBUGCODE(this->validate();)
 
30
}
 
31
 
 
32
void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count)
 
33
{
 
34
    SkASSERT(count > 0 && x >= 0);
 
35
 
 
36
//  SkAlphaRuns::BreakAt(runs, alpha, x);
 
37
//  SkAlphaRuns::BreakAt(&runs[x], &alpha[x], count);
 
38
 
 
39
    int16_t* next_runs = runs + x;
 
40
    uint8_t*  next_alpha = alpha + x;
 
41
 
 
42
    while (x > 0)
 
43
    {
 
44
        int n = runs[0];
 
45
        SkASSERT(n > 0);
 
46
 
 
47
        if (x < n)
 
48
        {
 
49
            alpha[x] = alpha[0];
 
50
            runs[0] = SkToS16(x);
 
51
            runs[x] = SkToS16(n - x);
 
52
            break;
 
53
        }
 
54
        runs += n;
 
55
        alpha += n;
 
56
        x -= n;
 
57
    }
 
58
 
 
59
    runs = next_runs;
 
60
    alpha = next_alpha;
 
61
    x = count;
 
62
 
 
63
    for (;;)
 
64
    {
 
65
        int n = runs[0];
 
66
        SkASSERT(n > 0);
 
67
 
 
68
        if (x < n)
 
69
        {
 
70
            alpha[x] = alpha[0];
 
71
            runs[0] = SkToS16(x);
 
72
            runs[x] = SkToS16(n - x);
 
73
            break;
 
74
        }
 
75
        x -= n;
 
76
        if (x <= 0)
 
77
            break;
 
78
 
 
79
        runs += n;
 
80
        alpha += n;
 
81
    }
 
82
}
 
83
 
 
84
void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue)
 
85
{
 
86
    SkASSERT(middleCount >= 0);
 
87
    SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
 
88
 
 
89
    int16_t*    runs = fRuns;
 
90
    uint8_t*     alpha = fAlpha;
 
91
 
 
92
    if (startAlpha)
 
93
    {
 
94
        SkAlphaRuns::Break(runs, alpha, x, 1);
 
95
        /*  I should be able to just add alpha[x] + startAlpha.
 
96
            However, if the trailing edge of the previous span and the leading
 
97
            edge of the current span round to the same super-sampled x value,
 
98
            I might overflow to 256 with this add, hence the funny subtract (crud).
 
99
        */
 
100
        unsigned tmp = alpha[x] + startAlpha;
 
101
        SkASSERT(tmp <= 256);
 
102
        alpha[x] = SkToU8(tmp - (tmp >> 8));    // was (tmp >> 7), but that seems wrong if we're trying to catch 256
 
103
 
 
104
        runs += x + 1;
 
105
        alpha += x + 1;
 
106
        x = 0;
 
107
        SkDEBUGCODE(this->validate();)
 
108
    }
 
109
    if (middleCount)
 
110
    {
 
111
        SkAlphaRuns::Break(runs, alpha, x, middleCount);
 
112
        alpha += x;
 
113
        runs += x;
 
114
        x = 0;
 
115
        do {
 
116
            alpha[0] = SkToU8(alpha[0] + maxValue);
 
117
            int n = runs[0];
 
118
            SkASSERT(n <= middleCount);
 
119
            alpha += n;
 
120
            runs += n;
 
121
            middleCount -= n;
 
122
        } while (middleCount > 0);
 
123
        SkDEBUGCODE(this->validate();)
 
124
    }
 
125
    if (stopAlpha)
 
126
    {
 
127
        SkAlphaRuns::Break(runs, alpha, x, 1);
 
128
        alpha[x] = SkToU8(alpha[x] + stopAlpha);
 
129
        SkDEBUGCODE(this->validate();)
 
130
    }
 
131
}
 
132
 
 
133
#ifdef SK_DEBUG
 
134
    void SkAlphaRuns::assertValid(int y, int maxStep) const
 
135
    {
 
136
        int max = (y + 1) * maxStep - (y == maxStep - 1);
 
137
 
 
138
        const int16_t* runs = fRuns;
 
139
        const uint8_t*   alpha = fAlpha;
 
140
 
 
141
        while (*runs)
 
142
        {
 
143
            SkASSERT(*alpha <= max);
 
144
            alpha += *runs;
 
145
            runs += *runs;
 
146
        }
 
147
    }
 
148
 
 
149
    void SkAlphaRuns::dump() const
 
150
    {
 
151
        const int16_t* runs = fRuns;
 
152
        const uint8_t* alpha = fAlpha;
 
153
 
 
154
        SkDebugf("Runs");
 
155
        while (*runs)
 
156
        {
 
157
            int n = *runs;
 
158
 
 
159
            SkDebugf(" %02x", *alpha);
 
160
            if (n > 1)
 
161
                SkDebugf(",%d", n);
 
162
            alpha += n;
 
163
            runs += n;
 
164
        }
 
165
        SkDebugf("\n");
 
166
    }
 
167
 
 
168
    void SkAlphaRuns::validate() const
 
169
    {
 
170
        SkASSERT(fWidth > 0);
 
171
 
 
172
        int         count = 0;
 
173
        const int16_t*  runs = fRuns;
 
174
 
 
175
        while (*runs)
 
176
        {
 
177
            SkASSERT(*runs > 0);
 
178
            count += *runs;
 
179
            SkASSERT(count <= fWidth);
 
180
            runs += *runs;
 
181
        }
 
182
        SkASSERT(count == fWidth);
 
183
    }
 
184
#endif
 
185