diff options
Diffstat (limited to 'skia/sgl/SkAntiRun.h')
-rw-r--r-- | skia/sgl/SkAntiRun.h | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/skia/sgl/SkAntiRun.h b/skia/sgl/SkAntiRun.h new file mode 100644 index 0000000..32814f1 --- /dev/null +++ b/skia/sgl/SkAntiRun.h @@ -0,0 +1,185 @@ +/* libs/graphics/sgl/SkAntiRun.h +** +** Copyright 2006, Google Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef SkAntiRun_DEFINED +#define SkAntiRun_DEFINED + +#include "SkBlitter.h" + +inline int sk_make_nonzero_neg_one(int x) +{ + return (x | -x) >> 31; +} + +#if 0 +template <int kShift> class SkAntiRun { + static uint8_t coverage_to_alpha(int aa) + { + aa <<= 8 - 2*kShift; + aa -= aa >> (8 - kShift - 1); + return SkToU8(aa); + } +public: + void set(int start, int stop) + { + SkASSERT(start >= 0 && stop > start); + +#if 1 + int fb = start & kMask; + int fe = stop & kMask; + int n = (stop >> kShift) - (start >> kShift) - 1; + + if (n < 0) + { + fb = fe - fb; + n = 0; + fe = 0; + } + else + { + if (fb == 0) + n += 1; + else + fb = (1 << kShift) - fb; + } + + fStartAlpha = coverage_to_alpha(fb); + fMiddleCount = n; + fStopAlpha = coverage_to_alpha(fe); +#else + int x0 = start >> kShift; + int x1 = (stop - 1) >> kShift; + int middle = x1 - x0; + int aa; + + if (middle == 0) + { + aa = stop - start; + aa <<= 8 - 2*kShift; + aa -= aa >> (8 - kShift - 1); + SkASSERT(aa > 0 && aa < kMax); + fStartAlpha = SkToU8(aa); + fMiddleCount = 0; + fStopAlpha = 0; + } + else + { + int aa = start & kMask; + aa <<= 8 - 2*kShift; + aa -= aa >> (8 - kShift - 1); + SkASSERT(aa >= 0 && aa < kMax); + if (aa) + fStartAlpha = SkToU8(kMax - aa); + else + { + fStartAlpha = 0; + middle += 1; + } + aa = stop & kMask; + aa <<= 8 - 2*kShift; + aa -= aa >> (8 - kShift - 1); + SkASSERT(aa >= 0 && aa < kMax); + middle += sk_make_nonzero_neg_one(aa); + + fStopAlpha = SkToU8(aa); + fMiddleCount = middle; + } + SkASSERT(fStartAlpha < kMax); + SkASSERT(fStopAlpha < kMax); +#endif + } + + void blit(int x, int y, SkBlitter* blitter) + { + int16_t runs[2]; + runs[0] = 1; + runs[1] = 0; + + if (fStartAlpha) + { + blitter->blitAntiH(x, y, &fStartAlpha, runs); + x += 1; + } + if (fMiddleCount) + { + blitter->blitH(x, y, fMiddleCount); + x += fMiddleCount; + } + if (fStopAlpha) + blitter->blitAntiH(x, y, &fStopAlpha, runs); + } + + uint8_t getStartAlpha() const { return fStartAlpha; } + int getMiddleCount() const { return fMiddleCount; } + uint8_t getStopAlpha() const { return fStopAlpha; } + +private: + uint8_t fStartAlpha, fStopAlpha; + int fMiddleCount; + + enum { + kMask = (1 << kShift) - 1, + kMax = (1 << (8 - kShift)) - 1 + }; +}; +#endif + +//////////////////////////////////////////////////////////////////////////////////// + +class SkAlphaRuns { +public: + int16_t* fRuns; + uint8_t* fAlpha; + + bool empty() const + { + SkASSERT(fRuns[0] > 0); + return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0; + } + void reset(int width); + void add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue); + SkDEBUGCODE(void assertValid(int y, int maxStep) const;) + SkDEBUGCODE(void dump() const;) + + static void Break(int16_t runs[], uint8_t alpha[], int x, int count); + static void BreakAt(int16_t runs[], uint8_t alpha[], int x) + { + while (x > 0) + { + int n = runs[0]; + SkASSERT(n > 0); + + if (x < n) + { + alpha[x] = alpha[0]; + runs[0] = SkToS16(x); + runs[x] = SkToS16(n - x); + break; + } + runs += n; + alpha += n; + x -= n; + } + } + +private: + SkDEBUGCODE(int fWidth;) + SkDEBUGCODE(void validate() const;) +}; + +#endif + |