/** * Compute a RGBA value with a specific format * \param r, g, b, a RGBA values [0-255]. * \param def_ordinal RGBA format definition. * \return RGBA nibble as ordinal value. */ adv_pixel alpha_make_from_def(unsigned r, unsigned g, unsigned b, unsigned a, adv_color_def def_ordinal) { int alpha_shift; adv_pixel alpha_mask; adv_pixel p; alpha_shiftmask_get(&alpha_shift, &alpha_mask, def_ordinal); return pixel_make_from_def(r, g, b, def_ordinal) | rgb_nibble_insert(a, alpha_shift, alpha_mask); }
static void ui_color_alpha_set(adv_pixel* map, const adv_color_rgb* fore, const adv_color_rgb* back, adv_color_def buffer_def, unsigned translucency) { unsigned i; int t; int red_shift, green_shift, blue_shift, alpha_shift; adv_pixel red_mask, green_mask, blue_mask, alpha_mask; union adv_color_def_union udef; udef.ordinal = buffer_def; rgb_shiftmask_get(&red_shift, &red_mask, udef.nibble.red_len, udef.nibble.red_pos); rgb_shiftmask_get(&green_shift, &green_mask, udef.nibble.green_len, udef.nibble.green_pos); rgb_shiftmask_get(&blue_shift, &blue_mask, udef.nibble.blue_len, udef.nibble.blue_pos); alpha_shiftmask_get(&alpha_shift, &alpha_mask, buffer_def); t = translucency; for (i = 0; i < 256; ++i) { int cr, cg, cb, ca; double F, B, A; double I, T; double a, b, c; /* I = ui foreground/background alpha channel T = ui/game alpha channel a = ui foreground component b = ui background component c = game component the color is computed with a * UI_FOREGROUND + b * UI_BACKGROUND + c * GAME with the corner conditions : T=1 -> a=I,b=1-I,c=0 T=0 -> a=I,b=0,c=1-I I=0 -> a=0,b=T,c=1-T I=1 -> a=1,b=0,c=0 where always a+b+c = 1 the following relations are arbitrarily chosen : a = I b = T * (1-I) c = (1-T) * (1-I) */ I = i / 255.0; T = t / 255.0; a = I; b = T * (1 - I); c = (1 - T) * (1 - I); A = 1 - c; /* alpha channel */ if (A == 0) { F = 0; B = 0; } else { /* the alpha component is implicitely applied */ F = a / A; B = b / A; } cr = fore->red * F + back->red * B; cg = fore->green * F + back->green * B; cb = fore->blue * F + back->blue * B; ca = 255 * A; if (cr > 255) cr = 255; if (cg > 255) cg = 255; if (cb > 255) cb = 255; if (ca > 255) ca = 255; map[i] = rgb_nibble_insert(cr, red_shift, red_mask) | rgb_nibble_insert(cg, green_shift, green_mask) | rgb_nibble_insert(cb, blue_shift, blue_mask) | rgb_nibble_insert(ca, alpha_shift, alpha_mask); } }