📄 ftview.c
字号:
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-2000, 2003, 2004, 2005 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* */
/* FTView - a simple font viewer. */
/* */
/* This is a new version using the MiGS graphics subsystem for */
/* blitting and display. */
/* */
/* Press F1 when running this program to have a list of key-bindings */
/* */
/****************************************************************************/
#include "ftcommon.i"
#include <math.h>
static FT_Error
Render_GammaGrid( void )
{
int g;
int yside = 11;
int xside = 10;
int levels = 17;
int gammas = 30;
int x_0 = (bit.width - levels*xside)/2;
int y_0 = (bit.rows - gammas*(yside+1))/2;
int pitch = bit.pitch;
if ( pitch < 0 )
pitch = -pitch;
memset( bit.buffer, 100, pitch*bit.rows );
grGotobitmap( &bit );
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 = bit.buffer + y*bit.pitch;
if ( bit.pitch < 0 )
line -= bit.pitch*(bit.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 += bit.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 );
}
}
}
return 0;
}
static FT_Error
Render_Stroke( int first_index )
{
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
FTC_ScalerRec scaler;
FT_Stroker stroker = NULL;
int i;
grBitmap bit3;
start_x = 4;
start_y = 16 + current_font.height;
scaler.face_id = current_font.face_id;
scaler.width = current_font.width;
scaler.height = current_font.height;
scaler.pixel = 1;
error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );
if ( error )
goto Exit;
error = FT_Stroker_New( size->face->memory, &stroker );
if ( error )
goto Exit;
FT_Stroker_Set( stroker,
64,
FT_STROKER_LINECAP_ROUND,
FT_STROKER_LINEJOIN_ROUND,
0 );
step_x = size->metrics.x_ppem + 4;
step_y = ( size->metrics.height >> 6 ) + 4;
x = start_x;
y = start_y;
i = first_index;
i = first_index;
while ( i < face->num_glyphs )
{
int left, top, x_advance, y_advance, x_top, y_top;
FT_GlyphSlot slot = size->face->glyph;
FT_Glyph glyphp;
#if 0
gindex = *(unsigned char*)p;
if ( encoding == FT_ENCODING_NONE )
gindex = get_glyph_index( gindex );
#endif
error = FT_Load_Glyph( size->face, i, FT_LOAD_NO_BITMAP );
if ( !error && slot->format == FT_GLYPH_FORMAT_OUTLINE )
{
FT_Glyph glyphb;
error = FT_Get_Glyph( slot, &glyphp );
if ( error )
goto Next;
error = FT_Glyph_Stroke( &glyphp, stroker, 1 );
if ( error )
{
FT_Done_Glyph( glyphp );
goto Next;
}
error = glyph_to_bitmap( glyphp, &bit3, &left, &top,
&x_advance, &y_advance, (FT_Pointer*)&glyphb );
if ( !error )
{
/* now render the bitmap into the display surface */
x_top = x + left;
y_top = y - top;
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
FT_Done_Glyph( glyphb );
FT_Done_Glyph( glyphp );
x += x_advance + 1;
if ( x + size->metrics.x_ppem > bit.width )
{
x = start_x;
y += step_y;
if ( y >= bit.rows )
goto Exit;
}
}
else
FT_Done_Glyph( glyphp );
if ( error )
goto Next;
}
else
{
Next:
Fail++;
}
i++;
}
Exit:
if ( stroker )
FT_Stroker_Done( stroker );
return error;
}
/* most code is copied from Render_Stroke */
static FT_Error
Render_Embolden( int first_index )
{
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
FTC_ScalerRec scaler;
int i;
grBitmap bit3;
start_x = 4;
start_y = 16 + current_font.height;
scaler.face_id = current_font.face_id;
scaler.width = current_font.width;
scaler.height = current_font.height;
scaler.pixel = 1;
error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );
if ( error )
goto Exit;
step_x = size->metrics.x_ppem + 4;
step_y = ( size->metrics.height >> 6 ) + 4;
x = start_x;
y = start_y;
i = first_index;
i = first_index;
while ( i < face->num_glyphs )
{
int left, top, x_advance, y_advance, x_top, y_top;
FT_GlyphSlot slot = size->face->glyph;
FT_Glyph glyphp;
#if 0
gindex = *(unsigned char*)p;
if ( encoding == FT_ENCODING_NONE )
gindex = get_glyph_index( gindex );
#endif
error = FT_Load_Glyph( size->face, i, FT_LOAD_DEFAULT );
if ( !error )
{
FT_Glyph glyphb;
FT_GlyphSlot_Embolden( slot );
error = FT_Get_Glyph( slot, &glyphp );
if ( error )
goto Next;
error = glyph_to_bitmap( glyphp, &bit3, &left, &top,
&x_advance, &y_advance,
(FT_Pointer*)&glyphb );
if ( !error )
{
/* now render the bitmap into the display surface */
x_top = x + left;
y_top = y - top;
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
FT_Done_Glyph( glyphb );
FT_Done_Glyph( glyphp );
x += x_advance + 1;
if ( x + size->metrics.x_ppem > bit.width )
{
x = start_x;
y += step_y;
if ( y >= bit.rows )
goto Exit;
}
}
else
FT_Done_Glyph( glyphp );
if ( error )
goto Next;
}
else
{
Next:
Fail++;
}
i++;
}
Exit:
return error;
}
static FT_Error
Render_All( int first_index )
{
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
FTC_ScalerRec scaler;
FT_Pointer glyf;
int i;
grBitmap bit3;
start_x = 4;
start_y = 16 + current_font.height;
scaler.face_id = current_font.face_id;
scaler.width = current_font.width;
scaler.height = current_font.height;
scaler.pixel = 1;
error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );
if ( error )
{
/* probably a non-existent bitmap font size */
return error;
}
step_x = size->metrics.x_ppem + 4;
step_y = ( size->metrics.height >> 6 ) + 4;
x = start_x;
y = start_y;
i = first_index;
#if 0
while ( i < first_index + 1 )
#else
while ( i < num_indices )
#endif
{
int x_top, y_top, left, top, x_advance, y_advance;
error = get_glyph_bitmap( i, &bit3, &left, &top,
&x_advance, &y_advance, &glyf );
if ( !error )
{
/* now render the bitmap into the display surface */
x_top = x + left;
y_top = y - top;
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
if ( glyf )
done_glyph_bitmap( glyf );
x += x_advance + 1;
if ( x + size->metrics.x_ppem > bit.width )
{
x = start_x;
y += step_y;
if ( y >= bit.rows )
return FT_Err_Ok;
}
}
else
Fail++;
i++;
}
return FT_Err_Ok;
}
static FT_Error
Render_Text( int first_index )
{
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
FTC_ScalerRec scaler;
FT_Pointer glyf;
int i;
grBitmap bit3;
const unsigned char* p;
start_x = 4;
start_y = 16 + current_font.height;
scaler.face_id = current_font.face_id;
scaler.width = current_font.width;
scaler.height = current_font.height;
scaler.pixel = 1;
error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );
if ( error )
{
/* probably a non-existent bitmap font size */
return error;
}
step_x = size->metrics.x_ppem + 4;
step_y = ( size->metrics.height >> 6 ) + 4;
x = start_x;
y = start_y;
i = first_index;
p = Text;
while ( i > 0 && *p )
{
p++;
i--;
}
while ( *p )
{
int left, top, x_advance, y_advance, x_top, y_top;
FT_UInt gindex;
gindex = *(unsigned char*)p;
if ( encoding == FT_ENCODING_NONE )
gindex = get_glyph_index( gindex );
/* if a cmap is active, `get_glyph_bitmap' will convert the */
/* char code in `gindex' to a real glyph index */
error = get_glyph_bitmap( gindex, &bit3, &left, &top,
&x_advance, &y_advance, &glyf );
if ( !error )
{
/* now render the bitmap into the display surface */
x_top = x + left;
y_top = y - top;
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
if ( glyf )
done_glyph_bitmap( glyf );
x += x_advance + 1;
if ( x + size->metrics.x_ppem > bit.width )
{
x = start_x;
y += step_y;
if ( y >= bit.rows )
return FT_Err_Ok;
}
}
else
Fail++;
p++;
}
return FT_Err_Ok;
}
static FT_Error
Render_Waterfall( int first_size )
{
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
FT_Pointer glyf;
int pt_size, max_size = 100000;
grBitmap bit3;
unsigned char text[256];
const unsigned char* p;
start_x = 4;
start_y = 16;
pt_size = first_size;
{
error = FTC_Manager_LookupFace( cache_manager, current_font.face_id, &face );
if ( error )
{
/* can't access the font file. do not render anything */
fprintf( stderr, "can't access font file %p\n", current_font.face_id );
return 0;
}
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;
}
}
for (;;)
{
FTC_ScalerRec scaler;
sprintf( (char*)text,
"%d: the quick brown fox jumps over the lazy dog "
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pt_size );
p = text;
set_current_pointsize( pt_size );
if ( pt_size > max_size )
break;
pt_size++;
scaler.face_id = current_font.face_id;
scaler.width = current_font.width;
scaler.height = current_font.height;
scaler.pixel = 1;
error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );
if ( error )
{
/* probably a non-existent bitmap font size */
continue;
}
step_x = size->metrics.x_ppem + 4;
step_y = ( size->metrics.height >> 6 ) + 1;
x = start_x;
y = start_y + ( size->metrics.ascender >> 6 );
start_y += step_y;
if ( y >= bit.rows )
break;
while ( *p )
{
int left, top, x_advance, y_advance, x_top, y_top;
FT_UInt gindex;
gindex = *(unsigned char*)p;
if ( encoding == FT_ENCODING_NONE )
gindex = get_glyph_index( gindex );
/* if a cmap is active, `get_glyph_bitmap' will convert the */
/* char code in `gindex' to a real glyph index */
error = get_glyph_bitmap( gindex, &bit3, &left, &top,
&x_advance, &y_advance, &glyf );
if ( !error )
{
/* now render the bitmap into the display surface */
x_top = x + left;
y_top = y - top;
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
if ( glyf )
done_glyph_bitmap( glyf );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -