📄 ftcmanag.c
字号:
/***************************************************************************/
/* */
/* ftcmanag.c */
/* */
/* FreeType Cache Manager (body). */
/* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_CACHE_H
#include "ftcmanag.h"
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_SIZES_H
#include "ftccback.h"
#include "ftcerror.h"
#undef FT_COMPONENT
#define FT_COMPONENT trace_cache
#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data )
static FT_Error
ftc_scaler_lookup_size( FTC_Manager manager,
FTC_Scaler scaler,
FT_Size *asize )
{
FT_Face face;
FT_Size size = NULL;
FT_Error error;
error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
if ( error )
goto Exit;
error = FT_New_Size( face, &size );
if ( error )
goto Exit;
FT_Activate_Size( size );
if ( scaler->pixel )
error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
else
error = FT_Set_Char_Size( face, scaler->width, scaler->height,
scaler->x_res, scaler->y_res );
if ( error )
{
FT_Done_Size( size );
size = NULL;
}
Exit:
*asize = size;
return error;
}
typedef struct FTC_SizeNodeRec_
{
FTC_MruNodeRec node;
FT_Size size;
FTC_ScalerRec scaler;
} FTC_SizeNodeRec, *FTC_SizeNode;
FT_CALLBACK_DEF( void )
ftc_size_node_done( FTC_MruNode ftcnode,
FT_Pointer data )
{
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
FT_Size size = node->size;
FT_UNUSED( data );
if ( size )
FT_Done_Size( size );
}
FT_CALLBACK_DEF( FT_Bool )
ftc_size_node_compare( FTC_MruNode ftcnode,
FT_Pointer ftcscaler )
{
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
FTC_Scaler scaler0 = &node->scaler;
if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
{
FT_Activate_Size( node->size );
return 1;
}
return 0;
}
FT_CALLBACK_DEF( FT_Error )
ftc_size_node_init( FTC_MruNode ftcnode,
FT_Pointer ftcscaler,
FT_Pointer ftcmanager )
{
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
FTC_Manager manager = (FTC_Manager)ftcmanager;
node->scaler = scaler[0];
return ftc_scaler_lookup_size( manager, scaler, &node->size );
}
FT_CALLBACK_DEF( FT_Error )
ftc_size_node_reset( FTC_MruNode ftcnode,
FT_Pointer ftcscaler,
FT_Pointer ftcmanager )
{
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
FTC_Manager manager = (FTC_Manager)ftcmanager;
FT_Done_Size( node->size );
node->scaler = scaler[0];
return ftc_scaler_lookup_size( manager, scaler, &node->size );
}
FT_CALLBACK_TABLE_DEF
const FTC_MruListClassRec ftc_size_list_class =
{
sizeof ( FTC_SizeNodeRec ),
ftc_size_node_compare,
ftc_size_node_init,
ftc_size_node_reset,
ftc_size_node_done
};
/* helper function used by ftc_face_node_done */
static FT_Bool
ftc_size_node_compare_faceid( FTC_MruNode ftcnode,
FT_Pointer ftcface_id )
{
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
return FT_BOOL( node->scaler.face_id == face_id );
}
/* documentation is in ftcache.h */
FT_EXPORT_DEF( FT_Error )
FTC_Manager_LookupSize( FTC_Manager manager,
FTC_Scaler scaler,
FT_Size *asize )
{
FT_Error error;
FTC_SizeNode node;
if ( asize == NULL )
return FTC_Err_Bad_Argument;
*asize = NULL;
if ( !manager )
return FTC_Err_Invalid_Cache_Handle;
#ifdef FTC_INLINE
FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare,
node, error );
#else
error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node );
#endif
if ( !error )
*asize = node->size;
return error;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** FACE MRU IMPLEMENTATION *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct FTC_FaceNodeRec_
{
FTC_MruNodeRec node;
FTC_FaceID face_id;
FT_Face face;
} FTC_FaceNodeRec, *FTC_FaceNode;
FT_CALLBACK_DEF( FT_Error )
ftc_face_node_init( FTC_MruNode ftcnode,
FT_Pointer ftcface_id,
FT_Pointer ftcmanager )
{
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
FTC_Manager manager = (FTC_Manager)ftcmanager;
FT_Error error;
node->face_id = face_id;
error = manager->request_face( face_id,
manager->library,
manager->request_data,
&node->face );
if ( !error )
{
/* destroy initial size object; it will be re-created later */
if ( node->face->size )
FT_Done_Size( node->face->size );
}
return error;
}
FT_CALLBACK_DEF( void )
ftc_face_node_done( FTC_MruNode ftcnode,
FT_Pointer ftcmanager )
{
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
FTC_Manager manager = (FTC_Manager)ftcmanager;
/* we must begin by removing all scalers for the target face */
/* from the manager's list */
FTC_MruList_RemoveSelection( &manager->sizes,
ftc_size_node_compare_faceid,
node->face_id );
/* all right, we can discard the face now */
FT_Done_Face( node->face );
node->face = NULL;
node->face_id = NULL;
}
FT_CALLBACK_DEF( FT_Bool )
ftc_face_node_compare( FTC_MruNode ftcnode,
FT_Pointer ftcface_id )
{
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
return FT_BOOL( node->face_id == face_id );
}
FT_CALLBACK_TABLE_DEF
const FTC_MruListClassRec ftc_face_list_class =
{
sizeof ( FTC_FaceNodeRec),
ftc_face_node_compare,
ftc_face_node_init,
0, /* FTC_MruNode_ResetFunc */
ftc_face_node_done
};
/* documentation is in ftcache.h */
FT_EXPORT_DEF( FT_Error )
FTC_Manager_LookupFace( FTC_Manager manager,
FTC_FaceID face_id,
FT_Face *aface )
{
FT_Error error;
FTC_FaceNode node;
if ( aface == NULL )
return FTC_Err_Bad_Argument;
*aface = NULL;
if ( !manager )
return FTC_Err_Invalid_Cache_Handle;
/* we break encapsulation for the sake of speed */
#ifdef FTC_INLINE
FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare,
node, error );
#else
error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node );
#endif
if ( !error )
*aface = node->face;
return error;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CACHE MANAGER ROUTINES *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* documentation is in ftcache.h */
FT_EXPORT_DEF( FT_Error )
FTC_Manager_New( FT_Library library,
FT_UInt max_faces,
FT_UInt max_sizes,
FT_ULong max_bytes,
FTC_Face_Requester requester,
FT_Pointer req_data,
FTC_Manager *amanager )
{
FT_Error error;
FT_Memory memory;
FTC_Manager manager = 0;
if ( !library )
return FTC_Err_Invalid_Library_Handle;
memory = library->memory;
if ( FT_NEW( manager ) )
goto Exit;
if ( max_faces == 0 )
max_faces = FTC_MAX_FACES_DEFAULT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -