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 0 : uint8_t* getAddr1(int x, int y) const {
59 0 : SkASSERT(kBW_Format == fFormat);
60 0 : SkASSERT(fBounds.contains(x, y));
61 0 : SkASSERT(fImage != NULL);
62 0 : 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 0 : uint8_t* getAddr8(int x, int y) const {
70 0 : SkASSERT(kA8_Format == fFormat);
71 0 : SkASSERT(fBounds.contains(x, y));
72 0 : SkASSERT(fImage != NULL);
73 0 : 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 : * Returns the address of the specified pixel, computing the pixel-size
104 : * at runtime based on the mask format. This will be slightly slower than
105 : * using one of the routines where the format is implied by the name
106 : * e.g. getAddr8 or getAddrLCD32.
107 : *
108 : * x,y must be contained by the mask's bounds (this is asserted in the
109 : * debug build, but not checked in the release build.)
110 : *
111 : * This should not be called with kBW_Format, as it will give unspecified
112 : * results (and assert in the debug build).
113 : */
114 : void* getAddr(int x, int y) const;
115 :
116 : static uint8_t* AllocImage(size_t bytes);
117 : static void FreeImage(void* image);
118 :
119 : enum CreateMode {
120 : kJustComputeBounds_CreateMode, //!< compute bounds and return
121 : kJustRenderImage_CreateMode, //!< render into preallocate mask
122 : kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it
123 : };
124 : };
125 :
126 : ///////////////////////////////////////////////////////////////////////////////
127 :
128 : /**
129 : * \class SkAutoMaskImage
130 : *
131 : * Stack class used to manage the fImage buffer in a SkMask.
132 : * When this object loses scope, the buffer is freed with SkMask::FreeImage().
133 : */
134 : class SkAutoMaskFreeImage {
135 : public:
136 0 : SkAutoMaskFreeImage(uint8_t* maskImage) {
137 0 : fImage = maskImage;
138 0 : }
139 :
140 0 : ~SkAutoMaskFreeImage() {
141 0 : SkMask::FreeImage(fImage);
142 0 : }
143 :
144 : private:
145 : uint8_t* fImage;
146 : };
147 :
148 : #endif
149 :
|