📄 fblin16.c
字号:
src_x_step_normal = x_step_fraction / x_denominator; src_x_step_one = SIGN(x_step_fraction); x_error_step_normal = ABS(x_step_fraction) - ABS(src_x_step_normal) * x_denominator; src_y_step_normal = y_step_fraction / y_denominator; src_y_step_one = SIGN(y_step_fraction) * srcpsd->linelen; y_error_step_normal = ABS(y_step_fraction) - ABS(src_y_step_normal) * y_denominator; src_y_step_normal *= srcpsd->linelen; /* DPRINTF("ov_stretch_image8: X: One step=%d, err-=%d; normal step=%d, err+=%d\n Y: One step=%d, err-=%d; normal step=%d, err+=%d\n", src_x_step_one, x_denominator, src_x_step_normal, x_error_step_normal, src_y_step_one, y_denominator, src_y_step_normal, y_error_step_normal); */ /* Pointer to the first source pixel */ next_src_ptr = ((unsigned short *) srcpsd->addr) + src_y_start * srcpsd->linelen + src_x_start; /* Cache the width of a scanline in dest */ dest_y_step = dstpsd->linelen; /* Pointer to the first dest pixel */ next_dest_ptr = ((unsigned short *) dstpsd->addr) + (dest_y_start * dest_y_step) + dest_x_start; /* * Note: The MWROP_SRC case below is a simple expansion of the * default case. It can be removed without significant speed * penalty if you need to reduce code size. * * The MWROP_CLEAR case could be removed. But it is a large * speed increase for a small quantity of code. */ switch (op & MWROP_EXTENSION) { case MWROP_SRC: /* Benchmarking shows that this while loop is faster than the equivalent * for loop: for(y_count=0; y_count<height; y_count++) { ... } */ y_count = height; while (y_count-- > 0) { src_ptr = next_src_ptr; dest_ptr = next_dest_ptr; x_error = x_error_start; x_count = width; while (x_count-- > 0) { *dest_ptr++ = *src_ptr; src_ptr += src_x_step_normal; x_error += x_error_step_normal; if (x_error >= 0) { src_ptr += src_x_step_one; x_error -= x_denominator; } } next_dest_ptr += dest_y_step; next_src_ptr += src_y_step_normal; y_error += y_error_step_normal; if (y_error >= 0) { next_src_ptr += src_y_step_one; y_error -= y_denominator; } } break; case MWROP_CLEAR: y_count = height; while (y_count-- > 0) { dest_ptr = next_dest_ptr; x_count = width; while (x_count-- > 0) { *dest_ptr++ = 0; } next_dest_ptr += dest_y_step; } break; default: y_count = height; while (y_count-- > 0) { src_ptr = next_src_ptr; dest_ptr = next_dest_ptr; x_error = x_error_start; x_count = width; while (x_count-- > 0) { applyOp(MWROP_TO_MODE(op), *src_ptr, dest_ptr, ADDR16); dest_ptr++; src_ptr += src_x_step_normal; x_error += x_error_step_normal; if (x_error >= 0) { src_ptr += src_x_step_one; x_error -= x_denominator; } } next_dest_ptr += dest_y_step; next_src_ptr += src_y_step_normal; y_error += y_error_step_normal; if (y_error >= 0) { next_src_ptr += src_y_step_one; y_error -= y_denominator; } } break; }}#if MW_FEATURE_PSDOP_BITMAP_BYTES_LSB_FIRST/* FIXME is the following "optimization" worthwhile? My guess is not, * but I'll leave it in for now. */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_BITMAP_BYTES_LSB_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. 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 * gr_usebg If set, bg_color is used. If zero, * then '0' bits are transparent. */static voidlinear16_drawarea_bitmap_bytes_lsb_first(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; unsigned short fg_color = gc->fg_color; unsigned short bg_color = gc->bg_color; int size_main, t, y; unsigned int advance_src, advance_dst; unsigned char bitmap_byte; 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 = fg_color ^ bg_color; size_main = last_byte - first_byte + 1; hard_prefix = 0; hard_postfix = 0; if (first_byte != last_byte) { if (prefixbits != 0) { /* Needs to do a few odd bits first */ hard_prefix = 1; size_main--; prefix_mask = 1 << prefixbits; prefix_last = 0x100; } if ( postfixbits != 7 ) { /* Last byte in source contains a few odd bits */ hard_postfix = 1; postfix_mask = 1; postfix_last = 2 << postfixbits; 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; if (gc->gr_usebg) { 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) { *dst++ = (m & *src) ? fg_color : bg_color; } src++; } /* Do all pixels 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) { *dst++ = (m & *src) ? fg_color : bg_color; } src++; } src += advance_src; dst += advance_dst; } } else { for (y = 0; y < gc->dsth; y++) { /* Do pixels of partial first byte */ if (hard_prefix) { bitmap_byte = *src++; for (m = prefix_mask; m < prefix_last; m <<= 1) { if (m & bitmap_byte) *dst = fg_color; dst++; } } /* Do all pixels of main part one byte at a time */ for (t = 0; t < size_main; t++) { bitmap_byte = *src++; if (0x01 & bitmap_byte) dst[0] = fg_color; if (0x02 & bitmap_byte) dst[1] = fg_color; if (0x04 & bitmap_byte) dst[2] = fg_color; if (0x08 & bitmap_byte) dst[3] = fg_color; if (0x10 & bitmap_byte) dst[4] = fg_color; if (0x20 & bitmap_byte) dst[5] = fg_color; if (0x40 & bitmap_byte) dst[6] = fg_color; if (0x80 & bitmap_byte) dst[7] = fg_color; dst += 8; } /* Do last few bits of line */ if (hard_postfix) { bitmap_byte = *src++; for (m = postfix_mask; m < postfix_last; m <<= 1) { if (m & bitmap_byte) *dst = fg_color; dst++; } } src += advance_src; dst += advance_dst; } } DRAWOFF;}#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 voidlinear16_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 short fg, bg; int first_byte, last_byte; int size_main; int t, y; unsigned int advance_src, advance_dst; ADDR8 src; ADDR16 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 = ((ADDR16) 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++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -