diff options
author | Ben Wagner <bungeman@google.com> | 2018-05-10 15:24:20 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-10 23:00:56 +0000 |
commit | e3f1b59d9f578e34b32aa57b9686688f0ddd7877 (patch) | |
tree | e4860d6ba8b2499596e83990dc9b9fe440eadf38 /src/core/SkMask.h | |
parent | 2128b4ac44e5c9f123259b11c675a2152b19f44b (diff) |
Non-normal blur styles to work with non-a8.
BUG=skia:7941
Change-Id: I500561c2fec1bcab324fd9519f1d20d356afdfb5
Reviewed-on: https://skia-review.googlesource.com/127500
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkMask.h')
-rw-r--r-- | src/core/SkMask.h | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/core/SkMask.h b/src/core/SkMask.h index 86022a0e9d..395eecc44b 100644 --- a/src/core/SkMask.h +++ b/src/core/SkMask.h @@ -10,7 +10,9 @@ #ifndef SkMask_DEFINED #define SkMask_DEFINED +#include "SkColorPriv.h" #include "SkRect.h" +#include "SkTemplates.h" /** \class SkMask SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or @@ -128,12 +130,102 @@ struct SkMask { kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it }; + /** Iterates over the coverage values along a scanline in a given SkMask::Format. Provides + * constructor, copy constructor for creating + * operator++, operator-- for iterating over the coverage values on a scanline + * operator>>= to add row bytes + * operator* to get the coverage value at the current location + * operator< to compare two iterators + */ + template <Format F> struct AlphaIter; + /** * Returns initial destination mask data padded by radiusX and radiusY */ static SkMask PrepareDestination(int radiusX, int radiusY, const SkMask& src); }; +template <> struct SkMask::AlphaIter<SkMask::kBW_Format> { + AlphaIter(const uint8_t* ptr, int offset) : fPtr(ptr), fOffset(7 - offset) {} + AlphaIter(const AlphaIter& that) : fPtr(that.fPtr), fOffset(that.fOffset) {} + AlphaIter& operator++() { + if (0 < fOffset ) { + --fOffset; + } else { + ++fPtr; + fOffset = 7; + } + return *this; + } + AlphaIter& operator--() { + if (fOffset < 7) { + ++fOffset; + } else { + --fPtr; + fOffset = 0; + } + return *this; + } + AlphaIter& operator>>=(uint32_t rb) { + fPtr = SkTAddOffset<const uint8_t>(fPtr, rb); + return *this; + } + uint8_t operator*() const { return ((*fPtr) >> fOffset) & 1 ? 0xFF : 0; } + bool operator<(const AlphaIter& that) const { + return fPtr < that.fPtr || (fPtr == that.fPtr && fOffset > that.fOffset); + } + const uint8_t* fPtr; + int fOffset; +}; + +template <> struct SkMask::AlphaIter<SkMask::kA8_Format> { + AlphaIter(const uint8_t* ptr) : fPtr(ptr) {} + AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {} + AlphaIter& operator++() { ++fPtr; return *this; } + AlphaIter& operator--() { --fPtr; return *this; } + AlphaIter& operator>>=(uint32_t rb) { + fPtr = SkTAddOffset<const uint8_t>(fPtr, rb); + return *this; + } + uint8_t operator*() const { return *fPtr; } + bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; } + const uint8_t* fPtr; +}; + +template <> struct SkMask::AlphaIter<SkMask::kARGB32_Format> { + AlphaIter(const uint32_t* ptr) : fPtr(ptr) {} + AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {} + AlphaIter& operator++() { ++fPtr; return *this; } + AlphaIter& operator--() { --fPtr; return *this; } + AlphaIter& operator>>=(uint32_t rb) { + fPtr = SkTAddOffset<const uint32_t>(fPtr, rb); + return *this; + } + uint8_t operator*() const { return SkGetPackedA32(*fPtr); } + bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; } + const uint32_t* fPtr; +}; + +template <> struct SkMask::AlphaIter<SkMask::kLCD16_Format> { + AlphaIter(const uint16_t* ptr) : fPtr(ptr) {} + AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {} + AlphaIter& operator++() { ++fPtr; return *this; } + AlphaIter& operator--() { --fPtr; return *this; } + AlphaIter& operator>>=(uint32_t rb) { + fPtr = SkTAddOffset<const uint16_t>(fPtr, rb); + return *this; + } + uint8_t operator*() const { + unsigned packed = *fPtr; + unsigned r = SkPacked16ToR32(packed); + unsigned g = SkPacked16ToG32(packed); + unsigned b = SkPacked16ToB32(packed); + return (r + g + b) / 3; + } + bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; } + const uint16_t* fPtr; +}; + /////////////////////////////////////////////////////////////////////////////// /** |