• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/graphics/sgl/SkAntiRun.h
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 #ifndef SkAntiRun_DEFINED
19 #define SkAntiRun_DEFINED
20 
21 #include "SkBlitter.h"
22 
sk_make_nonzero_neg_one(int x)23 inline int sk_make_nonzero_neg_one(int x)
24 {
25     return (x | -x) >> 31;
26 }
27 
28 #if 0
29 template <int kShift> class SkAntiRun {
30     static uint8_t coverage_to_alpha(int aa)
31     {
32         aa <<= 8 - 2*kShift;
33         aa -= aa >> (8 - kShift - 1);
34         return SkToU8(aa);
35     }
36 public:
37     void set(int start, int stop)
38     {
39         SkASSERT(start >= 0 && stop > start);
40 
41 #if 1
42         int fb = start & kMask;
43         int fe = stop & kMask;
44         int n = (stop >> kShift) - (start >> kShift) - 1;
45 
46         if (n < 0)
47         {
48             fb = fe - fb;
49             n = 0;
50             fe = 0;
51         }
52         else
53         {
54             if (fb == 0)
55                 n += 1;
56             else
57                 fb = (1 << kShift) - fb;
58         }
59 
60         fStartAlpha = coverage_to_alpha(fb);
61         fMiddleCount = n;
62         fStopAlpha = coverage_to_alpha(fe);
63 #else
64         int x0 = start >> kShift;
65         int x1 = (stop - 1) >> kShift;
66         int middle = x1 - x0;
67         int aa;
68 
69         if (middle == 0)
70         {
71             aa = stop - start;
72             aa <<= 8 - 2*kShift;
73             aa -= aa >> (8 - kShift - 1);
74             SkASSERT(aa > 0 && aa < kMax);
75             fStartAlpha = SkToU8(aa);
76             fMiddleCount = 0;
77             fStopAlpha = 0;
78         }
79         else
80         {
81             int aa = start & kMask;
82             aa <<= 8 - 2*kShift;
83             aa -= aa >> (8 - kShift - 1);
84             SkASSERT(aa >= 0 && aa < kMax);
85             if (aa)
86                 fStartAlpha = SkToU8(kMax - aa);
87             else
88             {
89                 fStartAlpha = 0;
90                 middle += 1;
91             }
92             aa = stop & kMask;
93             aa <<= 8 - 2*kShift;
94             aa -= aa >> (8 - kShift - 1);
95             SkASSERT(aa >= 0 && aa < kMax);
96             middle += sk_make_nonzero_neg_one(aa);
97 
98             fStopAlpha = SkToU8(aa);
99             fMiddleCount = middle;
100         }
101         SkASSERT(fStartAlpha < kMax);
102         SkASSERT(fStopAlpha < kMax);
103 #endif
104     }
105 
106     void blit(int x, int y, SkBlitter* blitter)
107     {
108         int16_t runs[2];
109         runs[0] = 1;
110         runs[1] = 0;
111 
112         if (fStartAlpha)
113         {
114             blitter->blitAntiH(x, y, &fStartAlpha, runs);
115             x += 1;
116         }
117         if (fMiddleCount)
118         {
119             blitter->blitH(x, y, fMiddleCount);
120             x += fMiddleCount;
121         }
122         if (fStopAlpha)
123             blitter->blitAntiH(x, y, &fStopAlpha, runs);
124     }
125 
126     uint8_t  getStartAlpha() const { return fStartAlpha; }
127     int getMiddleCount() const { return fMiddleCount; }
128     uint8_t  getStopAlpha() const { return fStopAlpha; }
129 
130 private:
131     uint8_t  fStartAlpha, fStopAlpha;
132     int fMiddleCount;
133 
134     enum {
135         kMask = (1 << kShift) - 1,
136         kMax = (1 << (8 - kShift)) - 1
137     };
138 };
139 #endif
140 
141 ////////////////////////////////////////////////////////////////////////////////////
142 
143 class SkAlphaRuns {
144 public:
145     int16_t*    fRuns;
146     uint8_t*     fAlpha;
147 
empty()148     bool    empty() const
149     {
150         SkASSERT(fRuns[0] > 0);
151         return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
152     }
153     void    reset(int width);
154     void    add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue);
155     SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
156     SkDEBUGCODE(void dump() const;)
157 
158     static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
BreakAt(int16_t runs[],uint8_t alpha[],int x)159     static void BreakAt(int16_t runs[], uint8_t alpha[], int x)
160     {
161         while (x > 0)
162         {
163             int n = runs[0];
164             SkASSERT(n > 0);
165 
166             if (x < n)
167             {
168                 alpha[x] = alpha[0];
169                 runs[0] = SkToS16(x);
170                 runs[x] = SkToS16(n - x);
171                 break;
172             }
173             runs += n;
174             alpha += n;
175             x -= n;
176         }
177     }
178 
179 private:
180     SkDEBUGCODE(int fWidth;)
181     SkDEBUGCODE(void validate() const;)
182 };
183 
184 #endif
185 
186