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