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