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