xref: /haiku/src/kits/interface/GraphicsDefs.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
1 /*
2  * Copyright 2001-2015, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		DarkWyrm <bpmagic@columbus.rr.com>
7  *		Caz <turok2@currantbun.com>
8  *		Axel Dörfler, axeld@pinc-software.de
9  */
10 
11 //!	Graphics functions and variables for the Interface Kit
12 
13 #include <GraphicsDefs.h>
14 
15 #include <AppServerLink.h>
16 #include <ServerProtocol.h>
17 
18 
19 // patterns
20 const pattern B_SOLID_HIGH = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
21 const pattern B_MIXED_COLORS = {{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55}};
22 const pattern B_SOLID_LOW = {{0, 0, 0, 0, 0, 0, 0, 0}};
23 
24 // colors
25 const rgb_color B_TRANSPARENT_COLOR = {0x77, 0x74, 0x77, 0x00};
26 const rgb_color B_TRANSPARENT_32_BIT = {0x77, 0x74, 0x77, 0x00};
27 const uint8 B_TRANSPARENT_8_BIT = 0xff;
28 
29 const uint8 B_TRANSPARENT_MAGIC_CMAP8 = 0xff;
30 const uint16 B_TRANSPARENT_MAGIC_RGBA15 = 0x39ce;
31 const uint16 B_TRANSPARENT_MAGIC_RGBA15_BIG = 0xce39;
32 const uint32 B_TRANSPARENT_MAGIC_RGBA32 = 0x00777477;
33 const uint32 B_TRANSPARENT_MAGIC_RGBA32_BIG = 0x77747700;
34 
35 // misc.
36 const struct screen_id B_MAIN_SCREEN_ID = {0};
37 
38 
39 // rgb_color
40 int32
41 rgb_color::Brightness() const
42 {
43 	return ((int32)red * 41 + (int32)green * 187 + (int32)blue * 28) >> 8;
44 }
45 
46 
47 // Mix two colors without respect for their alpha values
48 rgb_color
49 mix_color(rgb_color color1, rgb_color color2, uint8 amount)
50 {
51 	color1.red = (uint8)(((int16(color2.red) - int16(color1.red)) * amount)
52 		/ 255 + color1.red);
53 	color1.green = (uint8)(((int16(color2.green) - int16(color1.green))
54 		* amount) / 255 + color1.green);
55 	color1.blue = (uint8)(((int16(color2.blue) - int16(color1.blue)) * amount)
56 		/ 255 + color1.blue );
57 	color1.alpha = (uint8)(((int16(color2.alpha) - int16(color1.alpha))
58 		* amount) / 255 + color1.alpha );
59 
60 	return color1;
61 }
62 
63 
64 // Mix two colors, respecting their alpha values.
65 rgb_color
66 blend_color(rgb_color color1, rgb_color color2, uint8 amount)
67 {
68 	const uint8 alphaMix = (uint8)(((int16(color2.alpha) - int16(255
69 		- color1.alpha)) * amount) / 255 + (255 - color1.alpha));
70 
71 	color1.red = (uint8)(((int16(color2.red) - int16(color1.red)) * alphaMix)
72 		/ 255 + color1.red );
73 	color1.green = (uint8)(((int16(color2.green) - int16(color1.green))
74 		* alphaMix) / 255 + color1.green);
75 	color1.blue = (uint8)(((int16(color2.blue) - int16(color1.blue))
76 		* alphaMix) / 255 + color1.blue);
77 	color1.alpha = (uint8)(((int16(color2.alpha) - int16(color1.alpha))
78 		* amount) / 255 + color1.alpha);
79 
80 	return color1;
81 }
82 
83 
84 rgb_color
85 disable_color(rgb_color color, rgb_color background)
86 {
87 	return mix_color(color, background, 185);
88 }
89 
90 
91 status_t
92 get_pixel_size_for(color_space space, size_t *pixelChunk, size_t *rowAlignment,
93 	size_t *pixelsPerChunk)
94 {
95 	status_t status = B_OK;
96 	int32 bytesPerPixel = 0;
97 	int32 pixPerChunk = 0;
98 	switch (space) {
99 		// supported
100 		case B_RGBA64: case B_RGBA64_BIG:
101 			bytesPerPixel = 8;
102 			pixPerChunk = 2;
103 			break;
104 		case B_RGB48: case B_RGB48_BIG:
105 			bytesPerPixel = 6;
106 			pixPerChunk = 2;
107 			break;
108 		case B_RGB32: case B_RGBA32:
109 		case B_RGB32_BIG: case B_RGBA32_BIG:
110 		case B_UVL32: case B_UVLA32:
111 		case B_LAB32: case B_LABA32:
112 		case B_HSI32: case B_HSIA32:
113 		case B_HSV32: case B_HSVA32:
114 		case B_HLS32: case B_HLSA32:
115 		case B_CMY32: case B_CMYA32: case B_CMYK32:
116 			bytesPerPixel = 4;
117 			pixPerChunk = 1;
118 			break;
119 		case B_RGB24: case B_RGB24_BIG:
120 		case B_UVL24: case B_LAB24: case B_HSI24:
121 		case B_HSV24: case B_HLS24: case B_CMY24:
122 			bytesPerPixel = 3;
123 			pixPerChunk = 1;
124 			break;
125 		case B_RGB16:		case B_RGB15:		case B_RGBA15:
126 		case B_RGB16_BIG:	case B_RGB15_BIG:	case B_RGBA15_BIG:
127 			bytesPerPixel = 2;
128 			pixPerChunk = 1;
129 			break;
130 		case B_CMAP8: case B_GRAY8:
131 			bytesPerPixel = 1;
132 			pixPerChunk = 1;
133 			break;
134 		case B_GRAY1:
135 			bytesPerPixel = 1;
136 			pixPerChunk = 8;
137 			break;
138 		case B_YCbCr422: case B_YUV422:
139 			bytesPerPixel = 4;
140 			pixPerChunk = 2;
141 			break;
142 		case B_YCbCr411: case B_YUV411:
143 			bytesPerPixel = 12;
144 			pixPerChunk = 8;
145 			break;
146 		case B_YCbCr444: case B_YUV444:
147 			bytesPerPixel = 3;
148 			pixPerChunk = 1;
149 			break;
150 		// TODO: I don't know if it's correct,
151 		// but beos reports B_YUV420 to be
152 		// 6 bytes per pixel and 4 pixel per chunk
153 		case B_YCbCr420: case B_YUV420:
154 			bytesPerPixel = 3;
155 			pixPerChunk = 2;
156 			break;
157 		case B_YUV9:
158 			bytesPerPixel = 5;
159 			pixPerChunk = 4;
160 			break;
161 		case B_YUV12:
162 			bytesPerPixel = 6;
163 			pixPerChunk = 4;
164 			break;
165 		// unsupported
166 		case B_NO_COLOR_SPACE:
167 		default:
168 			status = B_BAD_VALUE;
169 			break;
170 	}
171 
172 	if (pixelChunk != NULL)
173 		*pixelChunk = bytesPerPixel;
174 
175 	size_t alignment = 0;
176 	if (bytesPerPixel != 0) {
177 		alignment = (sizeof(int) % bytesPerPixel) * sizeof(int);
178 		if (alignment < sizeof(int))
179 			alignment = sizeof(int);
180 	}
181 
182 	if (rowAlignment!= NULL)
183 		*rowAlignment = alignment;
184 
185 	if (pixelsPerChunk!= NULL)
186 		*pixelsPerChunk = pixPerChunk;
187 
188 	return status;
189 }
190 
191 
192 static uint32
193 get_overlay_flags(color_space space)
194 {
195 	BPrivate::AppServerLink link;
196 	link.StartMessage(AS_GET_BITMAP_SUPPORT_FLAGS);
197 	link.Attach<uint32>((uint32)space);
198 
199 	uint32 flags = 0;
200 	int32 code;
201 	if (link.FlushWithReply(code) == B_OK && code == B_OK) {
202 		if (link.Read<uint32>(&flags) < B_OK)
203 			flags = 0;
204 	}
205 	return flags;
206 }
207 
208 
209 bool
210 bitmaps_support_space(color_space space, uint32 *supportFlags)
211 {
212 	bool result = true;
213 	switch (space) {
214 		// supported, also for drawing and for attaching BViews
215 		case B_RGB32:		case B_RGBA32:		case B_RGB24:
216 		case B_RGB32_BIG:	case B_RGBA32_BIG:	case B_RGB24_BIG:
217 		case B_RGB16:		case B_RGB15:		case B_RGBA15:
218 		case B_RGB16_BIG:	case B_RGB15_BIG:	case B_RGBA15_BIG:
219 		case B_CMAP8:		case B_GRAY8:		case B_GRAY1:
220 			if (supportFlags != NULL) {
221 				*supportFlags = B_VIEWS_SUPPORT_DRAW_BITMAP
222 					| B_BITMAPS_SUPPORT_ATTACHED_VIEWS
223 					| get_overlay_flags(space);
224 			}
225 			break;
226 
227 		// supported, but cannot draw
228 		case B_RGBA64: case B_RGBA64_BIG:
229 		case B_RGB48: case B_RGB48_BIG:
230 		case B_YCbCr422: case B_YCbCr411: case B_YCbCr444: case B_YCbCr420:
231 		case B_YUV422: case B_YUV411: case B_YUV444: case B_YUV420:
232 		case B_UVL24: case B_UVL32: case B_UVLA32:
233 		case B_LAB24: case B_LAB32: case B_LABA32:
234 		case B_HSI24: case B_HSI32: case B_HSIA32:
235 		case B_HSV24: case B_HSV32: case B_HSVA32:
236 		case B_HLS24: case B_HLS32: case B_HLSA32:
237 		case B_CMY24: case B_CMY32: case B_CMYA32: case B_CMYK32:
238 			if (supportFlags != NULL)
239 				*supportFlags = get_overlay_flags(space);
240 			break;
241 		// unsupported
242 		case B_NO_COLOR_SPACE:
243 		case B_YUV9: case B_YUV12:
244 			result = false;
245 			break;
246 	}
247 	return result;
248 }
249