📄 ftobjs.c
字号:
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 ); ft_recompute_scaled_metrics( face, metrics ); } else { metrics->x_scale = 1L << 22; metrics->y_scale = 1L << 22; metrics->ascender = bsize->y_ppem; metrics->descender = 0; metrics->height = bsize->height << 6; metrics->max_advance = bsize->x_ppem; } } FT_BASE_DEF( void ) FT_Request_Metrics( FT_Face face, FT_Size_Request req ) { FT_Driver_Class clazz; FT_Size_Metrics* metrics; clazz = face->driver->clazz; metrics = &face->size->metrics; if ( FT_IS_SCALABLE( face ) ) { FT_Long w, h, scaled_w = 0, scaled_h = 0; switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: w = h = face->units_per_EM; break; case FT_SIZE_REQUEST_TYPE_REAL_DIM: w = h = face->ascender - face->descender; break; case FT_SIZE_REQUEST_TYPE_CELL: w = face->max_advance_width; h = face->ascender - face->descender; break; case FT_SIZE_REQUEST_TYPE_BBOX: w = face->bbox.xMax - face->bbox.xMin; h = face->bbox.yMax - face->bbox.yMin; break; case FT_SIZE_REQUEST_TYPE_SCALES: metrics->x_scale = (FT_Fixed)req->width; metrics->y_scale = (FT_Fixed)req->height; if ( !metrics->x_scale ) metrics->x_scale = metrics->y_scale; else if ( !metrics->y_scale ) metrics->y_scale = metrics->x_scale; goto Calculate_Ppem; break; default: /* this never happens */ return; break; } /* to be on the safe side */ if ( w < 0 ) w = -w; if ( h < 0 ) h = -h; scaled_w = FT_REQUEST_WIDTH ( req ); scaled_h = FT_REQUEST_HEIGHT( req ); /* determine scales */ if ( req->width ) { metrics->x_scale = FT_DivFix( scaled_w, w ); if ( req->height ) { metrics->y_scale = FT_DivFix( scaled_h, h ); if ( req->type == FT_SIZE_REQUEST_TYPE_CELL ) { if ( metrics->y_scale > metrics->x_scale ) metrics->y_scale = metrics->x_s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -