📄 ftobjs.c
字号:
error = FT_Err_Unknown_File_Format;
Fail2:
FT_Stream_Free( stream, external_stream );
goto Fail;
}
Success:
FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
/* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
if ( external_stream )
face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
/* add the face object to its driver's list */
if ( FT_NEW( node ) )
goto Fail;
node->data = face;
/* don't assume driver is the same as face->driver, so use */
/* face->driver instead. */
FT_List_Add( &face->driver->faces_list, node );
/* now allocate a glyph slot object for the face */
FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
if ( face_index >= 0 )
{
error = FT_New_GlyphSlot( face, NULL );
if ( error )
goto Fail;
/* finally, allocate a size object for the face */
{
FT_Size size;
FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
error = FT_New_Size( face, &size );
if ( error )
goto Fail;
face->size = size;
}
}
/* some checks */
if ( FT_IS_SCALABLE( face ) )
{
if ( face->height < 0 )
face->height = (FT_Short)-face->height;
if ( !FT_HAS_VERTICAL( face ) )
face->max_advance_height = (FT_Short)face->height;
}
if ( FT_HAS_FIXED_SIZES( face ) )
{
FT_Int i;
for ( i = 0; i < face->num_fixed_sizes; i++ )
{
FT_Bitmap_Size* bsize = face->available_sizes + i;
if ( bsize->height < 0 )
bsize->height = (FT_Short)-bsize->height;
if ( bsize->x_ppem < 0 )
bsize->x_ppem = (FT_Short)-bsize->x_ppem;
if ( bsize->y_ppem < 0 )
bsize->y_ppem = -bsize->y_ppem;
}
}
/* initialize internal face data */
{
FT_Face_Internal internal = face->internal;
internal->transform_matrix.xx = 0x10000L;
internal->transform_matrix.xy = 0;
internal->transform_matrix.yx = 0;
internal->transform_matrix.yy = 0x10000L;
internal->transform_delta.x = 0;
internal->transform_delta.y = 0;
}
if ( aface )
*aface = face;
else
FT_Done_Face( face );
goto Exit;
Fail:
FT_Done_Face( face );
Exit:
FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
return error;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Error )
FT_Attach_File( FT_Face face,
const char* filepathname )
{
FT_Open_Args open;
/* test for valid `face' delayed to FT_Attach_Stream() */
if ( !filepathname )
return FT_Err_Invalid_Argument;
open.stream = NULL;
open.flags = FT_OPEN_PATHNAME;
open.pathname = (char*)filepathname;
return FT_Attach_Stream( face, &open );
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Error )
FT_Attach_Stream( FT_Face face,
FT_Open_Args* parameters )
{
FT_Stream stream;
FT_Error error;
FT_Driver driver;
FT_Driver_Class clazz;
/* test for valid `parameters' delayed to FT_Stream_New() */
if ( !face )
return FT_Err_Invalid_Face_Handle;
driver = face->driver;
if ( !driver )
return FT_Err_Invalid_Driver_Handle;
error = FT_Stream_New( driver->root.library, parameters, &stream );
if ( error )
goto Exit;
/* we implement FT_Attach_Stream in each driver through the */
/* `attach_file' interface */
error = FT_Err_Unimplemented_Feature;
clazz = driver->clazz;
if ( clazz->attach_file )
error = clazz->attach_file( face, stream );
/* close the attached stream */
FT_Stream_Free( stream,
(FT_Bool)( parameters->stream &&
( parameters->flags & FT_OPEN_STREAM ) ) );
Exit:
return error;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Error )
FT_Done_Face( FT_Face face )
{
FT_Error error;
FT_Driver driver;
FT_Memory memory;
FT_ListNode node;
error = FT_Err_Invalid_Face_Handle;
if ( face && face->driver )
{
driver = face->driver;
memory = driver->root.memory;
/* find face in driver's list */
node = FT_List_Find( &driver->faces_list, face );
if ( node )
{
/* remove face object from the driver's list */
FT_List_Remove( &driver->faces_list, node );
FT_FREE( node );
/* now destroy the object proper */
destroy_face( memory, face, driver );
error = FT_Err_Ok;
}
}
return error;
}
/* documentation is in ftobjs.h */
FT_EXPORT_DEF( FT_Error )
FT_New_Size( FT_Face face,
FT_Size *asize )
{
FT_Error error;
FT_Memory memory;
FT_Driver driver;
FT_Driver_Class clazz;
FT_Size size = 0;
FT_ListNode node = 0;
if ( !face )
return FT_Err_Invalid_Face_Handle;
if ( !asize )
return FT_Err_Invalid_Size_Handle;
if ( !face->driver )
return FT_Err_Invalid_Driver_Handle;
*asize = 0;
driver = face->driver;
clazz = driver->clazz;
memory = face->memory;
/* Allocate new size object and perform basic initialisation */
if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
goto Exit;
size->face = face;
/* for now, do not use any internal fields in size objects */
size->internal = 0;
if ( clazz->init_size )
error = clazz->init_size( size );
/* in case of success, add to the face's list */
if ( !error )
{
*asize = size;
node->data = size;
FT_List_Add( &face->sizes_list, node );
}
Exit:
if ( error )
{
FT_FREE( node );
FT_FREE( size );
}
return error;
}
/* documentation is in ftobjs.h */
FT_EXPORT_DEF( FT_Error )
FT_Done_Size( FT_Size size )
{
FT_Error error;
FT_Driver driver;
FT_Memory memory;
FT_Face face;
FT_ListNode node;
if ( !size )
return FT_Err_Invalid_Size_Handle;
face = size->face;
if ( !face )
return FT_Err_Invalid_Face_Handle;
driver = face->driver;
if ( !driver )
return FT_Err_Invalid_Driver_Handle;
memory = driver->root.memory;
error = FT_Err_Ok;
node = FT_List_Find( &face->sizes_list, size );
if ( node )
{
FT_List_Remove( &face->sizes_list, node );
FT_FREE( node );
if ( face->size == size )
{
face->size = 0;
if ( face->sizes_list.head )
face->size = (FT_Size)(face->sizes_list.head->data);
}
destroy_size( memory, size, driver );
}
else
error = FT_Err_Invalid_Size_Handle;
return error;
}
/* documentation is in ftobjs.h */
FT_BASE_DEF( FT_Error )
FT_Match_Size( FT_Face face,
FT_Size_Request req,
FT_Bool ignore_width,
FT_ULong* size_index )
{
FT_Int i;
FT_Long w, h;
if ( !FT_HAS_FIXED_SIZES( face ) )
return FT_Err_Invalid_Face_Handle;
/* FT_Bitmap_Size doesn't provide enough info... */
if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
return FT_Err_Unimplemented_Feature;
w = FT_REQUEST_WIDTH ( req );
h = FT_REQUEST_HEIGHT( req );
if ( req->width && !req->height )
h = w;
else if ( !req->width && req->height )
w = h;
w = FT_PIX_ROUND( w );
h = FT_PIX_ROUND( h );
for ( i = 0; i < face->num_fixed_sizes; i++ )
{
FT_Bitmap_Size* bsize = face->available_sizes + i;
if ( h != FT_PIX_ROUND( bsize->y_ppem ) )
continue;
if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
{
if ( size_index )
*size_index = (FT_ULong)i;
return FT_Err_Ok;
}
}
return FT_Err_Invalid_Pixel_Size;
}
/* documentation is in ftobjs.h */
FT_BASE_DEF( void )
ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics,
FT_Pos advance )
{
/* the factor 1.2 is a heuristical value */
if ( !advance )
advance = metrics->height * 12 / 10;
metrics->vertBearingX = -( metrics->width / 2 );
metrics->vertBearingY = ( advance - metrics->height ) / 2;
metrics->vertAdvance = advance;
}
static void
ft_recompute_scaled_metrics( FT_Face face,
FT_Size_Metrics* metrics )
{
/* Compute root ascender, descender, test height, and max_advance */
#ifdef GRID_FIT_METRICS
metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender,
metrics->y_scale ) );
metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender,
metrics->y_scale ) );
metrics->height = FT_PIX_ROUND( FT_MulFix( face->height,
metrics->y_scale ) );
metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,
metrics->x_scale ) );
#else /* !GRID_FIT_METRICS */
metrics->ascender = FT_MulFix( face->ascender,
metrics->y_scale );
metrics->descender = FT_MulFix( face->descender,
metrics->y_scale );
metrics->height = FT_MulFix( face->height,
metrics->y_scale );
metrics->max_advance = FT_MulFix( face->max_advance_width,
metrics->x_scale );
#endif /* !GRID_FIT_METRICS */
}
FT_BASE_DEF( void )
FT_Select_Metrics( FT_Face face,
FT_ULong strike_index )
{
FT_Size_Metrics* metrics;
FT_Bitmap_Size* bsize;
metrics = &face->size->metrics;
bsize = face->available_sizes + strike_index;
metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );
metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );
if ( FT_IS_SCALABLE( face ) )
{
metrics->x_scale = FT_DivFix( bsize->x_ppem,
face->units_per_EM );
metrics->y_scale = FT_DivFix( bsize->y_ppem,
face->units_per_EM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -