📄 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 + -