xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h (revision 9d909e25560c098447fd4dddbed7ed48ae8c9748)
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 "PatternHandler.h"
13 #include "PixelFormat.h"
14 
15 class PatternHandler;
16 
17 typedef PixelFormat::color_type		color_type;
18 typedef PixelFormat::agg_buffer		agg_buffer;
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(d, r, g, b, a) \
31 { \
32 	pixel32 _p; \
33 	_p.data32 = *(uint32*)d; \
34 	d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \
35 	d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
36 	d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
37 	d[3] = 255; \
38 }
39 
40 // BLEND_FROM
41 //
42 // This macro assumes source alpha in range 0..255 and
43 // ignores dest alpha (is assumed to equal 255).
44 // It uses two colors for the blending (f and s) and writes
45 // the result into a third color (d).
46 // TODO: We need the assignment of alpha only when drawing into bitmaps!
47 #define BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a) \
48 { \
49 	d[0] = (((((b2) - (b1)) * (a)) + ((b1) << 8)) >> 8); \
50 	d[1] = (((((g2) - (g1)) * (a)) + ((g1) << 8)) >> 8); \
51 	d[2] = (((((r2) - (r1)) * (a)) + ((r1) << 8)) >> 8); \
52 	d[3] = 255; \
53 }
54 
55 // BLEND16
56 //
57 // This macro assumes source alpha in range 0..65025 and
58 // ignores dest alpha (is assumed to equal 255).
59 // TODO: We need the assignment of alpha only when drawing into bitmaps!
60 // BLEND16
61 #define BLEND16(d, r, g, b, a) \
62 { \
63 	pixel32 _p; \
64 	_p.data32 = *(uint32*)d; \
65 	d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 16)) >> 16); \
66 	d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 16)) >> 16); \
67 	d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 16)) >> 16); \
68 	d[3] = 255; \
69 }
70 
71 
72 
73 // BLEND_COMPOSITE
74 //
75 // This macro assumes source alpha in range 0..255 and
76 // composes the source color over a possibly semi-transparent background.
77 #define BLEND_COMPOSITE(d, r, g, b, a) \
78 { \
79 	pixel32 _p; \
80 	_p.data32 = *(uint32*)d; \
81 	if (_p.data8[3] == 255) { \
82 		BLEND(d, r, g, b, a); \
83 	} else { \
84 		uint8 alphaRest = 255 - (a); \
85 		uint32 alphaTemp = (65025 - alphaRest * (255 - _p.data8[3])); \
86 		uint32 alphaDest = _p.data8[3] * alphaRest; \
87 		uint32 alphaSrc = 255 * (a); \
88 		d[0] = (_p.data8[0] * alphaDest + (b) * alphaSrc) / alphaTemp; \
89 		d[1] = (_p.data8[1] * alphaDest + (g) * alphaSrc) / alphaTemp; \
90 		d[2] = (_p.data8[2] * alphaDest + (r) * alphaSrc) / alphaTemp; \
91 		d[3] = alphaTemp >> 8; \
92 	} \
93 }
94 
95 // BLEND_COMPOSITE16
96 //
97 // This macro assumes source alpha in range 0..65025 and
98 // composes the source color over a possibly semi-transparent background.
99 // TODO: implement a faster version
100 #define BLEND_COMPOSITE16(d, r, g, b, a) \
101 { \
102 	BLEND_COMPOSITE(d, r, g, b, (a) >> 8); \
103 }
104 
105 
106 #endif // DRAWING_MODE_H
107 
108