📄 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 + -