• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
reset(int width)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 
Break(int16_t runs[],uint8_t alpha[],int x,int count)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 
add(int x,U8CPU startAlpha,int middleCount,U8CPU stopAlpha,U8CPU maxValue)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
assertValid(int y,int maxStep) const134     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 
dump() const149     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 
validate() const168     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 
186