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