xref: /haiku/src/servers/app/drawing/drawing_support.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 2005-2007, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 #ifndef DRAWING_SUPPORT_H
9 #define DRAWING_SUPPORT_H
10 
11 
12 #include <SupportDefs.h>
13 
14 class BRect;
15 
16 
17 // gfxcpy
18 static inline void
19 gfxcpy(uint8* dst, const uint8* src, int32 numBytes)
20 {
21 	uint64* d64 = (uint64*)dst;
22 	uint64* s64 = (uint64*)src;
23 	int32 numBytesBegin = numBytes;
24 	while (numBytes >= 32) {
25 		*d64++ = *s64++;
26 		*d64++ = *s64++;
27 		*d64++ = *s64++;
28 		*d64++ = *s64++;
29 		numBytes -= 32;
30 	}
31 	while (numBytes >= 16) {
32 		*d64++ = *s64++;
33 		*d64++ = *s64++;
34 		numBytes -= 16;
35 	}
36 	while (numBytes >= 8) {
37 		*d64++ = *s64++;
38 		numBytes -= 8;
39 	}
40 	if (numBytes > 0) {
41 		// update original pointers
42 		dst += numBytesBegin - numBytes;
43 		src += numBytesBegin - numBytes;
44 		numBytesBegin = numBytes;
45 
46 		uint32* d32 = (uint32*)dst;
47 		uint32* s32 = (uint32*)src;
48 		while (numBytes >= 4) {
49 			*d32++ = *s32++;
50 			numBytes -= 4;
51 		}
52 		// update original pointers
53 		dst += numBytesBegin - numBytes;
54 		src += numBytesBegin - numBytes;
55 
56 		while (numBytes > 0) {
57 			*dst++ = *src++;
58 			numBytes--;
59 		}
60 	}
61 }
62 
63 // gfxcpy32
64 // * numBytes is expected to be a multiple of 4
65 static inline void
66 gfxcpy32(uint8* dst, const uint8* src, int32 numBytes)
67 {
68 	uint64* d64 = (uint64*)dst;
69 	uint64* s64 = (uint64*)src;
70 	int32 numBytesStart = numBytes;
71 	while (numBytes >= 32) {
72 		*d64++ = *s64++;
73 		*d64++ = *s64++;
74 		*d64++ = *s64++;
75 		*d64++ = *s64++;
76 		numBytes -= 32;
77 	}
78 	if (numBytes >= 16) {
79 		*d64++ = *s64++;
80 		*d64++ = *s64++;
81 		numBytes -= 16;
82 	}
83 	if (numBytes >= 8) {
84 		*d64++ = *s64++;
85 		numBytes -= 8;
86 	}
87 	if (numBytes == 4) {
88 		uint32* d32 = (uint32*)(dst + numBytesStart - numBytes);
89 		uint32* s32 = (uint32*)(src + numBytesStart - numBytes);
90 		*d32 = *s32;
91 	}
92 }
93 
94 // gfxset32
95 // * numBytes is expected to be a multiple of 4
96 static inline void
97 gfxset32(uint8* dst, uint32 color, int32 numBytes)
98 {
99 	uint64 s64 = ((uint64)color << 32) | color;
100 	while (numBytes >= 8) {
101 		*(uint64*)dst = s64;
102 		numBytes -= 8;
103 		dst += 8;
104 	}
105 	if (numBytes == 4) {
106 		*(uint32*)dst = color;
107 	}
108 }
109 
110 union pixel32 {
111 	uint32	data32;
112 	uint8	data8[4];
113 };
114 
115 // blend_line32
116 static inline void
117 blend_line32(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b, uint8 a)
118 {
119 	pixel32 p;
120 
121 	r = (r * a) >> 8;
122 	g = (g * a) >> 8;
123 	b = (b * a) >> 8;
124 	a = 255 - a;
125 
126 	uint8 tempBuffer[pixels * 4];
127 
128 	uint8* t = tempBuffer;
129 	uint8* s = buffer;
130 
131 	for (int32 i = 0; i < pixels; i++) {
132 		p.data32 = *(uint32*)s;
133 
134 		t[0] = ((p.data8[0] * a) >> 8) + b;
135 		t[1] = ((p.data8[1] * a) >> 8) + g;
136 		t[2] = ((p.data8[2] * a) >> 8) + r;
137 
138 		t += 4;
139 		s += 4;
140 	}
141 
142 	gfxcpy32(buffer, tempBuffer, pixels * 4);
143 }
144 
145 void align_rect_to_pixels(BRect* rect);
146 
147 #endif	// DRAWING_SUPPORT_H
148