• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
reset(int width)13 void SkAlphaRuns::reset(int width) {
14     SkASSERT(width > 0);
15 
16 #ifdef SK_DEBUG
17     sk_memset16((uint16_t*)fRuns, (uint16_t)(-42), width);
18 #endif
19     fRuns[0] = SkToS16(width);
20     fRuns[width] = 0;
21     fAlpha[0] = 0;
22 
23     SkDEBUGCODE(fWidth = width;)
24     SkDEBUGCODE(this->validate();)
25 }
26 
Break(int16_t runs[],uint8_t alpha[],int x,int count)27 void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count) {
28     SkASSERT(count > 0 && x >= 0);
29 
30 //  SkAlphaRuns::BreakAt(runs, alpha, x);
31 //  SkAlphaRuns::BreakAt(&runs[x], &alpha[x], count);
32 
33     int16_t* next_runs = runs + x;
34     uint8_t*  next_alpha = alpha + x;
35 
36     while (x > 0) {
37         int n = runs[0];
38         SkASSERT(n > 0);
39 
40         if (x < n) {
41             alpha[x] = alpha[0];
42             runs[0] = SkToS16(x);
43             runs[x] = SkToS16(n - x);
44             break;
45         }
46         runs += n;
47         alpha += n;
48         x -= n;
49     }
50 
51     runs = next_runs;
52     alpha = next_alpha;
53     x = count;
54 
55     for (;;) {
56         int n = runs[0];
57         SkASSERT(n > 0);
58 
59         if (x < n) {
60             alpha[x] = alpha[0];
61             runs[0] = SkToS16(x);
62             runs[x] = SkToS16(n - x);
63             break;
64         }
65         x -= n;
66         if (x <= 0) {
67             break;
68         }
69         runs += n;
70         alpha += n;
71     }
72 }
73 
add(int x,U8CPU startAlpha,int middleCount,U8CPU stopAlpha,U8CPU maxValue,int offsetX)74 int SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
75                      U8CPU maxValue, int offsetX) {
76     SkASSERT(middleCount >= 0);
77     SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
78 
79     SkASSERT(fRuns[offsetX] >= 0);
80 
81     int16_t*    runs = fRuns + offsetX;
82     uint8_t*    alpha = fAlpha + offsetX;
83     uint8_t*    lastAlpha = alpha;
84     x -= offsetX;
85 
86     if (startAlpha) {
87         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         unsigned tmp = alpha[x] + startAlpha;
94         SkASSERT(tmp <= 256);
95         alpha[x] = SkToU8(tmp - (tmp >> 8));    // was (tmp >> 7), but that seems wrong if we're trying to catch 256
96 
97         runs += x + 1;
98         alpha += x + 1;
99         x = 0;
100         lastAlpha += x; // we don't want the +1
101         SkDEBUGCODE(this->validate();)
102     }
103 
104     if (middleCount) {
105         SkAlphaRuns::Break(runs, alpha, x, middleCount);
106         alpha += x;
107         runs += x;
108         x = 0;
109         do {
110             alpha[0] = SkToU8(alpha[0] + maxValue);
111             int n = runs[0];
112             SkASSERT(n <= middleCount);
113             alpha += n;
114             runs += n;
115             middleCount -= n;
116         } while (middleCount > 0);
117         SkDEBUGCODE(this->validate();)
118         lastAlpha = alpha;
119     }
120 
121     if (stopAlpha) {
122         SkAlphaRuns::Break(runs, alpha, x, 1);
123         alpha += x;
124         alpha[0] = SkToU8(alpha[0] + stopAlpha);
125         SkDEBUGCODE(this->validate();)
126         lastAlpha = alpha;
127     }
128 
129     return lastAlpha - fAlpha;  // new offsetX
130 }
131 
132 #ifdef SK_DEBUG
assertValid(int y,int maxStep) const133     void SkAlphaRuns::assertValid(int y, int maxStep) const {
134         int max = (y + 1) * maxStep - (y == maxStep - 1);
135 
136         const int16_t* runs = fRuns;
137         const uint8_t*   alpha = fAlpha;
138 
139         while (*runs) {
140             SkASSERT(*alpha <= max);
141             alpha += *runs;
142             runs += *runs;
143         }
144     }
145 
dump() const146     void SkAlphaRuns::dump() const {
147         const int16_t* runs = fRuns;
148         const uint8_t* alpha = fAlpha;
149 
150         SkDebugf("Runs");
151         while (*runs) {
152             int n = *runs;
153 
154             SkDebugf(" %02x", *alpha);
155             if (n > 1) {
156                 SkDebugf(",%d", n);
157             }
158             alpha += n;
159             runs += n;
160         }
161         SkDebugf("\n");
162     }
163 
validate() const164     void SkAlphaRuns::validate() const {
165         SkASSERT(fWidth > 0);
166 
167         int         count = 0;
168         const int16_t*  runs = fRuns;
169 
170         while (*runs) {
171             SkASSERT(*runs > 0);
172             count += *runs;
173             SkASSERT(count <= fWidth);
174             runs += *runs;
175         }
176         SkASSERT(count == fWidth);
177     }
178 #endif
179 
180