OLD | NEW |
| (Empty) |
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 (cru
d). | |
99 */ | |
100 unsigned tmp = alpha[x] + startAlpha; | |
101 SkASSERT(tmp <= 256); | |
102 alpha[x] = SkToU8(tmp - (tmp >> 8)); // was (tmp >> 7), but that seem
s 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 | |
OLD | NEW |