📄 fblin16.c
字号:
for ( a=0; a < 32; a++ )
for ( x=0; x < 256; x++ ) {
idx = (a << 8) | x;
/* High byte */
r = (x >> 3) * a / 31;
g = ((x << 3) & 0x38) * a / 31;
hi[idx] = (r << 11) | (g << 5);
/* Low byte */
b = (x & 0x1f) * a / 31;
g = ((x >> 5) & 0x7) * a / 31;
lo[idx] = (g << 5) | b;
}
}
static void init_wordmask_lookup(unsigned short **byte2wordmask)
{
unsigned short *maskp, *b2wm;
int t, x, u;
b2wm = *byte2wordmask = malloc(256*8*2);
if ( b2wm == 0 )
exit(17);
for ( t=0; t < 256; t++ ) {
maskp = b2wm + 8 * t;
x = t;
for ( u=1; u < 256; u <<= 1 )
if ( x & u )
*maskp++ = 0xffff;
else
*maskp++ = 0x0000;
}
}
/* psd->DrawArea operation PSDOP_PIXMAP_COPYALL which takes a
* pixmap, each line is byte aligned, and copies it to the
* screen using fg_color and bg_color to replace a 1 and 0 in
* the pixmap. This pixmap is ordered the wrong way around;
* it has the leftmost pixel (on the screen) in LSB (Bit 0)
* of the bytes.
*
* The reason why this non-intuitive bit ordering is used is
* to match the bit ordering used in the T1lib font rendering
* library.
*
* Variables used in the gc:
* dstx, dsty, dsth, dstw Destination rectangle
* srcx, srcy Source rectangle
* src_linelen Linesize in bytes of source
* pixels Pixmap data
* fg_color Color of a '1' bit
* bg_color Color of a '0' bit
*/
static void pixmap_copyall(PSD psd, driver_gc_t *gc)
{
int first_byte, last_byte;
int hard_prefix, hard_postfix;
unsigned short prefixbits, postfixbits, *maskp;
unsigned short xor_color, m;
unsigned short prefix_mask = 0, prefix_last = 0;
unsigned short postfix_mask = 0, postfix_last = 0;
int size_main, t, y;
unsigned int advance_src, advance_dst;
ADDR8 src;
ADDR16 dst;
static unsigned short *byte2wordmask = 0;
prefixbits = gc->srcx & 7;
postfixbits = (gc->srcx + gc->dstw - 1) & 7;
first_byte = gc->srcx >> 3;
last_byte = (gc->srcx + gc->dstw - 1) >> 3;
src = ((ADDR8)gc->pixels) + gc->src_linelen * gc->srcy + first_byte;
dst = ((ADDR16)psd->addr) + psd->linelen * gc->dsty + gc->dstx;
xor_color = gc->fg_color ^ gc->bg_color;
if ( first_byte != last_byte ) {
if ( prefixbits == 0 ) {
/* All bits of first byte used */
hard_prefix = 0;
size_main = last_byte - first_byte;
} else {
/* Needs to do a few odd bits first */
hard_prefix = 1;
size_main = last_byte - first_byte - 1;
prefix_mask = 1 << prefixbits;
prefix_last = 256;
}
if ( postfixbits != 7 ) {
/* Last byte in source contains a few odd bits */
hard_postfix = 1;
postfix_mask = 1;
postfix_last = 2 << postfixbits;
} else {
/* Last byte in source is used completely */
hard_postfix = 0;
size_main++;
}
} else {
/* Very narrow pixmap, fits in single first byte */
hard_prefix = 1;
hard_postfix = 0;
size_main = 0;
prefix_mask = 1 << prefixbits;
prefix_last = 1 << (prefixbits + gc->dstw);
}
advance_src = gc->src_linelen - last_byte + first_byte - 1;
advance_dst = psd->linelen - gc->dstw;
if ( byte2wordmask == 0 )
init_wordmask_lookup(&byte2wordmask);
DRAWON;
for ( y=0; y < gc->dsth; y++ ) {
/* Do pixels of partial first byte */
if ( hard_prefix ) {
for ( m=prefix_mask; m < prefix_last; m <<= 1 ) {
if ( m & *src )
*dst++ = gc->fg_color;
else
*dst++ = gc->bg_color;
}
src++;
}
/* Do all pixles of main part one byte at a time */
for ( t=0; t < size_main; t++ ) {
maskp = byte2wordmask + 8 * (*src++);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
*dst++ = gc->bg_color ^ (*maskp++ & xor_color);
}
/* Do last few bits of line */
if ( hard_postfix ) {
for ( m=postfix_mask; m < postfix_last; m <<= 1 ) {
if ( *src & m )
*dst++ = gc->fg_color;
else
*dst++ = gc->bg_color;
}
src++;
}
src += advance_src;
dst += advance_dst;
}
DRAWOFF;
}
static unsigned short *low2scale = 0, *high2scale = 0;
static void drawarea_alphamap(PSD psd, driver_gc_t *gc)
{
ADDR8 src, dst, alpha;
unsigned short psl, psh, pd;
unsigned char as, ad;
int x, y;
if ( low2scale == 0 )
init_alpha_lookup(&low2scale,&high2scale);
src = (ADDR8)(((ADDR16)gc->pixels) + gc->srcx +
gc->src_linelen * gc->srcy);
dst = (ADDR8)(((ADDR16)psd->addr) +
psd->linelen * gc->dsty + gc->dstx);
alpha = ((ADDR8)gc->misc) + gc->src_linelen * gc->srcy + gc->srcx;
DRAWON;
for ( y=0; y < gc->dsth; y++ ) {
for ( x=0; x < gc->dstw; x++ ) {
as = (*alpha++) >> 3;
ad = 31 - as;
psl = low2scale[(as<<8)|*src++];
psh = high2scale[(as<<8)|*src++];
pd = low2scale[(ad<<8)|dst[0]] +
high2scale[(ad<<8)|dst[1]];
*((unsigned short *)dst)++ = psl + psh + pd;
}
}
DRAWOFF;
}
static void drawarea_alphacol(PSD psd, driver_gc_t *gc)
{
ADDR8 dst, alpha;
unsigned short col_low, col_high, psl, psh, pd;
unsigned char as, ad;
int x, y;
if ( low2scale == 0 )
init_alpha_lookup(&low2scale,&high2scale);
dst = (ADDR8)(((ADDR16)psd->addr) +
psd->linelen * gc->dsty + gc->dstx);
alpha = ((ADDR8)gc->misc) + gc->src_linelen * gc->srcy + gc->srcx;
col_low = gc->bg_color & 0xff;
col_high = ( gc->bg_color >> 8 ) & 0xff;
DRAWON;
for ( y=0; y < gc->dsth; y++ ) {
for ( x=0; x < gc->dstw; x++ ) {
as = (*alpha++) >> 3;
if ( as ) {
if ( (ad = 31 - as) ) {
psl = low2scale[(as<<8)|col_low];
psh = high2scale[(as<<8)|col_high];
pd = low2scale[(ad<<8)|dst[0]] +
high2scale[(ad<<8)|dst[1]];
*((unsigned short *)dst)++ = psl + psh + pd;
} else {
*((unsigned short *)dst)++ = gc->bg_color;
}
}
}
}
DRAWOFF;
}
static void linear16_drawarea(PSD psd, driver_gc_t *gc, int op)
{
ADDR16 src16, dst, rsrc, rdst;
int linesize, x, y;
unsigned short pcol;
assert(psd->addr != 0);
/*assert(gc->dstw <= gc->srcw);*/
assert(gc->dstx >= 0 && gc->dstx+gc->dstw <= psd->xres);
/*assert(gc->dsty >= 0 && gc->dsty+gc->dsth <= psd->yres);*/
/*assert(gc->srcx >= 0 && gc->srcx+gc->dstw <= gc->srcw);*/
assert(gc->srcy >= 0);
#if 0
op = GD_AREA_COPY;
printf("DrawArea op=%d x=%d y=%d\n",op,gc->x,gc->y);
#endif
if ( op == PSDOP_COPY )
op = gc->gr_usebg ? PSDOP_COPYALL : PSDOP_COPYTRANS;
switch ( op ) {
case PSDOP_COPYALL:
linesize = 2 * gc->dstw;
src16 = ((ADDR16)gc->pixels) + gc->srcx +
gc->src_linelen * gc->srcy;
dst = ((ADDR16)psd->addr) + gc->dstx +
psd->linelen * gc->dsty;
DRAWON;
for ( y=1; y < gc->dsth; y++ ) {
memcpy(dst,src16,linesize);
src16 += gc->src_linelen;
dst += psd->linelen;
}
memcpy(dst,src16,linesize); /* To be seriously ANSI */
DRAWOFF;
break;
case PSDOP_COPYTRANS:
src16 = ((ADDR16)gc->pixels) + gc->srcx +
gc->src_linelen * gc->srcy;
dst = ((ADDR16)psd->addr) + gc->dstx +
psd->linelen * gc->dsty;
DRAWON;
for ( y=0; y < gc->dsth; y++ ) {
rdst = dst;
rsrc = src16;
for ( x=0; x < gc->dstw; x++ ) {
pcol = *rsrc++;
if ( pcol == gc->bg_color )
rdst++;
else
*rdst++ = pcol;
}
dst += psd->linelen;
src16 += gc->src_linelen;
}
DRAWOFF;
break;
case PSDOP_ALPHAMAP:
drawarea_alphamap(psd,gc);
break;
case PSDOP_ALPHACOL:
drawarea_alphacol(psd,gc);
break;
case PSDOP_PIXMAP_COPYALL:
pixmap_copyall(psd,gc);
break;
}
}
#endif /* USE_DRAWAREA*/
SUBDRIVER fblinear16 = {
linear16_init,
linear16_drawpixel,
linear16_readpixel,
linear16_drawhorzline,
linear16_drawvertline,
gen_fillrect,
linear16_blit,
#if USE_DRAWAREA
linear16_drawarea,
#else
NULL,
#endif
linear16_stretchblit
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -