📄 ftview.c
字号:
if ( !FT_IS_SCALABLE( face ) )
{
int i;
max_size = 0;
for ( i = 0; i < face->num_fixed_sizes; i++ )
if ( face->available_sizes[i].height >= max_size )
max_size = face->available_sizes[i].height;
}
}
start_x = 4;
start_y = 2 * HEADER_HEIGHT;
for ( pt_size = first_size; pt_size < max_size; pt_size++ )
{
sprintf( (char*)text,
"%d: the quick brown fox jumps over the lazy dog "
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pt_size );
p = text;
FTDemo_Set_Current_Pointsize( handle, pt_size, status.res );
error = FTDemo_Get_Size( handle, &size );
if ( error )
{
/* probably a non-existent bitmap font size */
continue;
}
step_x = ( size->metrics.max_advance >> 6 ) + 4;
step_y = ( size->metrics.height >> 6 ) + 1;
x = start_x;
y = start_y + ( size->metrics.ascender >> 6 );
start_y += step_y;
if ( y >= display->bitmap->rows )
break;
while ( *p )
{
FT_UInt gindex;
gindex = FTDemo_Get_Index( handle, *p );
error = FTDemo_Draw_Index( handle, display, gindex, &x, &y );
if ( error )
status.Fail++;
else if ( X_TOO_LONG( x, size, display ) )
break;
p++;
}
}
FTDemo_Set_Current_Pointsize( handle, first_size, status.res );
return FT_Err_Ok;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** REST OF THE APPLICATION/PROGRAM *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static void
event_help( void )
{
grEvent dummy_event;
FTDemo_Display_Clear( display );
grGotoxy( 0, 0 );
grSetMargin( 2, 1 );
grGotobitmap( display->bitmap );
grWriteln( "FreeType Glyph Viewer - part of the FreeType test suite" );
grLn();
grWriteln( "This program is used to display all glyphs from one or" );
grWriteln( "several font files, with the FreeType library." );
grLn();
grWriteln( "Use the following keys:" );
grLn();
grWriteln( " F1 or ? : display this help screen" );
grLn();
grWriteln( " a : toggle anti-aliasing" );
grWriteln( " b : toggle embedded bitmaps" );
grWriteln( " c : toggle between cache modes" );
grWriteln( " f : toggle forced auto-hinting" );
grWriteln( " h : toggle outline hinting" );
grWriteln( " l : toggle low precision rendering" );
grLn();
grWriteln( " L : cycle through LCD modes" );
grWriteln( " space : toggle rendering mode" );
grWriteln( " 1-5 : select rendering mode" );
grLn();
grWriteln( " G : show gamma ramp" );
grWriteln( " g : increase gamma by 0.1" );
grWriteln( " v : decrease gamma by 0.1" );
grLn();
grWriteln( " n : next font" );
grWriteln( " p : previous font" );
grLn();
grWriteln( " Up : increase pointsize by 1 unit" );
grWriteln( " Down : decrease pointsize by 1 unit" );
grWriteln( " Page Up : increase pointsize by 10 units" );
grWriteln( " Page Down : decrease pointsize by 10 units" );
grLn();
grWriteln( " Right : increment index" );
grWriteln( " Left : decrement index" );
grLn();
grWriteln( " F7 : decrement index by 10" );
grWriteln( " F8 : increment index by 10" );
grWriteln( " F9 : decrement index by 100" );
grWriteln( " F10 : increment index by 100" );
grWriteln( " F11 : decrement index by 1000" );
grWriteln( " F12 : increment index by 1000" );
grLn();
grWriteln( "press any key to exit this help screen" );
grRefreshSurface( display->surface );
grListenSurface( display->surface, gr_event_key, &dummy_event );
}
static void
event_gamma_grid( void )
{
grEvent dummy_event;
int g;
int yside = 11;
int xside = 10;
int levels = 17;
int gammas = 30;
int x_0 = (display->bitmap->width - levels*xside)/2;
int y_0 = (display->bitmap->rows - gammas*(yside+1))/2;
int pitch = display->bitmap->pitch;
FTDemo_Display_Clear( display );
grGotobitmap( display->bitmap );
if ( pitch < 0 )
pitch = -pitch;
memset( display->bitmap->buffer, 100, pitch*display->bitmap->rows );
grWriteCellString( display->bitmap, 0, 0, "Gamma grid", display->fore_color );
for ( g = 1; g <= gammas; g += 1 )
{
double ggamma = g / 10.0;
char temp[6];
int y = y_0 + ( yside + 1 ) * ( g - 1 );
int nx, ny;
unsigned char* line = display->bitmap->buffer + y * display->bitmap->pitch;
if ( display->bitmap->pitch < 0 )
line -= display->bitmap->pitch * ( display->bitmap->rows - 1 );
line += x_0 * 3;
grSetPixelMargin( x_0 - 32, y + ( yside - 8 ) / 2 );
grGotoxy( 0, 0 );
sprintf( temp, "%.1f", ggamma );
grWrite( temp );
for ( ny = 0; ny < yside; ny++, line += display->bitmap->pitch )
{
unsigned char* dst = line;
for ( nx = 0; nx < levels; nx++, dst += 3 * xside )
{
double p = nx/(double)(levels - 1);
int gm = (int)( 255.0 * pow( p, ggamma ) );
memset( dst, gm, xside * 3 );
}
}
}
grRefreshSurface( display->surface );
grListenSurface( display->surface, gr_event_key, &dummy_event );
}
static void
event_gamma_change( double delta )
{
status.gamma += delta;
if ( status.gamma > 3.0 )
status.gamma = 3.0;
else if ( status.gamma < 0.0 )
status.gamma = 0.0;
grSetGlyphGamma( status.gamma );
sprintf( status.header_buffer, "gamma changed to %.1f%s",
status.gamma, status.gamma == 0.0 ? " (sRGB mode)" : "" );
status.header = status.header_buffer;
}
static void
event_size_change( int delta )
{
status.ptsize += delta;
if ( status.ptsize < 1 )
status.ptsize = 1;
else if ( status.ptsize > MAXPTSIZE )
status.ptsize = MAXPTSIZE;
FTDemo_Set_Current_Pointsize( handle, status.ptsize, status.res );
}
static void
event_index_change( int delta )
{
int num_indices = handle->current_font->num_indices;
status.Num += delta;
if ( status.Num < 0 )
status.Num = 0;
else if ( status.Num >= num_indices )
status.Num = num_indices - 1;
}
static void
event_render_mode_change( int delta )
{
if ( delta )
{
status.render_mode = ( status.render_mode + delta ) % N_RENDER_MODES;
if ( status.render_mode < 0 )
status.render_mode += N_RENDER_MODES;
}
switch ( status.render_mode )
{
case RENDER_MODE_ALL:
status.header = (char *)"rendering all glyphs in font";
break;
case RENDER_MODE_EMBOLDEN:
status.header = (char *)"rendering emboldened text";
break;
case RENDER_MODE_STROKE:
status.header = (char *)"rendering stroked text";
break;
case RENDER_MODE_TEXT:
status.header = (char *)"rendering test text string";
break;
case RENDER_MODE_WATERFALL:
status.header = (char *)"rendering glyph waterfall";
break;
}
}
static void
event_font_change( int delta )
{
int num_indices;
if ( status.font_index + delta >= handle->num_fonts ||
status.font_index + delta < 0 )
return;
status.font_index += delta;
FTDemo_Set_Current_Font( handle, handle->fonts[status.font_index] );
FTDemo_Set_Current_Pointsize( handle, status.ptsize, status.res );
FTDemo_Update_Current_Flags( handle );
num_indices = handle->current_font->num_indices;
if ( status.Num >= num_indices )
status.Num = num_indices - 1;
}
static int
Process_Event( grEvent* event )
{
int ret = 0;
if ( event->key >= '1' && event->key < '1' + N_RENDER_MODES )
{
status.render_mode = event->key - '1';
event_render_mode_change( 0 );
return ret;
}
switch ( event->key )
{
case grKeyEsc:
case grKEY( 'q' ):
ret = 1;
break;
case grKeyF1:
case grKEY( '?' ):
event_help();
break;
case grKEY( 'a' ):
handle->antialias = !handle->antialias;
status.header = handle->antialias
? (char *)"anti-aliasing is now on"
: (char *)"anti-aliasing is now off";
FTDemo_Update_Current_Flags( handle );
break;
case grKEY( 'b' ):
handle->use_sbits = !handle->use_sbits;
status.header = handle->use_sbits
? (char *)"embedded bitmaps are now used when available"
: (char *)"embedded bitmaps are now ignored";
FTDemo_Update_Current_Flags( handle );
break;
case grKEY( 'c' ):
handle->use_sbits_cache = !handle->use_sbits_cache;
status.header = handle->use_sbits_cache
? (char *)"now using sbits cache"
: (char *)"now using normal cache";
break;
case grKEY( 'f' ):
handle->autohint = !handle->autohint;
status.header = handle->autohint
? (char *)"forced auto-hinting is now on"
: (char *)"forced auto-hinting is now off";
FTDemo_Update_Current_Flags( handle );
break;
case grKEY( 'h' ):
handle->hinted = !handle->hinted;
status.header = handle->hinted
? (char *)"glyph hinting is now active"
: (char *)"glyph hinting is now ignored";
FTDemo_Update_Current_Flags( handle );
break;
case grKEY( 'l' ):
handle->low_prec = !handle->low_prec;
status.header = handle->low_prec
? (char *)"rendering precision is now forced to low"
: (char *)"rendering precision is now normal";
FTDemo_Update_Current_Flags( handle );
break;
case grKEY( 'L' ):
handle->lcd_mode = ( handle->lcd_mode + 1 ) % N_LCD_MODES;
switch ( handle->lcd_mode )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -