📄 ftstring.c
字号:
num_glyphs = expect = 0;
while ( *p )
{
in_code = *p++ ;
if ( in_code >= 0xC0 )
{
if ( in_code < 0xE0 ) /* U+0080 - U+07FF */
{
expect = 1;
codepoint = in_code & 0x1F;
}
else if ( in_code < 0xF0 ) /* U+0800 - U+FFFF */
{
expect = 2;
codepoint = in_code & 0x0F;
}
else if ( in_code < 0xF8 ) /* U+10000 - U+10FFFF */
{
expect = 3;
codepoint = in_code & 0x07;
}
continue;
}
else if ( in_code >= 0x80 )
{
--expect;
if ( expect >= 0 )
{
codepoint <<= 6;
codepoint += in_code & 0x3F;
}
if ( expect > 0 )
continue;
expect = 0;
}
else /* ASCII, U+0000 - U+007F */
codepoint = in_code;
if ( encoding )
glyph_index = FT_Get_Char_Index( face, codepoint );
else
glyph_index = codepoint;
glyph->glyph_index = glyph_index;
glyph++;
num_glyphs++;
if ( num_glyphs >= MAX_GLYPHS )
break;
}
}
static void
reset_transform( void )
{
double angle = Rotation * 3.14159 / 64.0;
FT_Fixed cosinus = (FT_Fixed)( cos( angle ) * 65536.0 );
FT_Fixed sinus = (FT_Fixed)( sin( angle ) * 65536.0 );
transform = ( angle != 0 );
trans_matrix.xx = cosinus;
trans_matrix.yx = sinus;
trans_matrix.xy = -sinus;
trans_matrix.yy = cosinus;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**** ****/
/**** E V E N T H A N D L I N G ****/
/**** ****/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static void
Help( void )
{
grEvent dummy_event;
clear_display();
grGotoxy( 0, 0 );
grSetMargin( 2, 1 );
grGotobitmap( &bit );
grWriteln("FreeType String Viewer - part of the FreeType test suite" );
grLn();
grWriteln("This program is used to display a string of text using" );
grWriteln("the new convenience API of the FreeType 2 library.");
grLn();
grWriteln("Use the following keys :");
grLn();
grWriteln(" F1 or ? : display this help screen" );
grWriteln(" a : toggle anti-aliasing" );
grWriteln(" f : toggle forced auto-hinting" );
grWriteln(" h : toggle outline hinting" );
grWriteln(" k : toggle kerning" );
grWriteln(" g : toggle gamma correction" );
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 : rotate counter-clockwise" );
grWriteln(" Left : rotate clockwise" );
grWriteln(" F7 : big rotate counter-clockwise");
grWriteln(" F8 : big rotate clockwise");
grLn();
grWriteln(" F9 : decrease gamma by 0.1" );
grWriteln(" F10 : increase gamma by 0.1" );
grLn();
grWriteln("press any key to exit this help screen");
grRefreshSurface( surface );
grListenSurface( surface, gr_event_key, &dummy_event );
}
static int
Process_Event( grEvent* event )
{
int i;
switch ( event->key )
{
case grKeyEsc: /* ESC or q */
case grKEY( 'q' ):
return 0;
case grKEY( 'f' ):
autohint = !autohint;
new_header = autohint ? (char *)"forced auto-hinting is now on"
: (char *)"forced auto-hinting is now off";
return 1;
case grKEY( 'k' ):
kerning = ( kerning + 1 ) % 3;
new_header =
kerning == 2
? (char *)"kerning and side bearing correction is now active"
: kerning == 1 ? (char *)"kerning is now active"
: (char *)"kerning is now ignored";
return 1;
case grKEY( 'a' ):
antialias = !antialias;
new_header = antialias ? (char *)"anti-aliasing is now on"
: (char *)"anti-aliasing is now off";
return 1;
case grKEY( 'b' ):
#if 0
use_sbits = !use_sbits;
new_header = use_sbits
? (char *)"embedded bitmaps are now used when available"
: (char *)"embedded bitmaps are now ignored";
#else
new_header = (char *)"embedded bitmaps can't be rotated/transformed";
#endif
return 1;
case grKEY( 'n' ):
case grKEY( 'p' ):
return (int)event->key;
case grKEY( 'h' ):
hinted = !hinted;
new_header = hinted ? (char *)"glyph hinting is now active"
: (char *)"glyph hinting is now ignored";
break;
case grKEY( 'g' ):
use_gamma = !use_gamma;
new_header = use_gamma ? (char *)"gamma correction is now on"
: (char *)"gamma correction is now off";
return 1;
case grKeyF1:
case grKEY( '?' ):
Help();
return 1;
#if 0
case grKeyF3: i = 16; goto Do_Rotate;
case grKeyF4: i = -16; goto Do_Rotate;
case grKeyF5: i = 1; goto Do_Rotate;
case grKeyF6: i = -1; goto Do_Rotate;
#endif
case grKeyPageUp: i = 10; goto Do_Scale;
case grKeyPageDown: i = -10; goto Do_Scale;
case grKeyUp: i = 1; goto Do_Scale;
case grKeyDown: i = -1; goto Do_Scale;
case grKeyLeft: i = -1; goto Do_Rotate;
case grKeyRight: i = 1; goto Do_Rotate;
case grKeyF7: i = -10; goto Do_Rotate;
case grKeyF8: i = 10; goto Do_Rotate;
case grKeyF9 : if (gamma_value > 0.1f) gamma_value -= 0.1f; goto Do_Gamma_Set;
case grKeyF10: gamma_value += 0.1f; goto Do_Gamma_Set;
default:
;
}
return 1;
Do_Rotate:
Rotation = ( Rotation + i ) & 127;
return 1;
Do_Gamma_Set:
{
static char header_buffer[64];
sprintf(header_buffer, "gamma is %.1f", gamma_value);
new_header = header_buffer;
init_gamma();
return 1;
}
Do_Scale:
ptsize += i;
if ( ptsize < 1 ) ptsize = 1;
if ( ptsize > MAXPTSIZE ) ptsize = MAXPTSIZE;
return 1;
#if 0
Do_Glyph:
Num += i;
if ( Num < 0 ) Num = 0;
if ( Num >= num_glyphs ) Num = num_glyphs - 1;
return 1;
#endif
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**** ****/
/**** M A I N P R O G R A M ****/
/**** ****/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static void
usage( char* execname )
{
fprintf( stderr, "\n" );
fprintf( stderr, "ftstring: string viewer -- part of the FreeType project\n" );
fprintf( stderr, "-------------------------------------------------------\n" );
fprintf( stderr, "\n" );
fprintf( stderr, "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n",
execname );
fprintf( stderr, "\n" );
fprintf( stderr, " -e enc specify encoding tag (default: unic)\n" );
fprintf( stderr, " -r R use resolution R dpi (default: 72 dpi)\n" );
fprintf( stderr, " -m message message to display\n" );
fprintf( stderr, "\n" );
exit( 1 );
}
int
main( int argc,
char** argv )
{
int i, old_ptsize, orig_ptsize, file;
int first_glyph = 0;
int XisSetup = 0;
char filename[128 + 4];
char alt_filename[128 + 4];
char* execname;
int option;
int file_loaded;
PGlyph glyph;
grEvent event;
execname = ft_basename( argv[0] );
while ( 1 )
{
option = getopt( argc, argv, "e:m:r:" );
if ( option == -1 )
break;
switch ( option )
{
case 'e':
encoding = (FT_Encoding)make_tag( optarg );
break;
case 'r':
res = atoi( optarg );
if ( res < 1 )
usage( execname );
break;
case 'm':
if ( argc < 3 )
usage( execname );
Text = optarg;
break;
default:
usage( execname );
break;
}
}
argc -= optind;
argv += optind;
if ( argc <= 1 )
usage( execname );
if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )
orig_ptsize = 64;
file = 1;
/* Initialize engine */
error = FT_Init_FreeType( &library );
if ( error )
PanicZ( "Could not initialize FreeType library" );
NewFile:
ptsize = orig_ptsize;
hinted = 1;
file_loaded = 0;
#ifndef macintosh
i = strlen( argv[file] );
while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
{
if ( argv[file][i] == '.' )
i = 0;
i--;
}
#endif
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, argv[file], 128 );
strncpy( alt_filename, argv[file], 128 );
/* first, try to load the glyph name as-is */
error = FT_New_Face( library, filename, 0, &face );
if ( !error )
goto Success;
#ifndef macintosh
if ( i >= 0 )
{
strncpy( filename + strlen( filename ), ".ttf", 4 );
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
}
#endif
/* if it didn't work, try to add ".ttf" at the end */
error = FT_New_Face( library, filename, 0, &face );
if ( error )
goto Display_Font;
Success:
init_gamma();
/* prepare the text to be rendered */
prepare_text( (unsigned char*)Text );
file_loaded++;
reset_scale( ptsize );
Display_Font:
/* initialise graphics if needed */
if ( !XisSetup )
{
XisSetup = 1;
init_display();
}
grSetTitle( surface, "FreeType String Viewer - press F1 for help" );
old_ptsize = ptsize;
if ( file_loaded >= 1 )
{
Fail = 0;
Num = first_glyph;
if ( Num >= num_glyphs )
Num = num_glyphs - 1;
if ( Num < 0 )
Num = 0;
}
for ( ;; )
{
int key;
clear_display();
if ( file_loaded >= 1 )
{
/* layout & render string */
{
reset_transform();
layout_glyphs();
if (use_gamma)
draw_gamma_ramp();
render_string( bit.width/2, bit.rows/2 );
}
sprintf( Header, "%s %s (file %s)",
face->family_name,
face->style_name,
ft_basename( filename ) );
if (!new_header)
new_header = Header;
grWriteCellString( &bit, 0, 0, new_header, fore_color );
new_header = 0;
sprintf( Header, "at %d points, rotation = %d",
ptsize,
Rotation );
}
else
{
sprintf( Header, "`%s' is not a font file or could not be opened",
ft_basename(filename) );
}
grWriteCellString( &bit, 0, 8, Header, fore_color );
grRefreshSurface( surface );
grListenSurface( surface, 0, &event );
if ( !( key = Process_Event( &event ) ) )
goto Fin;
if ( key == 'n' )
{
if ( file_loaded >= 1 )
FT_Done_Face( face );
if ( file < argc - 1 )
file++;
goto NewFile;
}
if ( key == 'p' )
{
if ( file_loaded >= 1 )
FT_Done_Face( face );
if ( file > 1 )
file--;
goto NewFile;
}
if ( ptsize != old_ptsize )
{
reset_scale( ptsize );
old_ptsize = ptsize;
}
}
Fin:
glyph = glyphs;
for ( i = 0; i < MAX_GLYPHS; i++, glyph++ )
if ( glyph->image )
FT_Done_Glyph( glyph->image );
FT_Done_Face ( face );
FT_Done_FreeType( library );
#if 0
grDoneSurface( surface );
grDone();
#endif
printf( "Execution completed successfully.\n" );
printf( "Fails = %d\n", Fail );
exit( 0 ); /* for safety reasons */
return 0; /* never reached */
}
/* End */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -