This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
SoftwareRasterizer/include/fbgfx/color.h

179 lines
5.8 KiB
C

#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "../types.h"
typedef uint32_t COLOR;
typedef uint8_t COLOR_COMPONENT;
static const COLOR_COMPONENT TRANSPARENT = 0;
static const COLOR_COMPONENT OPAQUE = 255;
static inline COLOR_COMPONENT color_get_a(COLOR color) {
return (color & 0xff000000) >> 24;
}
static inline COLOR_COMPONENT color_get_r(COLOR color) {
return (color & 0x00ff0000) >> 16;
}
static inline COLOR_COMPONENT color_get_g(COLOR color) {
return (color & 0x0000ff00) >> 8;
}
static inline COLOR_COMPONENT color_get_b(COLOR color) {
return (color & 0x000000ff);
}
static inline void color_extract(COLOR color, COLOR_COMPONENT *r, COLOR_COMPONENT *g, COLOR_COMPONENT *b, COLOR_COMPONENT *a) {
if (a)
*a = color_get_a(color);
if (r)
*r = color_get_r(color);
if (g)
*g = color_get_g(color);
if (b)
*b = color_get_b(color);
}
static inline COLOR color_create_rgba(COLOR_COMPONENT r, COLOR_COMPONENT g, COLOR_COMPONENT b, COLOR_COMPONENT a) {
return (a << 24) | (r << 16) | (g << 8) | b;
}
static inline COLOR color_create_rgb(COLOR_COMPONENT r, COLOR_COMPONENT g, COLOR_COMPONENT b) {
return color_create_rgba(r, g, b, OPAQUE);
}
/* floating-point color components */
typedef float COLORF_COMPONENT;
static const COLORF_COMPONENT TRANSPARENT_F = 0.0f;
static const COLORF_COMPONENT OPAQUE_F = 1.0f;
static inline COLORF_COMPONENT colorf_get_a(COLOR color) {
return (float)((color & 0xff000000) >> 24) / 255;
}
static inline COLORF_COMPONENT colorf_get_r(COLOR color) {
return (float)((color & 0x00ff0000) >> 16) / 255;
}
static inline COLORF_COMPONENT colorf_get_g(COLOR color) {
return (float)((color & 0x0000ff00) >> 8) / 255;
}
static inline COLORF_COMPONENT colorf_get_b(COLOR color) {
return (float)(color & 0x000000ff) / 255;
}
static inline void colorf_extract(COLOR color, COLORF_COMPONENT *r, COLORF_COMPONENT *g, COLORF_COMPONENT *b, COLORF_COMPONENT *a) {
if (a)
*a = colorf_get_a(color);
if (r)
*r = colorf_get_r(color);
if (g)
*g = colorf_get_g(color);
if (b)
*b = colorf_get_b(color);
}
static inline COLOR colorf_create_rgba(COLORF_COMPONENT r, COLORF_COMPONENT g, COLORF_COMPONENT b, COLORF_COMPONENT a) {
return ((COLOR_COMPONENT)(a * 255) << 24) |
((COLOR_COMPONENT)(r * 255) << 16) |
((COLOR_COMPONENT)(g * 255) << 8) |
(COLOR_COMPONENT)(b * 255);
}
static inline COLOR colorf_create_rgb(COLORF_COMPONENT r, COLORF_COMPONENT g, COLORF_COMPONENT b, COLORF_COMPONENT a) {
return colorf_create_rgba(r, g, b, OPAQUE_F);
}
static inline COLOR color_blend(COLOR source, COLOR destination) {
int sR = color_get_r(source);
int sG = color_get_g(source);
int sB = color_get_b(source);
int sA = color_get_a(source);
int dR = color_get_r(destination);
int dG = color_get_g(destination);
int dB = color_get_b(destination);
int dA = color_get_a(destination);
// this is equivalent to "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)"
return color_create_rgba(
(COLOR_COMPONENT)(((sR * sA) + (dR * (255 - sA))) / 255),
(COLOR_COMPONENT)(((sG * sA) + (dG * (255 - sA))) / 255),
(COLOR_COMPONENT)(((sB * sA) + (dB * (255 - sA))) / 255),
(COLOR_COMPONENT)(((sA * sA) + (dA * (255 - sA))) / 255)
);
}
static inline COLOR color_tint(COLOR color, COLOR tint) {
int cR = color_get_r(color);
int cG = color_get_g(color);
int cB = color_get_b(color);
int cA = color_get_a(color);
int tR = color_get_r(tint);
int tG = color_get_g(tint);
int tB = color_get_b(tint);
int tA = color_get_a(tint);
return color_create_rgba(
(COLOR_COMPONENT)((cR * tR) / 255),
(COLOR_COMPONENT)((cG * tG) / 255),
(COLOR_COMPONENT)((cB * tB) / 255),
(COLOR_COMPONENT)((cA * tA) / 255)
);
}
static inline COLOR color_tint_alpha(COLOR_COMPONENT alpha, COLOR tint) {
return color_create_rgba(
color_get_r(tint),
color_get_g(tint),
color_get_b(tint),
(COLOR_COMPONENT)(((uint32_t)alpha * color_get_a(tint)) / 255)
);
}
static inline void color_convert_rgba_to_rgb(COLOR rgba, COLOR_COMPONENT *r, COLOR_COMPONENT *g, COLOR_COMPONENT *b) {
COLOR_COMPONENT a = color_get_a(rgba);
*r = (COLOR_COMPONENT)(((uint32_t)color_get_r(rgba) * a) / 255);
*g = (COLOR_COMPONENT)(((uint32_t)color_get_g(rgba) * a) / 255);
*b = (COLOR_COMPONENT)(((uint32_t)color_get_b(rgba) * a) / 255);
}
/* -- */
#define COLOR_WHITE (color_create_rgb(255, 255, 255))
#define COLOR_RED (color_create_rgb(255, 0, 0))
#define COLOR_GREEN (color_create_rgb(0, 255, 0))
#define COLOR_BLUE (color_create_rgb(0, 0, 255))
#define COLOR_YELLOW (color_create_rgb(255, 255, 0))
#define COLOR_CYAN (color_create_rgb(0, 255, 255))
#define COLOR_MAGENTA (color_create_rgb(255, 0, 255))
#define COLOR_BLACK (color_create_rgb(0, 0, 0))
#define COLOR_DOS_BLACK (color_create_rgb(0, 0, 0))
#define COLOR_DOS_BLUE (color_create_rgb(0, 0, 170))
#define COLOR_DOS_GREEN (color_create_rgb(0, 170, 0))
#define COLOR_DOS_CYAN (color_create_rgb(0, 170, 170))
#define COLOR_DOS_RED (color_create_rgb(170, 0, 0))
#define COLOR_DOS_MAGENTA (color_create_rgb(170, 0, 170))
#define COLOR_DOS_BROWN (color_create_rgb(170, 85, 0))
#define COLOR_DOS_WHITE (color_create_rgb(170, 170, 170))
#define COLOR_DOS_GRAY (color_create_rgb(85, 85, 85))
#define COLOR_DOS_LIGHT_BLUE (color_create_rgb(85, 85, 255))
#define COLOR_DOS_LIGHT_GREEN (color_create_rgb(85, 255, 64))
#define COLOR_DOS_LIGHT_CYAN (color_create_rgb(85, 255, 255))
#define COLOR_DOS_LIGHT_RED (color_create_rgb(255, 85, 85))
#define COLOR_DOS_LIGHT_MAGENTA (color_create_rgb(255, 85, 255))
#define COLOR_DOS_YELLOW (color_create_rgb(255, 255, 85))
#define COLOR_DOS_BRIGHT_WHITE (color_create_rgb(255, 255, 255))
#ifdef __cplusplus
}
#endif