xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
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 		BLEND(d, r, g, b, a); \
80 	} else { \
81 		if (_p.data8[3] == 0) { \
82 			d[0] = (b); \
83 			d[1] = (g); \
84 			d[2] = (r); \
85 			d[3] = (a); \
86 		} else { \
87 			uint8 alphaRest = 255 - (a); \
88 			uint32 alphaTemp = (65025 - alphaRest * (255 - _p.data8[3])); \
89 			uint32 alphaDest = _p.data8[3] * alphaRest; \
90 			uint32 alphaSrc = 255 * (a); \
91 			d[0] = (_p.data8[0] * alphaDest + (b) * alphaSrc) / alphaTemp; \
92 			d[1] = (_p.data8[1] * alphaDest + (g) * alphaSrc) / alphaTemp; \
93 			d[2] = (_p.data8[2] * alphaDest + (r) * alphaSrc) / alphaTemp; \
94 			d[3] = alphaTemp >> 8; \
95 		} \
96 	} \
97 }
98 
99 // BLEND_COMPOSITE16
100 //
101 // This macro assumes source alpha in range 0..65025 and
102 // composes the source color over a possibly semi-transparent background.
103 // TODO: implement a faster version
104 #define BLEND_COMPOSITE16(d, r, g, b, a) \
105 { \
106 	BLEND_COMPOSITE(d, r, g, b, (a) >> 8); \
107 }
108 
109 
110 #endif // DRAWING_MODE_H
111 
112