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