xref: /haiku/src/kits/interface/GraphicsDefs.cpp (revision 97dfeb96704e5dbc5bec32ad7b21379d0125e031)
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_RGB32: case B_RGBA32:
101 		case B_RGB32_BIG: case B_RGBA32_BIG:
102 		case B_UVL32: case B_UVLA32:
103 		case B_LAB32: case B_LABA32:
104 		case B_HSI32: case B_HSIA32:
105 		case B_HSV32: case B_HSVA32:
106 		case B_HLS32: case B_HLSA32:
107 		case B_CMY32: case B_CMYA32: case B_CMYK32:
108 			bytesPerPixel = 4;
109 			pixPerChunk = 1;
110 			break;
111 		case B_RGB24: case B_RGB24_BIG:
112 		case B_UVL24: case B_LAB24: case B_HSI24:
113 		case B_HSV24: case B_HLS24: case B_CMY24:
114 			bytesPerPixel = 3;
115 			pixPerChunk = 1;
116 			break;
117 		case B_RGB16:		case B_RGB15:		case B_RGBA15:
118 		case B_RGB16_BIG:	case B_RGB15_BIG:	case B_RGBA15_BIG:
119 			bytesPerPixel = 2;
120 			pixPerChunk = 1;
121 			break;
122 		case B_CMAP8: case B_GRAY8:
123 			bytesPerPixel = 1;
124 			pixPerChunk = 1;
125 			break;
126 		case B_GRAY1:
127 			bytesPerPixel = 1;
128 			pixPerChunk = 8;
129 			break;
130 		case B_YCbCr422: case B_YUV422:
131 			bytesPerPixel = 4;
132 			pixPerChunk = 2;
133 			break;
134 		case B_YCbCr411: case B_YUV411:
135 			bytesPerPixel = 12;
136 			pixPerChunk = 8;
137 			break;
138 		case B_YCbCr444: case B_YUV444:
139 			bytesPerPixel = 3;
140 			pixPerChunk = 1;
141 			break;
142 		// TODO: I don't know if it's correct,
143 		// but beos reports B_YUV420 to be
144 		// 6 bytes per pixel and 4 pixel per chunk
145 		case B_YCbCr420: case B_YUV420:
146 			bytesPerPixel = 3;
147 			pixPerChunk = 2;
148 			break;
149 		case B_YUV9:
150 			bytesPerPixel = 5;
151 			pixPerChunk = 4;
152 			break;
153 		case B_YUV12:
154 			bytesPerPixel = 6;
155 			pixPerChunk = 4;
156 			break;
157 		// unsupported
158 		case B_NO_COLOR_SPACE:
159 		default:
160 			status = B_BAD_VALUE;
161 			break;
162 	}
163 
164 	if (pixelChunk != NULL)
165 		*pixelChunk = bytesPerPixel;
166 
167 	size_t alignment = 0;
168 	if (bytesPerPixel != 0) {
169 		alignment = (sizeof(int) % bytesPerPixel) * sizeof(int);
170 		if (alignment < sizeof(int))
171 			alignment = sizeof(int);
172 	}
173 
174 	if (rowAlignment!= NULL)
175 		*rowAlignment = alignment;
176 
177 	if (pixelsPerChunk!= NULL)
178 		*pixelsPerChunk = pixPerChunk;
179 
180 	return status;
181 }
182 
183 
184 static uint32
185 get_overlay_flags(color_space space)
186 {
187 	BPrivate::AppServerLink link;
188 	link.StartMessage(AS_GET_BITMAP_SUPPORT_FLAGS);
189 	link.Attach<uint32>((uint32)space);
190 
191 	uint32 flags = 0;
192 	int32 code;
193 	if (link.FlushWithReply(code) == B_OK && code == B_OK) {
194 		if (link.Read<uint32>(&flags) < B_OK)
195 			flags = 0;
196 	}
197 	return flags;
198 }
199 
200 
201 bool
202 bitmaps_support_space(color_space space, uint32 *supportFlags)
203 {
204 	bool result = true;
205 	switch (space) {
206 		// supported, also for drawing and for attaching BViews
207 		case B_RGB32:		case B_RGBA32:		case B_RGB24:
208 		case B_RGB32_BIG:	case B_RGBA32_BIG:	case B_RGB24_BIG:
209 		case B_RGB16:		case B_RGB15:		case B_RGBA15:
210 		case B_RGB16_BIG:	case B_RGB15_BIG:	case B_RGBA15_BIG:
211 		case B_CMAP8:		case B_GRAY8:		case B_GRAY1:
212 			if (supportFlags != NULL) {
213 				*supportFlags = B_VIEWS_SUPPORT_DRAW_BITMAP
214 					| B_BITMAPS_SUPPORT_ATTACHED_VIEWS
215 					| get_overlay_flags(space);
216 			}
217 			break;
218 
219 		// supported, but cannot draw
220 		case B_YCbCr422: case B_YCbCr411: case B_YCbCr444: case B_YCbCr420:
221 		case B_YUV422: case B_YUV411: case B_YUV444: case B_YUV420:
222 		case B_UVL24: case B_UVL32: case B_UVLA32:
223 		case B_LAB24: case B_LAB32: case B_LABA32:
224 		case B_HSI24: case B_HSI32: case B_HSIA32:
225 		case B_HSV24: case B_HSV32: case B_HSVA32:
226 		case B_HLS24: case B_HLS32: case B_HLSA32:
227 		case B_CMY24: case B_CMY32: case B_CMYA32: case B_CMYK32:
228 			if (supportFlags != NULL)
229 				*supportFlags = get_overlay_flags(space);
230 			break;
231 		// unsupported
232 		case B_NO_COLOR_SPACE:
233 		case B_YUV9: case B_YUV12:
234 			result = false;
235 			break;
236 	}
237 	return result;
238 }
239