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
14class BRect;
15
16
17// gfxcpy
18static inline void
19gfxcpy(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
65static inline void
66gfxcpy32(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
96static inline void
97gfxset32(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
110union pixel32 {
111	uint32	data32;
112	uint8	data8[4];
113};
114
115// blend_line32
116static inline void
117blend_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
145void align_rect_to_pixels(BRect* rect);
146
147#endif	// DRAWING_SUPPORT_H
148