📄 ftcommon.c
字号:
case FT_ENCODING_ADOBE_CUSTOM:
case FT_ENCODING_APPLE_ROMAN:
font->num_indices = 0x100L;
break;
default:
font->num_indices = 0x10000L;
}
FT_Done_Face( face );
face = NULL;
if ( handle->max_fonts == 0 )
{
handle->max_fonts = 16;
handle->fonts = (PFont*)calloc( handle->max_fonts,
sizeof ( PFont ) );
}
else if ( handle->num_fonts >= handle->max_fonts )
{
handle->max_fonts *= 2;
handle->fonts = (PFont*)realloc( handle->fonts,
handle->max_fonts *
sizeof ( PFont ) );
memset( &handle->fonts[handle->num_fonts], 0,
( handle->max_fonts - handle->num_fonts ) *
sizeof ( PFont ) );
}
handle->fonts[handle->num_fonts++] = font;
}
return FT_Err_Ok;
}
void
FTDemo_Set_Current_Font( FTDemo_Handle* handle,
PFont font )
{
handle->current_font = font;
handle->image_type.face_id = (FTC_FaceID)font;
handle->string_reload = 1;
}
void
FTDemo_Set_Current_Size( FTDemo_Handle* handle,
int pixel_size )
{
if ( pixel_size > 0xFFFF )
pixel_size = 0xFFFF;
handle->image_type.width = (FT_UShort)pixel_size;
handle->image_type.height = (FT_UShort)pixel_size;
handle->string_reload = 1;
}
void
FTDemo_Set_Preload( FTDemo_Handle* handle,
int preload )
{
handle->preload = !!preload;
}
void
FTDemo_Set_Current_Pointsize( FTDemo_Handle* handle,
int point_size,
int res )
{
FTDemo_Set_Current_Size( handle, ( point_size * res + 36 ) / 72 );
}
void
FTDemo_Update_Current_Flags( FTDemo_Handle* handle )
{
FT_UInt32 flags, target;
flags = FT_LOAD_DEFAULT; /* really 0 */
flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
if ( handle->autohint )
flags |= FT_LOAD_FORCE_AUTOHINT;
if ( !handle->use_sbits )
flags |= FT_LOAD_NO_BITMAP;
if ( handle->hinted )
{
target = 0;
if ( handle->antialias )
{
switch ( handle->lcd_mode )
{
case LCD_MODE_LIGHT:
target = FT_LOAD_TARGET_LIGHT;
break;
case LCD_MODE_RGB:
case LCD_MODE_BGR:
target = FT_LOAD_TARGET_LCD;
break;
case LCD_MODE_VRGB:
case LCD_MODE_VBGR:
target = FT_LOAD_TARGET_LCD_V;
break;
default:
target = FT_LOAD_TARGET_NORMAL;
}
}
else
target = FT_LOAD_TARGET_MONO;
flags |= target;
}
else
flags |= FT_LOAD_NO_HINTING;
handle->image_type.flags = flags;
handle->string_reload = 1;
}
FT_UInt
FTDemo_Get_Index( FTDemo_Handle* handle,
FT_UInt32 charcode )
{
FTC_FaceID face_id = handle->image_type.face_id;
PFont font = handle->current_font;
return FTC_CMapCache_Lookup( handle->cmap_cache, face_id,
font->cmap_index, charcode );
}
FT_Error
FTDemo_Get_Size( FTDemo_Handle* handle,
FT_Size* asize )
{
FTC_ScalerRec scaler;
FT_Size size;
scaler.face_id = handle->image_type.face_id;
scaler.width = handle->image_type.width;
scaler.height = handle->image_type.height;
scaler.pixel = 1;
error = FTC_Manager_LookupSize( handle->cache_manager, &scaler, &size );
if ( !error )
*asize = size;
return error;
}
FT_Error
FTDemo_Glyph_To_Bitmap( FTDemo_Handle* handle,
FT_Glyph glyf,
grBitmap* target,
int* left,
int* top,
int* x_advance,
int* y_advance,
FT_Glyph* aglyf )
{
FT_BitmapGlyph bitmap;
FT_Bitmap* source;
*aglyf = NULL;
error = FT_Err_Ok;
if ( glyf->format == FT_GLYPH_FORMAT_OUTLINE )
{
FT_Render_Mode render_mode = FT_RENDER_MODE_MONO;
if ( handle->antialias )
{
if ( handle->lcd_mode == 0 )
render_mode = FT_RENDER_MODE_NORMAL;
else if ( handle->lcd_mode == 1 )
render_mode = FT_RENDER_MODE_LIGHT;
else if ( handle->lcd_mode <= 3 )
render_mode = FT_RENDER_MODE_LCD;
else
render_mode = FT_RENDER_MODE_LCD_V;
}
/* render the glyph to a bitmap, don't destroy original */
error = FT_Glyph_To_Bitmap( &glyf, render_mode, NULL, 0 );
if ( error )
return error;
*aglyf = glyf;
}
if ( glyf->format != FT_GLYPH_FORMAT_BITMAP )
PanicZ( "invalid glyph format returned!" );
bitmap = (FT_BitmapGlyph)glyf;
source = &bitmap->bitmap;
target->rows = source->rows;
target->width = source->width;
target->pitch = source->pitch;
target->buffer = source->buffer;
target->grays = source->num_grays;
switch ( source->pixel_mode )
{
case FT_PIXEL_MODE_MONO:
target->mode = gr_pixel_mode_mono;
break;
case FT_PIXEL_MODE_GRAY:
target->mode = gr_pixel_mode_gray;
target->grays = source->num_grays;
break;
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
(void)FT_Bitmap_Convert( handle->library, source, &handle->bitmap, 1 );
target->pitch = handle->bitmap.pitch;
target->buffer = handle->bitmap.buffer;
target->mode = gr_pixel_mode_gray;
target->grays = handle->bitmap.num_grays;
break;
case FT_PIXEL_MODE_LCD:
target->mode = handle->lcd_mode == 2 ? gr_pixel_mode_lcd
: gr_pixel_mode_lcd2;
target->grays = source->num_grays;
break;
case FT_PIXEL_MODE_LCD_V:
target->mode = handle->lcd_mode == 4 ? gr_pixel_mode_lcdv
: gr_pixel_mode_lcdv2;
target->grays = source->num_grays;
break;
default:
return FT_Err_Invalid_Glyph_Format;
}
*left = bitmap->left;
*top = bitmap->top;
*x_advance = ( glyf->advance.x + 0x8000 ) >> 16;
*y_advance = ( glyf->advance.y + 0x8000 ) >> 16;
return error;
}
FT_Error
FTDemo_Index_To_Bitmap( FTDemo_Handle* handle,
FT_ULong Index,
grBitmap* target,
int* left,
int* top,
int* x_advance,
int* y_advance,
FT_Glyph* aglyf )
{
int cached_bitmap = 1;
*aglyf = NULL;
/* use the SBits cache to store small glyph bitmaps; this is a lot */
/* more memory-efficient */
/* */
if ( handle->use_sbits_cache &&
handle->image_type.width < 48 &&
handle->image_type.height < 48 )
{
FTC_SBit sbit;
FT_Bitmap source;
error = FTC_SBitCache_Lookup( handle->sbits_cache,
&handle->image_type,
Index,
&sbit,
NULL );
if ( error )
goto Exit;
if ( sbit->buffer )
{
target->rows = sbit->height;
target->width = sbit->width;
target->pitch = sbit->pitch;
target->buffer = sbit->buffer;
target->grays = sbit->max_grays + 1;
switch ( sbit->format )
{
case FT_PIXEL_MODE_MONO:
target->mode = gr_pixel_mode_mono;
break;
case FT_PIXEL_MODE_GRAY:
target->mode = gr_pixel_mode_gray;
target->grays = sbit->max_grays + 1;
break;
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
source.rows = sbit->height;
source.width = sbit->width;
source.pitch = sbit->pitch;
source.buffer = sbit->buffer;
source.pixel_mode = sbit->format;
(void)FT_Bitmap_Convert( handle->library, &source,
&handle->bitmap, 1 );
target->pitch = handle->bitmap.pitch;
target->buffer = handle->bitmap.buffer;
target->mode = gr_pixel_mode_gray;
target->grays = handle->bitmap.num_grays;
cached_bitmap = 0;
break;
case FT_PIXEL_MODE_LCD:
target->mode = handle->lcd_mode == 2 ? gr_pixel_mode_lcd
: gr_pixel_mode_lcd2;
target->grays = sbit->max_grays + 1;
break;
case FT_PIXEL_MODE_LCD_V:
target->mode = handle->lcd_mode == 4 ? gr_pixel_mode_lcdv
: gr_pixel_mode_lcdv2;
target->grays = sbit->max_grays + 1;
break;
default:
return FT_Err_Invalid_Glyph_Format;
}
*left = sbit->left;
*top = sbit->top;
*x_advance = sbit->xadvance;
*y_advance = sbit->yadvance;
goto Exit;
}
}
/* otherwise, use an image cache to store glyph outlines, and render */
/* them on demand. we can thus support very large sizes easily.. */
{
FT_Glyph glyf;
error = FTC_ImageCache_Lookup( handle->image_cache,
&handle->image_type,
Index,
&glyf,
NULL );
if ( !error )
error = FTDemo_Glyph_To_Bitmap( handle, glyf, target, left, top,
x_advance, y_advance, aglyf );
}
Exit:
#ifdef FT_RGB_FILTER_H
/* note that we apply the RGB filter to each cached glyph, which is
* a performance killer, but that's better than modifying the cache
* at the moment
*/
if ( !error )
{
if ( target->mode == gr_pixel_mode_lcd ||
target->mode == gr_pixel_mode_lcdv )
{
/* copy the bitmap before filtering it, we don't want to touch
* the content of cache nodes at all
*/
{
}
}
}
#endif /* FT_RGB_FILTER_H */
/* don't accept a `missing' character with zero or negative width */
if ( Index == 0 && *x_advance <= 0 )
*x_advance = 1;
return error;
}
FT_Error
FTDemo_Draw_Index( FTDemo_Handle* handle,
FTDemo_Display* display,
int gindex,
int* pen_x,
int* pen_y )
{
int left, top, x_advance, y_advance;
grBitmap bit3;
FT_Glyph glyf;
error = FTDemo_Index_To_Bitmap( handle, gindex, &bit3, &left, &top,
&x_advance, &y_advance, &glyf );
if ( error )
return error;
/* now render the bitmap into the display surface */
grBlitGlyphToBitmap( display->bitmap, &bit3, *pen_x + left,
*pen_y - top, display->fore_color );
if ( glyf )
FT_Done_Glyph( glyf );
*pen_x += x_advance + 1;
return FT_Err_Ok;
}
FT_Error
FTDemo_Draw_Glyph( FTDemo_Handle* handle,
FTDemo_Display* display,
FT_Glyph glyph,
int* pen_x,
int* pen_y )
{
int left, top, x_advance, y_advance;
grBitmap bit3;
FT_Glyph glyf;
error = FTDemo_Glyph_To_Bitmap( handle, glyph, &bit3, &left, &top,
&x_advance, &y_advance, &glyf );
if ( error )
{
FT_Done_Glyph( glyph );
return error;
}
/* now render the bitmap into the display surface */
grBlitGlyphToBitmap( display->bitmap, &bit3, *pen_x + left,
*pen_y - top, display->fore_color );
if ( glyf )
FT_Done_Glyph( glyf );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -