📄 fblin32.c
字号:
* bg_color Color of a '0' bit * gr_usebg If set, bg_color is used. If zero, * then '0' bits are transparent. */static voidlinear32_drawarea_bitmap_bytes_lsb_first(PSD psd, driver_gc_t * gc){/* * The difference between the MSB_FIRST and LSB_FIRST variants of * this function is simply the definition of these three #defines. * * MWI_IS_BIT_BEFORE_OR_EQUAL(A,B) returns true if bit A is before * (i.e. to the left of) bit B. * MWI_ADVANCE_BIT(X) advances X on to the next bit to the right, * and stores the result back in X. * MWI_BIT_NO(N), where 0<=n<=7, gives the Nth bit, where 0 is the * leftmost bit and 7 is the rightmost bit. This is a constant * iff N is a constant. */#define MWI_IS_BIT_BEFORE_OR_EQUAL(a,b) ((a) <= (b))#define MWI_ADVANCE_BIT(target) ((target) <<= 1)#define MWI_BIT_NO(n) (0x01 << (n))/* * Two convenience defines - these are the same for MSB_FIRST and * LSB_FIRST. */#define MWI_FIRST_BIT MWI_BIT_NO(0)#define MWI_LAST_BIT MWI_BIT_NO(7) unsigned char prefix_first_bit; unsigned char postfix_first_bit = MWI_FIRST_BIT; unsigned char postfix_last_bit; unsigned char bitmap_byte; unsigned char mask; unsigned long fg, bg; int first_byte, last_byte; int size_main; int t, y; unsigned int advance_src, advance_dst; ADDR8 src; ADDR32 dst; /* The bit in the first byte, which corresponds to the leftmost pixel. */ prefix_first_bit = MWI_BIT_NO(gc->srcx & 7); /* The bit in the last byte, which corresponds to the rightmost pixel. */ postfix_last_bit = MWI_BIT_NO((gc->srcx + gc->dstw - 1) & 7); /* The index into each scanline of the first byte to use. */ first_byte = gc->srcx >> 3; /* The index into each scanline of the last byte to use. */ last_byte = (gc->srcx + gc->dstw - 1) >> 3; src = ((ADDR8) gc->pixels) + gc->src_linelen * gc->srcy + first_byte; dst = ((ADDR32) psd->addr) + psd->linelen * gc->dsty + gc->dstx; fg = gc->fg_color; bg = gc->bg_color; advance_src = gc->src_linelen - last_byte + first_byte - 1; advance_dst = psd->linelen - gc->dstw; if (first_byte != last_byte) { /* The total number of bytes to use, less the two special-cased * bytes (first and last). */ size_main = last_byte - first_byte + 1 - 2; if (prefix_first_bit == MWI_FIRST_BIT) { /* No need to special case. */ prefix_first_bit = 0; size_main++; } if (postfix_last_bit == MWI_LAST_BIT) { /* No need to special case. */ postfix_last_bit = 0; size_main++; } } else if ((prefix_first_bit == MWI_FIRST_BIT) && (postfix_last_bit == MWI_LAST_BIT)) { /* Exactly one byte wide. */ prefix_first_bit = 0; postfix_last_bit = 0; size_main = 1; } else { /* Very narrow pixmap, fits in single first byte. */ /* Do everything in 'postfix' loop. */ postfix_first_bit = prefix_first_bit; prefix_first_bit = 0; size_main = 0; } DRAWON; if (gc->gr_usebg) { for (y = 0; y < gc->dsth; y++) { /* Do pixels of partial first byte */ if (prefix_first_bit) { bitmap_byte = *src++; for (mask = prefix_first_bit; mask; MWI_ADVANCE_BIT(mask)) { *dst++ = (mask & bitmap_byte) ? fg : bg; } } /* Do all pixels of main part one byte at a time */ for (t = size_main; t != 0; t--) { bitmap_byte = *src++; *dst++ = (MWI_BIT_NO(0) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(1) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(2) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(3) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(4) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(5) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(6) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(7) & bitmap_byte) ? fg : bg; } /* Do last few bits of line */ if (postfix_last_bit) { bitmap_byte = *src++; for (mask = postfix_first_bit; MWI_IS_BIT_BEFORE_OR_EQUAL(mask, postfix_last_bit); MWI_ADVANCE_BIT(mask)) { *dst++ = (mask & bitmap_byte) ? fg : bg; } } src += advance_src; dst += advance_dst; } } else { for (y = 0; y < gc->dsth; y++) { /* Do pixels of partial first byte */ if (prefix_first_bit) { bitmap_byte = *src++; for (mask = prefix_first_bit; mask; MWI_ADVANCE_BIT(mask)) { if (mask & bitmap_byte) *dst = fg; dst++; } } /* Do all pixels of main part one byte at a time */ for (t = size_main; t != 0; t--) { bitmap_byte = *src++; if (MWI_BIT_NO(0) & bitmap_byte) dst[0] = fg; if (MWI_BIT_NO(1) & bitmap_byte) dst[1] = fg; if (MWI_BIT_NO(2) & bitmap_byte) dst[2] = fg; if (MWI_BIT_NO(3) & bitmap_byte) dst[3] = fg; if (MWI_BIT_NO(4) & bitmap_byte) dst[4] = fg; if (MWI_BIT_NO(5) & bitmap_byte) dst[5] = fg; if (MWI_BIT_NO(6) & bitmap_byte) dst[6] = fg; if (MWI_BIT_NO(7) & bitmap_byte) dst[7] = fg; dst += 8; } /* Do last few bits of line */ if (postfix_last_bit) { bitmap_byte = *src++; for (mask = postfix_first_bit; MWI_IS_BIT_BEFORE_OR_EQUAL(mask, postfix_last_bit); MWI_ADVANCE_BIT(mask)) { if (mask & bitmap_byte) *dst = fg; dst++; } } src += advance_src; dst += advance_dst; } } DRAWOFF;#undef MWI_IS_BIT_BEFORE_OR_EQUAL#undef MWI_ADVANCE_BIT#undef MWI_BIT_NO#undef MWI_FIRST_BIT#undef MWI_LAST_BIT}#endif /* MW_FEATURE_PSDOP_BITMAP_BYTES_LSB_FIRST */#if MW_FEATURE_PSDOP_BITMAP_BYTES_MSB_FIRST/* psd->DrawArea operation PSDOP_BITMAP_BYTES_MSB_FIRST 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. * * The bitmap is ordered how you'd expect, with the MSB used * for the leftmost of the 8 pixels controlled by each byte. * * 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 * gr_usebg If set, bg_color is used. If zero, * then '0' bits are transparent. */static voidlinear32_drawarea_bitmap_bytes_msb_first(PSD psd, driver_gc_t * gc){/* * The difference between the MSB_FIRST and LSB_FIRST variants of * this function is simply the definition of these three #defines. * * MWI_IS_BIT_BEFORE_OR_EQUAL(A,B) returns true if bit A is before * (i.e. to the left of) bit B. * MWI_ADVANCE_BIT(X) advances X on to the next bit to the right, * and stores the result back in X. * MWI_BIT_NO(N), where 0<=n<=7, gives the Nth bit, where 0 is the * leftmost bit and 7 is the rightmost bit. This is a constant * iff N is a constant. */#define MWI_IS_BIT_BEFORE_OR_EQUAL(a,b) ((a) >= (b))#define MWI_ADVANCE_BIT(target) ((target) >>= 1)#define MWI_BIT_NO(n) (0x80 >> (n))/* * Two convenience defines - these are the same for MSB_FIRST and * LSB_FIRST. */#define MWI_FIRST_BIT MWI_BIT_NO(0)#define MWI_LAST_BIT MWI_BIT_NO(7) unsigned char prefix_first_bit; unsigned char postfix_first_bit = MWI_FIRST_BIT; unsigned char postfix_last_bit; unsigned char bitmap_byte; unsigned char mask; unsigned long fg, bg; int first_byte, last_byte; int size_main; int t, y; unsigned int advance_src, advance_dst; ADDR8 src; ADDR32 dst; /* The bit in the first byte, which corresponds to the leftmost pixel. */ prefix_first_bit = MWI_BIT_NO(gc->srcx & 7); /* The bit in the last byte, which corresponds to the rightmost pixel. */ postfix_last_bit = MWI_BIT_NO((gc->srcx + gc->dstw - 1) & 7); /* The index into each scanline of the first byte to use. */ first_byte = gc->srcx >> 3; /* The index into each scanline of the last byte to use. */ last_byte = (gc->srcx + gc->dstw - 1) >> 3; src = ((ADDR8) gc->pixels) + gc->src_linelen * gc->srcy + first_byte; dst = ((ADDR32) psd->addr) + psd->linelen * gc->dsty + gc->dstx; fg = gc->fg_color; bg = gc->bg_color; advance_src = gc->src_linelen - last_byte + first_byte - 1; advance_dst = psd->linelen - gc->dstw; if (first_byte != last_byte) { /* The total number of bytes to use, less the two special-cased * bytes (first and last). */ size_main = last_byte - first_byte + 1 - 2; if (prefix_first_bit == MWI_FIRST_BIT) { /* No need to special case. */ prefix_first_bit = 0; size_main++; } if (postfix_last_bit == MWI_LAST_BIT) { /* No need to special case. */ postfix_last_bit = 0; size_main++; } } else if ((prefix_first_bit == MWI_FIRST_BIT) && (postfix_last_bit == MWI_LAST_BIT)) { /* Exactly one byte wide. */ prefix_first_bit = 0; postfix_last_bit = 0; size_main = 1; } else { /* Very narrow pixmap, fits in single first byte. */ /* Do everything in 'postfix' loop. */ postfix_first_bit = prefix_first_bit; prefix_first_bit = 0; size_main = 0; } DRAWON; if (gc->gr_usebg) { for (y = 0; y < gc->dsth; y++) { /* Do pixels of partial first byte */ if (prefix_first_bit) { bitmap_byte = *src++; for (mask = prefix_first_bit; mask; MWI_ADVANCE_BIT(mask)) { *dst++ = (mask & bitmap_byte) ? fg : bg; } } /* Do all pixels of main part one byte at a time */ for (t = size_main; t != 0; t--) { bitmap_byte = *src++; *dst++ = (MWI_BIT_NO(0) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(1) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(2) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(3) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(4) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(5) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(6) & bitmap_byte) ? fg : bg; *dst++ = (MWI_BIT_NO(7) & bitmap_byte) ? fg : bg; } /* Do last few bits of line */ if (postfix_last_bit) { bitmap_byte = *src++; for (mask = postfix_first_bit; MWI_IS_BIT_BEFORE_OR_EQUAL(mask, postfix_last_bit); MWI_ADVANCE_BIT(mask)) { *dst++ = (mask & bitmap_byte) ? fg : bg; } } src += advance_src; dst += advance_dst; } } else { for (y = 0; y < gc->dsth; y++) { /* Do pixels of partial first byte */ if (prefix_first_bit) { bitmap_byte = *src++; for (mask = prefix_first_bit; mask; MWI_ADVANCE_BIT(mask)) { if (mask & bitmap_byte) *dst = fg; dst++; } } /* Do all pixels of main part one byte at a time */ for (t = size_main; t != 0; t--) { bitmap_byte = *src++; if (MWI_BIT_NO(0) & bitmap_byte) dst[0] = fg; if (MWI_BIT_NO(1) & bitmap_byte) dst[1] = fg; if (MWI_BIT_NO(2) & bitmap_byte) dst[2] = fg; if (MWI_BIT_NO(3) & bitmap_byte) dst[3] = fg; if (MWI_BIT_NO(4) & bitmap_byte) dst[4] = fg; if (MWI_BIT_NO(5) & bitmap_byte) dst[5] = fg; if (MWI_BIT_NO(6) & bitmap_byte) dst[6] = fg; if (MWI_BIT_NO(7) & bitmap_byte) dst[7] = fg; dst += 8; } /* Do last few bits of line */ if (postfix_last_bit) { bitmap_byte = *src++; for (mask = postfix_first_bit; MWI_IS_BIT_BEFORE_OR_EQUAL(mask, postfix_last_bit); MWI_ADVANCE_BIT(mask)) { if (mask & bitmap_byte) *dst = fg; dst++; } } src += advance_src; dst += advance_dst; } } DRAWOFF;#undef MWI_IS_BIT_BEFORE_OR_EQUAL#undef MWI_ADVANCE_BIT#undef MWI_BIT_NO#undef MWI_FIRST_BIT#undef MWI_LAST_BIT}#endif /* MW_FEATURE_PSDOP_BITMAP_BYTES_MSB_FIRST */#if MW_FEATURE_PSDOP_ALPHACOLstatic voidlinear32_drawarea_alphacol(PSD psd, driver_gc_t * gc){ ADDR32 dst; ADDR8 alpha; unsigned long ps, pd; int as; long psr, psg, psb; int x, y; int src_row_step, dst_row_step; alpha = ((ADDR8) gc->misc) + gc->src_linelen * gc->srcy + gc->srcx; dst = ((ADDR32) psd->addr) + psd->linelen * gc->dsty + gc->dstx; ps = gc->fg_color; psr = (long) (ps & 0x00FF0000UL); psg = (long) (ps & 0x0000FF00UL); psb = (long) (ps & 0x000000FFUL); src_row_step = gc->src_linelen - gc->dstw; dst_row_step = psd->linelen - gc->dstw; DRAWON; for (y = 0; y < gc->dsth; y++) { for (x = 0; x < gc->dstw; x++) { as = *alpha++; if (as == 255) { *dst++ = ps; } else if (as != 0) { /* * Scale alpha value from 255ths to 256ths * (In other words, if as >= 128, add 1 to it) * * Also flip the direction of alpha, so it's * backwards from it's usual meaning. * This is because the equation below is most * easily written with source and dest interchanged * (since we can split ps into it's components * before we enter the loop) */ as = 256 - (as + (as >> 7)); pd = *dst; *dst++ = ((unsigned long) (((((long) (pd & 0x00FF0000UL) - psr) * as) >> 8) + psr) & 0x00FF0000UL) | ((unsigned long) (((((long) (pd & 0x0000FF00UL) - psg) * as) >> 8) + psg) & 0x0000FF00UL) | ((unsigned long) (((((long) (pd & 0x000000FFUL) - psb) * as) >> 8) + psb) & 0x000000FFUL); } else { dst++; } } alpha += src_row_step; dst += dst_row_step; } DRAWOFF;}#endif /* MW_FEATURE_PSDOP_ALPHACOL */static voidlinear32_drawarea(PSD psd, driver_gc_t * gc, int op){ 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); /*DPRINTF("linear32_drawarea op=%d dstx=%d dsty=%d\n", op, gc->dstx, gc->dsty);*/ switch (op) {#if MW_FEATURE_PSDOP_ALPHACOL case PSDOP_ALPHACOL: linear32_drawarea_alphacol(psd, gc); break;#endif /* MW_FEATURE_PSDOP_ALPHACOL */#if MW_FEATURE_PSDOP_BITMAP_BYTES_LSB_FIRST case PSDOP_BITMAP_BYTES_LSB_FIRST: linear32_drawarea_bitmap_bytes_lsb_first(psd, gc); break;#endif /* MW_FEATURE_PSDOP_BITMAP_BYTES_LSB_FIRST */#if MW_FEATURE_PSDOP_BITMAP_BYTES_MSB_FIRST case PSDOP_BITMAP_BYTES_MSB_FIRST: linear32_drawarea_bitmap_bytes_msb_first(psd, gc); break;#endif /* MW_FEATURE_PSDOP_BITMAP_BYTES_MSB_FIRST */ }}SUBDRIVER fblinear32 = { linear32_init, linear32_drawpixel, linear32_readpixel, linear32_drawhorzline, linear32_drawvertline, gen_fillrect, linear32_blit, linear32_drawarea, linear32_stretchblit, linear32_stretchblitex,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -