SkMask.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkMask_DEFINED
  8. #define SkMask_DEFINED
  9. #include "include/core/SkRect.h"
  10. #include "include/private/SkColorData.h"
  11. #include "include/private/SkMacros.h"
  12. #include "include/private/SkTemplates.h"
  13. #include <memory>
  14. /** \class SkMask
  15. SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
  16. the 3-channel 3D format. These are passed to SkMaskFilter objects.
  17. */
  18. struct SkMask {
  19. SkMask() : fImage(nullptr) {}
  20. enum Format {
  21. kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
  22. kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
  23. k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
  24. kARGB32_Format, //!< SkPMColor
  25. kLCD16_Format, //!< 565 alpha for r/g/b
  26. kSDF_Format, //!< 8bits representing signed distance field
  27. };
  28. enum {
  29. kCountMaskFormats = kSDF_Format + 1
  30. };
  31. uint8_t* fImage;
  32. SkIRect fBounds;
  33. uint32_t fRowBytes;
  34. Format fFormat;
  35. static bool IsValidFormat(uint8_t format) { return format < kCountMaskFormats; }
  36. /** Returns true if the mask is empty: i.e. it has an empty bounds.
  37. */
  38. bool isEmpty() const { return fBounds.isEmpty(); }
  39. /** Return the byte size of the mask, assuming only 1 plane.
  40. Does not account for k3D_Format. For that, use computeTotalImageSize().
  41. If there is an overflow of 32bits, then returns 0.
  42. */
  43. size_t computeImageSize() const;
  44. /** Return the byte size of the mask, taking into account
  45. any extra planes (e.g. k3D_Format).
  46. If there is an overflow of 32bits, then returns 0.
  47. */
  48. size_t computeTotalImageSize() const;
  49. /** Returns the address of the byte that holds the specified bit.
  50. Asserts that the mask is kBW_Format, and that x,y are in range.
  51. x,y are in the same coordiate space as fBounds.
  52. */
  53. uint8_t* getAddr1(int x, int y) const {
  54. SkASSERT(kBW_Format == fFormat);
  55. SkASSERT(fBounds.contains(x, y));
  56. SkASSERT(fImage != nullptr);
  57. return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
  58. }
  59. /** Returns the address of the specified byte.
  60. Asserts that the mask is kA8_Format, and that x,y are in range.
  61. x,y are in the same coordiate space as fBounds.
  62. */
  63. uint8_t* getAddr8(int x, int y) const {
  64. SkASSERT(kA8_Format == fFormat || kSDF_Format == fFormat);
  65. SkASSERT(fBounds.contains(x, y));
  66. SkASSERT(fImage != nullptr);
  67. return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
  68. }
  69. /**
  70. * Return the address of the specified 16bit mask. In the debug build,
  71. * this asserts that the mask's format is kLCD16_Format, and that (x,y)
  72. * are contained in the mask's fBounds.
  73. */
  74. uint16_t* getAddrLCD16(int x, int y) const {
  75. SkASSERT(kLCD16_Format == fFormat);
  76. SkASSERT(fBounds.contains(x, y));
  77. SkASSERT(fImage != nullptr);
  78. uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
  79. return row + (x - fBounds.fLeft);
  80. }
  81. /**
  82. * Return the address of the specified 32bit mask. In the debug build,
  83. * this asserts that the mask's format is 32bits, and that (x,y)
  84. * are contained in the mask's fBounds.
  85. */
  86. uint32_t* getAddr32(int x, int y) const {
  87. SkASSERT(kARGB32_Format == fFormat);
  88. SkASSERT(fBounds.contains(x, y));
  89. SkASSERT(fImage != nullptr);
  90. uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
  91. return row + (x - fBounds.fLeft);
  92. }
  93. /**
  94. * Returns the address of the specified pixel, computing the pixel-size
  95. * at runtime based on the mask format. This will be slightly slower than
  96. * using one of the routines where the format is implied by the name
  97. * e.g. getAddr8 or getAddr32.
  98. *
  99. * x,y must be contained by the mask's bounds (this is asserted in the
  100. * debug build, but not checked in the release build.)
  101. *
  102. * This should not be called with kBW_Format, as it will give unspecified
  103. * results (and assert in the debug build).
  104. */
  105. void* getAddr(int x, int y) const;
  106. enum AllocType {
  107. kUninit_Alloc,
  108. kZeroInit_Alloc,
  109. };
  110. static uint8_t* AllocImage(size_t bytes, AllocType = kUninit_Alloc);
  111. static void FreeImage(void* image);
  112. enum CreateMode {
  113. kJustComputeBounds_CreateMode, //!< compute bounds and return
  114. kJustRenderImage_CreateMode, //!< render into preallocate mask
  115. kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it
  116. };
  117. /** Iterates over the coverage values along a scanline in a given SkMask::Format. Provides
  118. * constructor, copy constructor for creating
  119. * operator++, operator-- for iterating over the coverage values on a scanline
  120. * operator>>= to add row bytes
  121. * operator* to get the coverage value at the current location
  122. * operator< to compare two iterators
  123. */
  124. template <Format F> struct AlphaIter;
  125. /**
  126. * Returns initial destination mask data padded by radiusX and radiusY
  127. */
  128. static SkMask PrepareDestination(int radiusX, int radiusY, const SkMask& src);
  129. };
  130. template <> struct SkMask::AlphaIter<SkMask::kBW_Format> {
  131. AlphaIter(const uint8_t* ptr, int offset) : fPtr(ptr), fOffset(7 - offset) {}
  132. AlphaIter(const AlphaIter& that) : fPtr(that.fPtr), fOffset(that.fOffset) {}
  133. AlphaIter& operator++() {
  134. if (0 < fOffset ) {
  135. --fOffset;
  136. } else {
  137. ++fPtr;
  138. fOffset = 7;
  139. }
  140. return *this;
  141. }
  142. AlphaIter& operator--() {
  143. if (fOffset < 7) {
  144. ++fOffset;
  145. } else {
  146. --fPtr;
  147. fOffset = 0;
  148. }
  149. return *this;
  150. }
  151. AlphaIter& operator>>=(uint32_t rb) {
  152. fPtr = SkTAddOffset<const uint8_t>(fPtr, rb);
  153. return *this;
  154. }
  155. uint8_t operator*() const { return ((*fPtr) >> fOffset) & 1 ? 0xFF : 0; }
  156. bool operator<(const AlphaIter& that) const {
  157. return fPtr < that.fPtr || (fPtr == that.fPtr && fOffset > that.fOffset);
  158. }
  159. const uint8_t* fPtr;
  160. int fOffset;
  161. };
  162. template <> struct SkMask::AlphaIter<SkMask::kA8_Format> {
  163. AlphaIter(const uint8_t* ptr) : fPtr(ptr) {}
  164. AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
  165. AlphaIter& operator++() { ++fPtr; return *this; }
  166. AlphaIter& operator--() { --fPtr; return *this; }
  167. AlphaIter& operator>>=(uint32_t rb) {
  168. fPtr = SkTAddOffset<const uint8_t>(fPtr, rb);
  169. return *this;
  170. }
  171. uint8_t operator*() const { return *fPtr; }
  172. bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
  173. const uint8_t* fPtr;
  174. };
  175. template <> struct SkMask::AlphaIter<SkMask::kARGB32_Format> {
  176. AlphaIter(const uint32_t* ptr) : fPtr(ptr) {}
  177. AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
  178. AlphaIter& operator++() { ++fPtr; return *this; }
  179. AlphaIter& operator--() { --fPtr; return *this; }
  180. AlphaIter& operator>>=(uint32_t rb) {
  181. fPtr = SkTAddOffset<const uint32_t>(fPtr, rb);
  182. return *this;
  183. }
  184. uint8_t operator*() const { return SkGetPackedA32(*fPtr); }
  185. bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
  186. const uint32_t* fPtr;
  187. };
  188. template <> struct SkMask::AlphaIter<SkMask::kLCD16_Format> {
  189. AlphaIter(const uint16_t* ptr) : fPtr(ptr) {}
  190. AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
  191. AlphaIter& operator++() { ++fPtr; return *this; }
  192. AlphaIter& operator--() { --fPtr; return *this; }
  193. AlphaIter& operator>>=(uint32_t rb) {
  194. fPtr = SkTAddOffset<const uint16_t>(fPtr, rb);
  195. return *this;
  196. }
  197. uint8_t operator*() const {
  198. unsigned packed = *fPtr;
  199. unsigned r = SkPacked16ToR32(packed);
  200. unsigned g = SkPacked16ToG32(packed);
  201. unsigned b = SkPacked16ToB32(packed);
  202. return (r + g + b) / 3;
  203. }
  204. bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
  205. const uint16_t* fPtr;
  206. };
  207. ///////////////////////////////////////////////////////////////////////////////
  208. /**
  209. * \using SkAutoMaskImage
  210. *
  211. * Stack class used to manage the fImage buffer in a SkMask.
  212. * When this object loses scope, the buffer is freed with SkMask::FreeImage().
  213. */
  214. using SkAutoMaskFreeImage = std::unique_ptr<uint8_t,SkFunctionWrapper<void,void,SkMask::FreeImage>>;
  215. #define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage)
  216. #endif