📄 grblit.c
字号:
/****************************************************************************//* *//* The FreeType project -- a free and portable quality TrueType renderer. *//* *//* Copyright 1996-1999, 2000, 2001, 2002 by *//* D. Turner, R.Wilhelm, and W. Lemberg *//* *//* grblit.c: Support for blitting of bitmaps with various depth. *//* *//****************************************************************************/#include "grblit.h"#include "grobjs.h"#define GRAY8 static int compute_clips( grBlitter* blit, int x_offset, int y_offset ) { int xmin, ymin, xmax, ymax, width, height, target_width; /* perform clipping and setup variables */ width = blit->source.width; height = blit->source.rows; switch ( blit->source.mode ) { case gr_pixel_mode_mono: width = (width + 7) & -8; break; case gr_pixel_mode_pal4: width = (width + 1) & -2; break; case gr_pixel_mode_lcd: case gr_pixel_mode_lcd2: width /= 3; break; case gr_pixel_mode_lcdv: case gr_pixel_mode_lcdv2: height /= 3; break; default: ; } xmin = x_offset; ymin = y_offset; xmax = xmin + width-1; ymax = ymin + height-1; /* clip if necessary */ if ( width == 0 || height == 0 || xmax < 0 || xmin >= blit->target.width || ymax < 0 || ymin >= blit->target.rows ) return 1; /* set up clipping and cursors */ blit->yread = 0; if ( ymin < 0 ) { blit->yread -= ymin; height += ymin; blit->ywrite = 0; } else blit->ywrite = ymin; if ( ymax >= blit->target.rows ) height -= ymax - blit->target.rows + 1; blit->xread = 0; if ( xmin < 0 ) { blit->xread -= xmin; width += xmin; blit->xwrite = 0; } else blit->xwrite = xmin; target_width = blit->target.width; switch ( blit->target.mode ) { case gr_pixel_mode_mono: target_width = (target_width + 7) & -8; break; case gr_pixel_mode_pal4: target_width = (target_width + 1) & -2; break; default: ; } blit->right_clip = xmax - target_width + 1; if ( blit->right_clip > 0 ) width -= blit->right_clip; else blit->right_clip = 0; blit->width = width; blit->height = height; /* set read and write to the top-left corner of the read */ /* and write areas before clipping. */ blit->read = blit->source.buffer; blit->write = blit->target.buffer; blit->read_line = blit->source.pitch; blit->write_line = blit->target.pitch; if ( blit->read_line < 0 ) blit->read -= (blit->source.rows-1) * blit->read_line; if ( blit->write_line < 0 ) blit->write -= (blit->target.rows-1) * blit->write_line; /* now go to the start line. Note that we do not move the */ /* x position yet, as this is dependent on the pixel format */ blit->read += blit->yread * blit->read_line; blit->write += blit->ywrite * blit->write_line; return 0; }/**************************************************************************//* *//* <Function> blit_mono_to_mono *//* *//**************************************************************************/ static void blit_mono_to_mono( grBlitter* blit, grColor color ) { int shift, left_clip, x, y; byte* read; byte* write; (void)color; /* unused argument */ left_clip = ( blit->xread > 0 ); shift = ( blit->xwrite - blit->xread ) & 7; read = blit->read + (blit->xread >> 3); write = blit->write + (blit->xwrite >> 3); if ( shift == 0 ) { y = blit->height; do { byte* _read = read; byte* _write = write; x = blit->width; do { *_write++ |= *_read++; x -= 8; } while ( x > 0 ); read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); } else { int first, last, count; first = blit->xwrite >> 3; last = (blit->xwrite + blit->width-1) >> 3; count = last - first; if ( blit->right_clip ) count++; y = blit->height; do { unsigned char* _read = read; unsigned char* _write = write; unsigned int old; int shift2 = (8-shift); if ( left_clip ) old = (*_read++) << shift2; else old = 0; x = count; while ( x > 0 ) { unsigned char val; val = *_read++; *_write++ |= (unsigned char)( (val >> shift) | old ); old = val << shift2; x--; } if ( !blit->right_clip ) *_write |= (unsigned char)old; read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); } }/**************************************************************************//* *//* <Function> blit_mono_to_pal8 *//* *//**************************************************************************/ static void blit_mono_to_pal8( grBlitter* blit, grColor color ) { int x, y, shift; unsigned char* read; unsigned char* write; read = blit->read + (blit->xread >> 3); write = blit->write + blit->xwrite; shift = blit->xread & 7; y = blit->height; do { unsigned char* _read = read; unsigned char* _write = write; unsigned long val = (*_read++ | 0x100) << shift; x = blit->width; do { if (val & 0x10000) val = *_read++ | 0x100; if ( val & 0x80 ) *_write = (unsigned char)color.value; val <<= 1; _write++; } while ( --x > 0 ); read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); }/**************************************************************************//* *//* <Function> blit_mono_to_pal4 *//* *//**************************************************************************/ static void blit_mono_to_pal4( grBlitter* blit, grColor color ) { int x, y, phase,shift; unsigned char* read; unsigned char* write; unsigned int col; col = color.value & 15; read = blit->read + (blit->xread >> 3); write = blit->write + (blit->xwrite >> 1); /* now begin blit */ shift = blit->xread & 7; phase = blit->xwrite & 1; y = blit->height; do { unsigned char* _read = read; unsigned char* _write = write; int _phase = phase; unsigned long val = (*_read++ | 0x100) << shift; x = blit->width; do { if (val & 0x10000) val = *_read++ | 0x100; if ( val & 0x80 ) { if ( _phase ) *_write = (unsigned char)((*_write & 0xF0) | col); else *_write = (unsigned char)((*_write & 0x0F) | (col << 4)); } val <<= 1; _write += _phase; _phase ^= 1; x--; } while ( x > 0 ); read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); }/**************************************************************************//* *//* <Function> blit_mono_to_rgb16 *//* *//**************************************************************************/ static void blit_mono_to_rgb16( grBlitter* blit, grColor color ) { int x, y,shift; unsigned char* read; unsigned char* write; read = blit->read + (blit->xread >> 3); write = blit->write + blit->xwrite*2; shift = blit->xread & 7; y = blit->height; do { unsigned char* _read = read; unsigned char* _write = write; unsigned long val = (*_read++ | 0x100) << shift; x = blit->width; do { if (val & 0x10000) val = *_read++ | 0x100; if ( val & 0x80 ) *(short*)_write = (short)color.value; val <<= 1; _write +=2; x--; } while ( x > 0 ); read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); }/**************************************************************************//* *//* <Function> blit_mono_to_rgb24 *//* *//**************************************************************************/ static void blit_mono_to_rgb24( grBlitter* blit, grColor color ) { int x, y, shift; unsigned char* read; unsigned char* write; read = blit->read + (blit->xread >> 3); write = blit->write + blit->xwrite*3; shift = blit->xread & 7; y = blit->height; do { unsigned char* _read = read; unsigned char* _write = write; unsigned long val = (*_read++ | 0x100) << shift; x = blit->width; do { if (val & 0x10000) val = *_read++ | 0x100; if ( val & 0x80 ) { _write[0] = color.chroma[0]; _write[1] = color.chroma[1]; _write[2] = color.chroma[2]; } val <<= 1; _write += 3; x--; } while ( x > 0 ); read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); }/**************************************************************************//* *//* <Function> blit_mono_to_rgb32 *//* *//**************************************************************************/ static void blit_mono_to_rgb32( grBlitter* blit, grColor color ) { int x, y,shift; unsigned char* read; unsigned char* write; read = blit->read + ( blit->xread >> 3 ); write = blit->write + blit->xwrite*4; shift = blit->xread & 7; y = blit->height; do { unsigned char* _read = read; unsigned char* _write = write; unsigned long val = ( *_read++ | 0x100L ) << shift; x = blit->width; do { if ( val & 0x10000 ) val = *_read++ | 0x100L; if ( val & 0x80 ) { /* this could be greatly optimized as */ /* */ /* *(long*)_write = color.value */ /* */ /* but it wouldn't work on 64-bits systems... stupid C types! */ _write[0] = color.chroma[0]; _write[1] = color.chroma[1]; _write[2] = color.chroma[2]; _write[3] = color.chroma[3]; } val <<= 1; _write += 4; x--; } while ( x > 0 ); read += blit->read_line; write += blit->write_line; y--; } while ( y > 0 ); } static const grBlitterFunc gr_mono_blitters[gr_pixel_mode_max] = { 0, blit_mono_to_mono, blit_mono_to_pal4, blit_mono_to_pal8, blit_mono_to_pal8, blit_mono_to_rgb16, blit_mono_to_rgb16, blit_mono_to_rgb24, blit_mono_to_rgb32 }; /*******************************************************************/ /* */ /* Saturation tables */ /* */ /*******************************************************************/ typedef struct grSaturation_ { int count; const byte* table; } grSaturation; static
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -