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 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 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); 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