|
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 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 kLCD32_Format //!< 888 alpha for r/g/b |
|
27 }; |
|
28 |
|
29 enum { |
|
30 kCountMaskFormats = kLCD32_Format + 1 |
|
31 }; |
|
32 |
|
33 uint8_t* fImage; |
|
34 SkIRect fBounds; |
|
35 uint32_t fRowBytes; |
|
36 Format fFormat; |
|
37 |
|
38 /** Returns true if the mask is empty: i.e. it has an empty bounds. |
|
39 */ |
|
40 bool isEmpty() const { return fBounds.isEmpty(); } |
|
41 |
|
42 /** Return the byte size of the mask, assuming only 1 plane. |
|
43 Does not account for k3D_Format. For that, use computeTotalImageSize(). |
|
44 If there is an overflow of 32bits, then returns 0. |
|
45 */ |
|
46 size_t computeImageSize() const; |
|
47 |
|
48 /** Return the byte size of the mask, taking into account |
|
49 any extra planes (e.g. k3D_Format). |
|
50 If there is an overflow of 32bits, then returns 0. |
|
51 */ |
|
52 size_t computeTotalImageSize() const; |
|
53 |
|
54 /** Returns the address of the byte that holds the specified bit. |
|
55 Asserts that the mask is kBW_Format, and that x,y are in range. |
|
56 x,y are in the same coordiate space as fBounds. |
|
57 */ |
|
58 uint8_t* getAddr1(int x, int y) const { |
|
59 SkASSERT(kBW_Format == fFormat); |
|
60 SkASSERT(fBounds.contains(x, y)); |
|
61 SkASSERT(fImage != NULL); |
|
62 return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes; |
|
63 } |
|
64 |
|
65 /** Returns the address of the specified byte. |
|
66 Asserts that the mask is kA8_Format, and that x,y are in range. |
|
67 x,y are in the same coordiate space as fBounds. |
|
68 */ |
|
69 uint8_t* getAddr8(int x, int y) const { |
|
70 SkASSERT(kA8_Format == fFormat); |
|
71 SkASSERT(fBounds.contains(x, y)); |
|
72 SkASSERT(fImage != NULL); |
|
73 return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes; |
|
74 } |
|
75 |
|
76 /** |
|
77 * Return the address of the specified 16bit mask. In the debug build, |
|
78 * this asserts that the mask's format is kLCD16_Format, and that (x,y) |
|
79 * are contained in the mask's fBounds. |
|
80 */ |
|
81 uint16_t* getAddrLCD16(int x, int y) const { |
|
82 SkASSERT(kLCD16_Format == fFormat); |
|
83 SkASSERT(fBounds.contains(x, y)); |
|
84 SkASSERT(fImage != NULL); |
|
85 uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes); |
|
86 return row + (x - fBounds.fLeft); |
|
87 } |
|
88 |
|
89 /** |
|
90 * Return the address of the specified 32bit mask. In the debug build, |
|
91 * this asserts that the mask's format is kLCD32_Format, and that (x,y) |
|
92 * are contained in the mask's fBounds. |
|
93 */ |
|
94 uint32_t* getAddrLCD32(int x, int y) const { |
|
95 SkASSERT(kLCD32_Format == fFormat); |
|
96 SkASSERT(fBounds.contains(x, y)); |
|
97 SkASSERT(fImage != NULL); |
|
98 uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); |
|
99 return row + (x - fBounds.fLeft); |
|
100 } |
|
101 |
|
102 /** |
|
103 * Return the address of the specified 32bit mask. In the debug build, |
|
104 * this asserts that the mask's format is 32bits, and that (x,y) |
|
105 * are contained in the mask's fBounds. |
|
106 */ |
|
107 uint32_t* getAddr32(int x, int y) const { |
|
108 SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat); |
|
109 SkASSERT(fBounds.contains(x, y)); |
|
110 SkASSERT(fImage != NULL); |
|
111 uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); |
|
112 return row + (x - fBounds.fLeft); |
|
113 } |
|
114 |
|
115 /** |
|
116 * Returns the address of the specified pixel, computing the pixel-size |
|
117 * at runtime based on the mask format. This will be slightly slower than |
|
118 * using one of the routines where the format is implied by the name |
|
119 * e.g. getAddr8 or getAddrLCD32. |
|
120 * |
|
121 * x,y must be contained by the mask's bounds (this is asserted in the |
|
122 * debug build, but not checked in the release build.) |
|
123 * |
|
124 * This should not be called with kBW_Format, as it will give unspecified |
|
125 * results (and assert in the debug build). |
|
126 */ |
|
127 void* getAddr(int x, int y) const; |
|
128 |
|
129 static uint8_t* AllocImage(size_t bytes); |
|
130 static void FreeImage(void* image); |
|
131 |
|
132 enum CreateMode { |
|
133 kJustComputeBounds_CreateMode, //!< compute bounds and return |
|
134 kJustRenderImage_CreateMode, //!< render into preallocate mask |
|
135 kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it |
|
136 }; |
|
137 }; |
|
138 |
|
139 /////////////////////////////////////////////////////////////////////////////// |
|
140 |
|
141 /** |
|
142 * \class SkAutoMaskImage |
|
143 * |
|
144 * Stack class used to manage the fImage buffer in a SkMask. |
|
145 * When this object loses scope, the buffer is freed with SkMask::FreeImage(). |
|
146 */ |
|
147 class SkAutoMaskFreeImage { |
|
148 public: |
|
149 SkAutoMaskFreeImage(uint8_t* maskImage) { |
|
150 fImage = maskImage; |
|
151 } |
|
152 |
|
153 ~SkAutoMaskFreeImage() { |
|
154 SkMask::FreeImage(fImage); |
|
155 } |
|
156 |
|
157 private: |
|
158 uint8_t* fImage; |
|
159 }; |
|
160 #define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage) |
|
161 |
|
162 #endif |