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