xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h (revision 683cbefe9ec156fe9587b9a64a5e1b666a21654d)
1 /*
2  * Copyright 2005, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Base class for different drawing modes.
6  *
7  */
8 
9 #ifndef DRAWING_MODE_H
10 #define DRAWING_MODE_H
11 
12 #include <stdio.h>
13 #include <string.h>
14 #include <agg_basics.h>
15 #include <agg_color_rgba8.h>
16 #include <agg_rendering_buffer.h>
17 
18 class PatternHandler;
19 
20 // BLEND
21 //
22 // This macro assumes source alpha in range 0..255 and
23 // ignores dest alpha (is assumed to equal 255).
24 // TODO: We need the assignment of alpha only when drawing into bitmaps!
25 #define BLEND(d1, d2, d3, da, s1, s2, s3, a) \
26 { \
27 	(d1) = (((((s1) - (d1)) * (a)) + ((d1) << 8)) >> 8); \
28 	(d2) = (((((s2) - (d2)) * (a)) + ((d2) << 8)) >> 8); \
29 	(d3) = (((((s3) - (d3)) * (a)) + ((d3) << 8)) >> 8); \
30 	(da) = max_c((da), (a)); \
31 }
32 
33 // BLEND_FROM
34 //
35 // This macro assumes source alpha in range 0..255 and
36 // ignores dest alpha (is assumed to equal 255).
37 // It uses two colors for the blending (f and s) and writes
38 // the result into a third color (d).
39 // TODO: We need the assignment of alpha only when drawing into bitmaps!
40 #define BLEND_FROM(d1, d2, d3, da, f1, f2, f3, s1, s2, s3, a) \
41 { \
42 	(d1) = (((((s1) - (f1)) * (a)) + ((f1) << 8)) >> 8); \
43 	(d2) = (((((s2) - (f2)) * (a)) + ((f2) << 8)) >> 8); \
44 	(d3) = (((((s3) - (f3)) * (a)) + ((f3) << 8)) >> 8); \
45 	(da) = max_c((da), (a)); \
46 }
47 
48 // BLEND16
49 //
50 // This macro assumes source alpha in range 0..65025 and
51 // ignores dest alpha (is assumed to equal 255).
52 // TODO: We need the assignment of alpha only when drawing into bitmaps!
53 #define BLEND16(d1, d2, d3, da, s1, s2, s3, a) \
54 { \
55 	(d1) = (((((s1) - (d1)) * (a)) + ((d1) << 16)) >> 16); \
56 	(d2) = (((((s2) - (d2)) * (a)) + ((d2) << 16)) >> 16); \
57 	(d3) = (((((s3) - (d3)) * (a)) + ((d3) << 16)) >> 16); \
58 	(da) = max_c((da), (a) >> 8); \
59 }
60 
61 // BLEND_COMPOSITE
62 //
63 // This macro assumes source alpha in range 0..255 and
64 // composes the source color over a possibly semi-transparent background.
65 #define BLEND_COMPOSITE(d1, d2, d3, da, s1, s2, s3, a) \
66 { \
67 	if ((da) == 255) { \
68 		BLEND(d1, d2, d3, da, s1, s2, s3, a); \
69 	} else { \
70 		uint8 alphaRest = 255 - (a); \
71 		uint32 alphaTemp = (65025 - alphaRest * (255 - (da))); \
72 		uint32 alphaDest = (da) * alphaRest; \
73 		uint32 alphaSrc = 255 * (a); \
74 		(d1) = ((d1) * alphaDest + (s2) * alphaSrc) / alphaTemp; \
75 		(d2) = ((d2) * alphaDest + (s2) * alphaSrc) / alphaTemp; \
76 		(d3) = ((d3) * alphaDest + (s3) * alphaSrc) / alphaTemp; \
77 		(da) = alphaTemp >> 8; \
78 	} \
79 }
80 
81 // BLEND_COMPOSITE16
82 //
83 // This macro assumes source alpha in range 0..65025 and
84 // composes the source color over a possibly semi-transparent background.
85 // TODO: implement a faster version
86 #define BLEND_COMPOSITE16(d1, d2, d3, da, s1, s2, s3, a) \
87 { \
88 	BLEND_COMPOSITE(d1, d2, d3, da, s1, s2, s3, (a) >> 8); \
89 }
90 
91 class DrawingMode {
92  public:
93 	typedef agg::rgba8 color_type;
94 
95 	// constructor
96 	DrawingMode()
97 		: fBuffer(NULL)
98 	{
99 	}
100 
101 	// destructor
102 	virtual ~DrawingMode()
103 	{
104 	}
105 
106 	// set_rendering_buffer
107 	void set_rendering_buffer(agg::rendering_buffer* buffer)
108 	{
109 		fBuffer = buffer;
110 	}
111 
112 	// set_pattern_handler
113 	void set_pattern_handler(const PatternHandler* handler)
114 	{
115 		fPatternHandler = handler;
116 	}
117 
118 	virtual	void blend_pixel(int x, int y, const color_type& c, uint8 cover) = 0;
119 
120 	virtual	void blend_hline(int x, int y, unsigned len,
121 							 const color_type& c, uint8 cover) = 0;
122 
123 	virtual	void blend_vline(int x, int y, unsigned len,
124 							 const color_type& c, uint8 cover) = 0;
125 
126 	virtual	void blend_solid_hspan(int x, int y, unsigned len,
127 								   const color_type& c, const uint8* covers) = 0;
128 
129 	virtual	void blend_solid_vspan(int x, int y, unsigned len,
130 								   const color_type& c, const uint8* covers) = 0;
131 
132 	virtual	void blend_color_hspan(int x, int y, unsigned len,
133 								   const color_type* colors,
134 								   const uint8* covers,
135 								   uint8 cover) = 0;
136 
137 	virtual	void blend_color_vspan(int x, int y, unsigned len,
138 								   const color_type* colors,
139 								   const uint8* covers,
140 								   uint8 cover) = 0;
141 
142 protected:
143 	agg::rendering_buffer*	fBuffer;
144 	const PatternHandler*	fPatternHandler;
145 
146 
147 };
148 
149 #endif // DRAWING_MODE_H
150 
151