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