You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libksquirrel/kernel/kls_ttf/ftview/gblender.h

217 lines
8.1 KiB

/****************************************************************************
*
* Gamma-correct alpha blending of text
*
* (C) 2004 David Turner
*
*/
#ifndef __GBLENDER_H__
#define __GBLENDER_H__
#ifndef GBLENDER_API
#define GBLENDER_API(x) extern x
#endif
#ifndef GBLENDER_APIDEF
#define GBLENDER_APIDEF(x) x
#endif
#define GBLENDER_SHADE_BITS 4 /* must be <= 7 !! */
#define GBLENDER_SHADE_COUNT ( 1 << GBLENDER_SHADE_BITS )
#define GBLENDER_SHADE_INDEX(n) ((n + (GBLENDER_SHADE_COUNT/2)) >> GBLENDER_SHADE_BITS)
#define GBLENDER_KEY_COUNT 256
#define GBLENDER_GAMMA_SHIFT 2
#define xGBLENDER_STORE_BYTES /* define this to store (R,G,B) values on 3 \
* bytes, instead of a single 32-bit integer.\
* surprisingly, this can speed up \
* the blender on certain machines. \
* Go figure what's really happenning though :-) \
*/
#define GBLENDER_STATS /* define this to collect statistics in the \
* blender \
*/
typedef unsigned int GBlenderPixel; /* needs 32-bits here !! */
#ifdef GBLENDER_STORE_BYTES
typedef unsigned char GBlenderCell;
# define GBLENDER_CELL_SIZE 3
#else
typedef GBlenderPixel GBlenderCell;
# define GBLENDER_CELL_SIZE 1
#endif
typedef struct
{
GBlenderPixel background;
GBlenderPixel foreground;
GBlenderCell* cells;
} GBlenderKeyRec, *GBlenderKey;
typedef struct
{
unsigned short backfore; /* (fore << 8) | back */
signed short index; /* offset in (unsigned char*)cells */
} GBlenderChanKeyRec, *GBlenderChanKey;
typedef struct GBlenderRec_
{
GBlenderKeyRec keys [ GBLENDER_KEY_COUNT ];
GBlenderCell cells[ GBLENDER_KEY_COUNT*GBLENDER_SHADE_COUNT*GBLENDER_CELL_SIZE ];
/* a small cache for normal modes
*/
GBlenderPixel cache_back;
GBlenderPixel cache_fore;
GBlenderCell* cache_cells;
/* a small cache for RGB channels modes
*/
int cache_r_back;
int cache_r_fore;
unsigned char* cache_r_cells;
int cache_g_back;
int cache_g_fore;
unsigned char* cache_g_cells;
int cache_b_back;
int cache_b_fore;
unsigned char* cache_b_cells;
/* are we in color or channel mode ?
*/
int channels;
/* the gamma table
*/
unsigned short gamma_ramp[256]; /* voltage to linear */
unsigned char gamma_ramp_inv[256 << GBLENDER_GAMMA_SHIFT]; /* linear to voltage */
#ifdef GBLENDER_STATS
long stat_hits; /* number of direct hits */
long stat_lookups; /* number of table lookups */
long stat_keys; /* number of table key recomputation */
long stat_clears; /* number of table clears */
#endif
} GBlenderRec, *GBlender;
/* initialize with a given gamma */
GBLENDER_API( void )
gblender_init( GBlender blender,
double gamma );
/* clear blender, and reset stats */
GBLENDER_API( void )
gblender_reset( GBlender reset );
/* lookup a cell range for a given (background,foreground) pair
*/
GBLENDER_API( GBlenderCell* )
gblender_lookup( GBlender blender,
GBlenderPixel background,
GBlenderPixel foreground );
GBLENDER_API( unsigned char* )
gblender_lookup_channel( GBlender blender,
int background,
int foreground );
#ifdef GBLENDER_STATS
GBLENDER_API( void )
gblender_dump_stats( GBlender blender );
#else
# define gblender_dump_stats(b) do { } while (0);
#endif
/* no final `;'! */
#define GBLENDER_VARS(_gb,_fore) \
GBlenderPixel _gback = (_gb)->cache_back; \
GBlenderCell* _gcells = ( (_fore) == (_gb)->cache_fore ? (_gb)->cache_cells : gblender_lookup( (_gb), _gback, _fore ) ); \
GBlenderPixel _gfore = (_fore)
#define GBLENDER_CLOSE(_gb) \
(_gb)->cache_back = _gback; \
(_gb)->cache_fore = _gfore; \
(_gb)->cache_cells = _gcells;
/* no final `;'! */
#define GBLENDER_CHANNEL_VARS(_gb,_rfore,_gfore,_bfore) \
int _grback = (_gb)->cache_r_back; \
unsigned char* _grcells = ( (_rfore) == (_gb)->cache_r_fore ? (_gb)->cache_r_cells : gblender_lookup_channel( (_gb), _grback, _rfore )); \
int _grfore = (_rfore); \
int _ggback = (_gb)->cache_g_back; \
unsigned char* _ggcells = ( (_gfore) == (_gb)->cache_g_fore ? (_gb)->cache_g_cells : gblender_lookup_channel( (_gb), _ggback, _gfore )); \
int _ggfore = (_rfore); \
int _gbback = (_gb)->cache_b_back; \
unsigned char* _gbcells = ( (_bfore) == (_gb)->cache_b_fore ? (_gb)->cache_b_cells : gblender_lookup_channel( (_gb), _gbback, _bfore )); \
int _gbfore = (_bfore)
#define GBLENDER_CHANNEL_CLOSE(_gb) \
(_gb)->cache_r_back = _grback; \
(_gb)->cache_r_fore = _grfore; \
(_gb)->cache_r_cells = _grcells; \
(_gb)->cache_g_back = _ggback; \
(_gb)->cache_g_fore = _ggfore; \
(_gb)->cache_g_cells = _ggcells; \
(_gb)->cache_b_back = _gbback; \
(_gb)->cache_b_fore = _gbfore; \
(_gb)->cache_b_cells = _gbcells;
#ifdef GBLENDER_STATS
#define GBLENDER_STAT_HIT(gb) (gb)->stat_hits++
#else
#define GBLENDER_STAT_HIT(gb) /* nothing */
#endif
#define GBLENDER_LOOKUP(gb,back) \
GBLENDER_STAT_HIT(gb); \
if ( _gback != (GBlenderPixel)(back) ) \
{ \
_gback = (GBlenderPixel)(back); \
_gcells = gblender_lookup( (gb), _gback, _gfore ); \
}
#define GBLENDER_LOOKUP_R(gb,back) \
GBLENDER_STAT_HIT(gb); \
if ( _grback != (int)(back) ) \
{ \
_grback = (GBlenderPixel)(back); \
_grcells = gblender_lookup_channel( (gb), _grback, _grfore ); \
}
#define GBLENDER_LOOKUP_G(gb,back) \
GBLENDER_STAT_HIT(gb); \
if ( _ggback != (int)(back) ) \
{ \
_ggback = (GBlenderPixel)(back); \
_ggcells = gblender_lookup_channel( (gb), _ggback, _ggfore ); \
}
#define GBLENDER_LOOKUP_B(gb,back) \
GBLENDER_STAT_HIT(gb); \
if ( _gbback != (int)(back) ) \
{ \
_gbback = (GBlenderPixel)(back); \
_gbcells = gblender_lookup_channel( (gb), _gbback, _gbfore ); \
}
#endif /* __GBENCH_CACHE_H__ */