Line data Source code
1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #ifndef SkMask_DEFINED
11 : #define SkMask_DEFINED
12 :
13 : #include "SkRect.h"
14 :
15 : /** \class SkMask
16 : SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
17 : the 3-channel 3D format. These are passed to SkMaskFilter objects.
18 : */
19 : struct SkMask {
20 538 : SkMask() : fImage(nullptr) {}
21 :
22 : enum Format {
23 : kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
24 : kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
25 : k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
26 : kARGB32_Format, //!< SkPMColor
27 : kLCD16_Format, //!< 565 alpha for r/g/b
28 : };
29 :
30 : enum {
31 : kCountMaskFormats = kLCD16_Format + 1
32 : };
33 :
34 : uint8_t* fImage;
35 : SkIRect fBounds;
36 : uint32_t fRowBytes;
37 : Format fFormat;
38 :
39 : /** Returns true if the mask is empty: i.e. it has an empty bounds.
40 : */
41 : bool isEmpty() const { return fBounds.isEmpty(); }
42 :
43 : /** Return the byte size of the mask, assuming only 1 plane.
44 : Does not account for k3D_Format. For that, use computeTotalImageSize().
45 : If there is an overflow of 32bits, then returns 0.
46 : */
47 : size_t computeImageSize() const;
48 :
49 : /** Return the byte size of the mask, taking into account
50 : any extra planes (e.g. k3D_Format).
51 : If there is an overflow of 32bits, then returns 0.
52 : */
53 : size_t computeTotalImageSize() const;
54 :
55 : /** Returns the address of the byte that holds the specified bit.
56 : Asserts that the mask is kBW_Format, and that x,y are in range.
57 : x,y are in the same coordiate space as fBounds.
58 : */
59 0 : uint8_t* getAddr1(int x, int y) const {
60 0 : SkASSERT(kBW_Format == fFormat);
61 0 : SkASSERT(fBounds.contains(x, y));
62 0 : SkASSERT(fImage != NULL);
63 0 : return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
64 : }
65 :
66 : /** Returns the address of the specified byte.
67 : Asserts that the mask is kA8_Format, and that x,y are in range.
68 : x,y are in the same coordiate space as fBounds.
69 : */
70 27 : uint8_t* getAddr8(int x, int y) const {
71 27 : SkASSERT(kA8_Format == fFormat);
72 27 : SkASSERT(fBounds.contains(x, y));
73 27 : SkASSERT(fImage != NULL);
74 27 : return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
75 : }
76 :
77 : /**
78 : * Return the address of the specified 16bit mask. In the debug build,
79 : * this asserts that the mask's format is kLCD16_Format, and that (x,y)
80 : * are contained in the mask's fBounds.
81 : */
82 0 : uint16_t* getAddrLCD16(int x, int y) const {
83 0 : SkASSERT(kLCD16_Format == fFormat);
84 0 : SkASSERT(fBounds.contains(x, y));
85 0 : SkASSERT(fImage != NULL);
86 0 : uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
87 0 : return row + (x - fBounds.fLeft);
88 : }
89 :
90 : /**
91 : * Return the address of the specified 32bit mask. In the debug build,
92 : * this asserts that the mask's format is 32bits, and that (x,y)
93 : * are contained in the mask's fBounds.
94 : */
95 : uint32_t* getAddr32(int x, int y) const {
96 : SkASSERT(kARGB32_Format == fFormat);
97 : SkASSERT(fBounds.contains(x, y));
98 : SkASSERT(fImage != NULL);
99 : uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
100 : return row + (x - fBounds.fLeft);
101 : }
102 :
103 : /**
104 : * Returns the address of the specified pixel, computing the pixel-size
105 : * at runtime based on the mask format. This will be slightly slower than
106 : * using one of the routines where the format is implied by the name
107 : * e.g. getAddr8 or getAddr32.
108 : *
109 : * x,y must be contained by the mask's bounds (this is asserted in the
110 : * debug build, but not checked in the release build.)
111 : *
112 : * This should not be called with kBW_Format, as it will give unspecified
113 : * results (and assert in the debug build).
114 : */
115 : void* getAddr(int x, int y) const;
116 :
117 : static uint8_t* AllocImage(size_t bytes);
118 : static void FreeImage(void* image);
119 :
120 : enum CreateMode {
121 : kJustComputeBounds_CreateMode, //!< compute bounds and return
122 : kJustRenderImage_CreateMode, //!< render into preallocate mask
123 : kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it
124 : };
125 : };
126 :
127 : ///////////////////////////////////////////////////////////////////////////////
128 :
129 : /**
130 : * \class SkAutoMaskImage
131 : *
132 : * Stack class used to manage the fImage buffer in a SkMask.
133 : * When this object loses scope, the buffer is freed with SkMask::FreeImage().
134 : */
135 : class SkAutoMaskFreeImage {
136 : public:
137 4 : SkAutoMaskFreeImage(uint8_t* maskImage) {
138 4 : fImage = maskImage;
139 4 : }
140 :
141 8 : ~SkAutoMaskFreeImage() {
142 4 : SkMask::FreeImage(fImage);
143 4 : }
144 :
145 : private:
146 : uint8_t* fImage;
147 : };
148 : #define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage)
149 :
150 : #endif
|