📄 grblit.c
字号:
}
while (y > 0);
}
#endif /* GRAY8 */
static void
blit_lcd2_to_24( grBlitter* blit,
grColor color,
int max )
{
int y;
unsigned char* read;
unsigned char* write;
read = blit->read + 3*blit->xread;
write = blit->write + 3*blit->xwrite;
y = blit->height;
do
{
unsigned char* _read = read;
unsigned char* _write = write;
int x = blit->width;
while (x > 0)
{
int val0, val1, val2;
val0 = _read[2];
val1 = _read[1];
val2 = _read[0];
if ( val0 | val1 | val2 )
{
if ( val0 == val1 &&
val0 == val2 &&
val0 == max )
{
_write[0] = color.chroma[0];
_write[1] = color.chroma[1];
_write[2] = color.chroma[2];
}
else
{
/* compose gray value */
grColor pix;
pix.chroma[0] = _write[0];
pix.chroma[1] = _write[1];
pix.chroma[2] = _write[2];
compose_pixel_full( pix, color, val0, val1, val2, max );
_write[0] = pix.chroma[0];
_write[1] = pix.chroma[1];
_write[2] = pix.chroma[2];
}
}
_write += 3;
_read += 3;
x--;
}
read += blit->read_line;
write += blit->write_line;
y--;
}
while (y > 0);
}
/**************************************************************************/
/* */
/* <Function> blit_lcdv_to_24 */
/* */
/**************************************************************************/
static void
blit_lcdv_to_24( grBlitter* blit,
grColor color,
int max )
{
int y;
unsigned char* read;
unsigned char* write;
long line;
read = blit->read + blit->xread;
write = blit->write + 3*blit->xwrite;
line = blit->read_line;
y = blit->height;
do
{
unsigned char* _read = read;
unsigned char* _write = write;
int x = blit->width;
while (x > 0)
{
unsigned char val0, val1, val2;
val0 = _read[0*line];
val1 = _read[1*line];
val2 = _read[2*line];
if ( val0 | val1 | val2 )
{
if ( val0 == val1 &&
val0 == val2 &&
val0 == max )
{
_write[0] = color.chroma[0];
_write[1] = color.chroma[1];
_write[2] = color.chroma[2];
}
else
{
/* compose gray value */
grColor pix;
pix.chroma[0] = _write[0];
pix.chroma[1] = _write[1];
pix.chroma[2] = _write[2];
compose_pixel_full( pix, color, val0, val1, val2, max );
_write[0] = pix.chroma[0];
_write[1] = pix.chroma[1];
_write[2] = pix.chroma[2];
}
}
_write += 3;
_read += 1;
x--;
}
read += 3*line;
write += blit->write_line;
y--;
}
while (y > 0);
}
static void
blit_lcdv2_to_24( grBlitter* blit,
grColor color,
int max )
{
int y;
unsigned char* read;
unsigned char* write;
long line;
read = blit->read + blit->xread;
write = blit->write + 3*blit->xwrite;
line = blit->read_line;
y = blit->height;
do
{
unsigned char* _read = read;
unsigned char* _write = write;
int x = blit->width;
while (x > 0)
{
unsigned char val0, val1, val2;
val0 = _read[2*line];
val1 = _read[1*line];
val2 = _read[0*line];
if ( val0 | val1 | val2 )
{
if ( val0 == val1 &&
val0 == val2 &&
val0 == max )
{
_write[0] = color.chroma[0];
_write[1] = color.chroma[1];
_write[2] = color.chroma[2];
}
else
{
/* compose gray value */
grColor pix;
pix.chroma[0] = _write[0];
pix.chroma[1] = _write[1];
pix.chroma[2] = _write[2];
compose_pixel_full( pix, color, val0, val1, val2, max );
_write[0] = pix.chroma[0];
_write[1] = pix.chroma[1];
_write[2] = pix.chroma[2];
}
}
_write += 3;
_read += 1;
x--;
}
read += 3*line;
write += blit->write_line;
y--;
}
while (y > 0);
}
/**********************************************************************
*
* <Function>
* grBlitGlyphBitmap
*
* <Description>
* writes a given glyph bitmap to a target surface.
*
* <Input>
* surface :: handle to target surface
* x :: position of left-most pixel of glyph image in surface
* y :: position of top-most pixel of glyph image in surface
* bitmap :: source glyph image
*
* <Return>
* Error code. 0 means success
*
**********************************************************************/
typedef void (*grColorGlyphBlitter)( grBlitter* blit,
grColor color,
int max_gray );
static
const grColorGlyphBlitter gr_color_blitters[gr_pixel_mode_max] =
{
0,
0,
0,
0,
0,
blit_gray_to_555,
blit_gray_to_565,
blit_gray_to_24,
blit_gray_to_32
};
#ifdef GRAY8
typedef void (*grGray8GlyphBlitter)( grBlitter* blit,
grColor color );
static
const grGray8GlyphBlitter gr_gray8_blitters[gr_pixel_mode_max] =
{
0,
0,
0,
0,
0,
blit_gray8_to_555,
blit_gray8_to_565,
blit_gray8_to_24,
blit_gray8_to_32
};
#endif
#include "gblblit.h"
static double gr_glyph_gamma = 1.2;
void grSetGlyphGamma( double gamma )
{
gr_glyph_gamma = gamma;
}
int
grBlitGlyphToBitmap( grBitmap* target,
grBitmap* glyph,
grPos x,
grPos y,
grColor color )
{
grBlitter blit;
grPixelMode mode;
/* check arguments */
if ( !target || !glyph )
{
grError = gr_err_bad_argument;
return -1;
}
/* short cut to alpha blender for certain glyph types
*/
{
GBlenderSourceFormat src_format;
GBlenderTargetFormat dst_format;
int width, height;
GBlenderBlitRec gblit[1];
GBlenderPixel gcolor;
static GBlenderRec gblender[1];
static double gblender_gamma = -100.0;
if ( glyph->grays != 256 )
goto DefaultBlit;
switch ( glyph->mode )
{
case gr_pixel_mode_gray: src_format = GBLENDER_SOURCE_GRAY8; break;
case gr_pixel_mode_lcd: src_format = GBLENDER_SOURCE_HRGB; break;
case gr_pixel_mode_lcdv: src_format = GBLENDER_SOURCE_VRGB; break;
case gr_pixel_mode_lcd2: src_format = GBLENDER_SOURCE_HBGR; break;
case gr_pixel_mode_lcdv2: src_format = GBLENDER_SOURCE_VBGR; break;
default:
goto DefaultBlit;
}
width = glyph->width;
height = glyph->rows;
if ( glyph->mode == gr_pixel_mode_lcd ||
glyph->mode == gr_pixel_mode_lcd2 )
width /= 3;
if ( glyph->mode == gr_pixel_mode_lcdv ||
glyph->mode == gr_pixel_mode_lcdv2 )
height /= 3;
switch ( target->mode )
{
case gr_pixel_mode_rgb32: dst_format = GBLENDER_TARGET_RGB32; break;
case gr_pixel_mode_rgb24: dst_format = GBLENDER_TARGET_RGB24; break;
case gr_pixel_mode_rgb565: dst_format = GBLENDER_TARGET_RGB565; break;
default:
goto DefaultBlit;
}
/* initialize blender when needed, i.e. when gamma changes
*/
if ( gblender_gamma != gr_glyph_gamma )
{
gblender_gamma = gr_glyph_gamma;
gblender_init( gblender, gblender_gamma );
}
if ( gblender_blit_init( gblit, gblender,
x, y,
src_format,
glyph->buffer,
glyph->pitch,
width,
height,
dst_format,
target->buffer,
target->pitch,
target->width,
target->rows ) < 0 )
{
/* nothing to do */
return 0;
}
gcolor = ((GBlenderPixel)color.chroma[0] << 16) |
((GBlenderPixel)color.chroma[1] << 8 ) |
((GBlenderPixel)color.chroma[2] ) ;
gblender_blit_run( gblit, gcolor );
return 1;
}
DefaultBlit:
/* set up blitter and compute clipping. Return immediately if needed */
blit.source = *glyph;
blit.target = *target;
mode = target->mode;
if ( compute_clips( &blit, x, y ) )
return 0;
switch ( glyph->mode )
{
case gr_pixel_mode_mono: /* handle monochrome bitmap blitting */
if ( mode <= gr_pixel_mode_none || mode >= gr_pixel_mode_max )
{
grError = gr_err_bad_source_depth;
return -1;
}
gr_mono_blitters[mode]( &blit, color );
break;
case gr_pixel_mode_gray:
if ( glyph->grays > 1 )
{
int target_grays = target->grays;
int source_grays = glyph->grays;
const byte* saturation;
if ( mode == gr_pixel_mode_gray && target_grays > 1 )
{
/* rendering into a gray target - use special composition */
/* routines.. */
if ( gr_last_saturation->count == target_grays )
saturation = gr_last_saturation->table;
else
{
saturation = grGetSaturation( target_grays );
if ( !saturation )
return -3;
}
if ( target_grays == source_grays )
blit_gray_to_gray_simple( &blit, saturation );
else
{
const byte* conversion;
if ( gr_last_conversion->target_grays == target_grays &&
gr_last_conversion->source_grays == source_grays )
conversion = gr_last_conversion->table;
else
{
conversion = grGetConversion( target_grays, source_grays );
if ( !conversion )
return -3;
}
blit_gray_to_gray( &blit, saturation, conversion );
}
}
else
{
/* rendering into a color target */
if ( mode <= gr_pixel_mode_gray ||
mode >= gr_pixel_mode_max )
{
grError = gr_err_bad_target_depth;
return -1;
}
#ifdef GRAY8
if ( source_grays == 256 )
gr_gray8_blitters[mode]( &blit, color );
else
#endif /* GRAY8 */
gr_color_blitters[mode]( &blit, color, source_grays - 1 );
}
}
break;
case gr_pixel_mode_lcd:
if ( mode == gr_pixel_mode_rgb24 )
{
#ifdef GRAY8
if ( glyph->grays == 256 )
blit_lcd8_to_24( &blit, color );
else
#endif
if ( glyph->grays > 1 )
blit_lcd_to_24( &blit, color, glyph->grays-1 );
}
break;
case gr_pixel_mode_lcdv:
if ( glyph->grays > 1 && mode == gr_pixel_mode_rgb24 )
{
blit_lcdv_to_24( &blit, color, glyph->grays-1 );
break;
}
case gr_pixel_mode_lcd2:
if ( mode == gr_pixel_mode_rgb24 )
{
#ifdef GRAY8
if ( glyph->grays == 256 )
blit_lcd28_to_24( &blit, color );
else
#endif
if ( glyph->grays > 1 )
blit_lcd2_to_24( &blit, color, glyph->grays-1 );
}
break;
case gr_pixel_mode_lcdv2:
if ( mode == gr_pixel_mode_rgb24 )
{
if ( glyph->grays > 1 )
blit_lcdv2_to_24( &blit, color, glyph->grays-1 );
}
break;
default:
/* we don't support the blitting of bitmaps of the following */
/* types : pal4, pal8, rgb555, rgb565, rgb24, rgb32 */
/* */
grError = gr_err_bad_source_depth;
return -2;
}
return 0;
}
/* End */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -