1/*
2 * Copyright 2014-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 */
5
6#ifndef ALPHA_MASK_H
7#define ALPHA_MASK_H
8
9#include <Referenceable.h>
10#include <locks.h>
11
12#include "agg_clipped_alpha_mask.h"
13#include "ServerPicture.h"
14
15#include "DrawState.h"
16#include "drawing/Painter/defines.h"
17#include "IntRect.h"
18
19
20class BShape;
21class ServerBitmap;
22class ServerPicture;
23class shape_data;
24class UtilityBitmap;
25
26
27// #pragma mark - AlphaMask
28
29
30class AlphaMask : public BReferenceable {
31public:
32								AlphaMask(AlphaMask* previousMask,
33									bool inverse);
34								AlphaMask(AlphaMask* previousMask,
35									AlphaMask* other);
36								AlphaMask(uint8 backgroundOpacity);
37	virtual						~AlphaMask();
38
39			IntPoint			SetCanvasGeometry(IntPoint origin,
40									IntRect bounds);
41
42			scanline_unpacked_masked_type* Scanline()
43								{ return &fScanline; }
44
45			agg::clipped_alpha_mask* Mask()
46								{ return &fMask; }
47
48			size_t				BitmapSize() const;
49
50			bool				IsInverted() const
51								{ return fInverse; }
52
53			bool				IsClipped() const
54								{ return fClippedToCanvas; }
55
56			uint8				OutsideOpacity() const
57								{ return fOutsideOpacity; }
58
59protected:
60			ServerBitmap*		_CreateTemporaryBitmap(BRect bounds) const;
61			void				_Generate();
62			void				_SetNoClipping();
63			const IntRect&		_PreviousMaskBounds() const;
64	virtual	void				_AddToCache() = 0;
65			void				_SetOutsideOpacity();
66
67private:
68	virtual	ServerBitmap*		_RenderSource(const IntRect& canvasBounds) = 0;
69 	virtual	IntPoint			_Offset() = 0;
70
71			void				_AttachMaskToBuffer();
72
73protected:
74			BReference<AlphaMask> fPreviousMask;
75			IntRect				fBounds;
76			bool				fClippedToCanvas;
77			recursive_lock		fLock;
78
79private:
80	friend class AlphaMaskCache;
81
82			IntPoint			fCanvasOrigin;
83			IntRect				fCanvasBounds;
84			const bool			fInverse;
85			uint8				fBackgroundOpacity;
86			uint8				fOutsideOpacity;
87
88			int32				fNextMaskCount;
89			bool				fInCache;
90			uint32				fIndirectCacheReferences;
91									// number of times this mask has been
92									// seen as "previous mask" of another
93									// one in the cache, without being
94									// in the cache itself
95
96			BReference<UtilityBitmap> fBits;
97			agg::rendering_buffer fBuffer;
98			agg::clipped_alpha_mask fMask;
99			scanline_unpacked_masked_type fScanline;
100};
101
102
103class UniformAlphaMask : public AlphaMask {
104public:
105								UniformAlphaMask(uint8 opacity);
106
107private:
108	virtual	ServerBitmap*		_RenderSource(const IntRect& canvasBounds);
109	virtual	IntPoint			_Offset();
110	virtual void				_AddToCache();
111};
112
113
114// #pragma mark - VectorAlphaMask
115
116
117template<class VectorMaskType>
118class VectorAlphaMask : public AlphaMask {
119public:
120								VectorAlphaMask(AlphaMask* previousMask,
121									BPoint where, bool inverse);
122								VectorAlphaMask(AlphaMask* previousMask,
123									VectorAlphaMask* other);
124
125private:
126	virtual	ServerBitmap*		_RenderSource(const IntRect& canvasBounds);
127	virtual	IntPoint			_Offset();
128
129protected:
130			BPoint				fWhere;
131};
132
133
134// #pragma mark - PictureAlphaMask
135
136
137class PictureAlphaMask : public VectorAlphaMask<PictureAlphaMask> {
138public:
139								PictureAlphaMask(AlphaMask* previousMask,
140									ServerPicture* picture,
141									const DrawState& drawState, BPoint where,
142									bool inverse);
143	virtual						~PictureAlphaMask();
144
145			void				DrawVectors(Canvas* canvas);
146			BRect				DetermineBoundingBox() const;
147			const DrawState&	GetDrawState() const;
148
149private:
150	virtual void				_AddToCache();
151
152private:
153			BReference<ServerPicture> fPicture;
154			ObjectDeleter<DrawState> fDrawState;
155};
156
157
158// #pragma mark - ShapeAlphaMask
159
160
161class ShapeAlphaMask : public VectorAlphaMask<ShapeAlphaMask> {
162private:
163								ShapeAlphaMask(AlphaMask* previousMask,
164									const shape_data& shape,
165									BPoint where, bool inverse);
166								ShapeAlphaMask(AlphaMask* previousMask,
167									ShapeAlphaMask* other);
168
169public:
170	virtual						~ShapeAlphaMask();
171
172	static	ShapeAlphaMask*		Create(AlphaMask* previousMask,
173									const shape_data& shape,
174									BPoint where, bool inverse);
175
176			void				DrawVectors(Canvas* canvas);
177			BRect				DetermineBoundingBox() const;
178			const DrawState&	GetDrawState() const;
179
180private:
181	virtual void				_AddToCache();
182
183private:
184	friend class AlphaMaskCache;
185
186			BReference<shape_data> fShape;
187			BRect				fShapeBounds;
188	static	DrawState*			fDrawState;
189};
190
191
192#endif // ALPHA_MASK_H
193