📄 fblin24.c
字号:
/* Pointer to the first source pixel */ next_src_ptr = ((unsigned char *) srcpsd->addr) + 3 * (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 char *) dstpsd->addr) + 3 * (dest_y_start * dest_y_step + dest_x_start); /* Convert from pixels to bytes (only for this 24bpp mode) */ src_x_step_normal *= 3; src_x_step_one *= 3; src_y_step_normal *= 3; src_y_step_one *= 3; /* * 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[0]; *dest_ptr++ = src_ptr[1]; *dest_ptr++ = src_ptr[2]; 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 * 3; 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[0], dest_ptr, ADDR8); dest_ptr++; applyOp(MWROP_TO_MODE(op), src_ptr[1], dest_ptr, ADDR8); dest_ptr++; applyOp(MWROP_TO_MODE(op), src_ptr[2], dest_ptr, ADDR8); 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/* 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 voidlinear24_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; unsigned char fg_r, fg_g, fg_b, bg_r, bg_g, bg_b; int first_byte, last_byte; int size_main; int t, y; unsigned int advance_src, advance_dst; ADDR8 src; ADDR8 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 = ((ADDR8) psd->addr) + (psd->linelen * gc->dsty + gc->dstx) * 3; fg = gc->fg_color; fg_r = PIXEL888RED(fg); fg_g = PIXEL888GREEN(fg); fg_b = PIXEL888BLUE(fg); bg = gc->bg_color; bg_r = PIXEL888RED(bg); bg_g = PIXEL888GREEN(bg); bg_b = PIXEL888BLUE(bg); advance_src = gc->src_linelen - last_byte + first_byte - 1; advance_dst = (psd->linelen - gc->dstw) * 3; 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)) { if (mask & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } } } /* 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++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(1) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(2) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(3) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(4) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(5) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(6) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } if (MWI_BIT_NO(7) & bitmap_byte) { *dst++ = fg_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } } /* 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_b; *dst++ = fg_g; *dst++ = fg_r; } else { *dst++ = bg_b; *dst++ = bg_g; *dst++ = bg_r; } } } 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[0] = fg_b; dst[1] = fg_g; dst[2] = fg_r; } dst += 3; } } /* 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 * 3 + 0] = fg_b; dst[0 * 3 + 1] = fg_g; dst[0 * 3 + 2] = fg_r; } if (MWI_BIT_NO(1) & bitmap_byte) { dst[1 * 3 + 0] = fg_b; dst[1 * 3 + 1] = fg_g; dst[1 * 3 + 2] = fg_r; } if (MWI_BIT_NO(2) & bitmap_byte) { dst[2 * 3 + 0] = fg_b; dst[2 * 3 + 1] = fg_g; dst[2 * 3 + 2] = fg_r; } if (MWI_BIT_NO(3) & bitmap_byte) { dst[3 * 3 + 0] = fg_b; dst[3 * 3 + 1] = fg_g; dst[3 * 3 + 2] = fg_r; } if (MWI_BIT_NO(4) & bitmap_byte) { dst[4 * 3 + 0] = fg_b; dst[4 * 3 + 1] = fg_g; dst[4 * 3 + 2] = fg_r; } if (MWI_BIT_NO(5) & bitmap_byte) { dst[5 * 3 + 0] = fg_b; dst[5 * 3 + 1] = fg_g; dst[5 * 3 + 2] = fg_r; } if (MWI_BIT_NO(6) & bitmap_byte) { dst[6 * 3 + 0] = fg_b; dst[6 * 3 + 1] = fg_g; dst[6 * 3 + 2] = fg_r; } if (MWI_BIT_NO(7) & bitmap_byte) { dst[7 * 3 + 0] = fg_b; dst[7 * 3 + 1] = fg_g; dst[7 * 3 + 2] = fg_r; } dst += 8 * 3; } /* 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[0] = fg_b; dst[1] = fg_g; dst[2] = fg_r; } dst += 3; } } src += advance_src; dst += advance_dst; } } DRAWOFF;#undef MWI_IS_BIT_BEFORE_OR_EQUAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -