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