?? ftcmanag.c
字號:
/***************************************************************************//* *//* ftcmanag.c *//* *//* FreeType Cache Manager (body). *//* *//* Copyright 2000-2001, 2002 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 FT_CACHE_MANAGER_H#include FT_CACHE_INTERNAL_LRU_H#include FT_INTERNAL_OBJECTS_H#include FT_INTERNAL_DEBUG_H#include FT_SIZES_H#include "ftcerror.h"#undef FT_COMPONENT#define FT_COMPONENT trace_cache#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FACE LRU IMPLEMENTATION *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct FTC_FaceNodeRec_* FTC_FaceNode; typedef struct FTC_SizeNodeRec_* FTC_SizeNode; typedef struct FTC_FaceNodeRec_ { FT_LruNodeRec lru; FT_Face face; } FTC_FaceNodeRec; typedef struct FTC_SizeNodeRec_ { FT_LruNodeRec lru; FT_Size size; } FTC_SizeNodeRec; FT_CALLBACK_DEF( FT_Error ) ftc_face_node_init( FTC_FaceNode node, FTC_FaceID face_id, FTC_Manager manager ) { FT_Error error; 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; } /* helper function for ftc_face_node_done() */ FT_CALLBACK_DEF( FT_Bool ) ftc_size_node_select( FTC_SizeNode node, FT_Face face ) { return FT_BOOL( node->size->face == face ); } FT_CALLBACK_DEF( void ) ftc_face_node_done( FTC_FaceNode node, FTC_Manager manager ) { FT_Face face = node->face; /* we must begin by removing all sizes for the target face */ /* from the manager's list */ FT_LruList_Remove_Selection( manager->sizes_list, (FT_LruNode_SelectFunc)ftc_size_node_select, face ); /* all right, we can discard the face now */ FT_Done_Face( face ); node->face = NULL; } FT_CALLBACK_TABLE_DEF const FT_LruList_ClassRec ftc_face_list_class = { sizeof ( FT_LruListRec ), (FT_LruList_InitFunc)0, (FT_LruList_DoneFunc)0, sizeof ( FTC_FaceNodeRec ), (FT_LruNode_InitFunc) ftc_face_node_init, (FT_LruNode_DoneFunc) ftc_face_node_done, (FT_LruNode_FlushFunc) 0, /* no flushing needed */ (FT_LruNode_CompareFunc)0, /* direct comparison of FTC_FaceID handles */ }; /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) FTC_Manager_Lookup_Face( 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; error = FT_LruList_Lookup( manager->faces_list, (FT_LruKey)face_id, (FT_LruNode*)&node ); if ( !error ) *aface = node->face; return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** SIZES LRU IMPLEMENTATION *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct FTC_SizeQueryRec_ { FT_Face face; FT_UInt width; FT_UInt height; } FTC_SizeQueryRec, *FTC_SizeQuery; FT_CALLBACK_DEF( FT_Error ) ftc_size_node_init( FTC_SizeNode node, FTC_SizeQuery query ) { FT_Face face = query->face; FT_Size size; FT_Error error; node->size = NULL; error = FT_New_Size( face, &size ); if ( !error ) { FT_Activate_Size( size ); error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); if ( error ) FT_Done_Size( size ); else node->size = size; } return error; } FT_CALLBACK_DEF( void ) ftc_size_node_done( FTC_SizeNode node ) { if ( node->size ) { FT_Done_Size( node->size ); node->size = NULL; } } FT_CALLBACK_DEF( FT_Error ) ftc_size_node_flush( FTC_SizeNode node, FTC_SizeQuery query ) { FT_Size size = node->size; FT_Error error; if ( size->face == query->face ) { FT_Activate_Size( size ); error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); if ( error ) { FT_Done_Size( size ); node->size = NULL; } } else { FT_Done_Size( size ); node->size = NULL; error = ftc_size_node_init( node, query ); } return error; } FT_CALLBACK_DEF( FT_Bool ) ftc_size_node_compare( FTC_SizeNode node, FTC_SizeQuery query ) { FT_Size size = node->size; return FT_BOOL( size->face == query->face && (FT_UInt)size->metrics.x_ppem == query->width && (FT_UInt)size->metrics.y_ppem == query->height ); } FT_CALLBACK_TABLE_DEF const FT_LruList_ClassRec ftc_size_list_class = { sizeof ( FT_LruListRec ), (FT_LruList_InitFunc)0, (FT_LruList_DoneFunc)0, sizeof ( FTC_SizeNodeRec ), (FT_LruNode_InitFunc) ftc_size_node_init, (FT_LruNode_DoneFunc) ftc_size_node_done, (FT_LruNode_FlushFunc) ftc_size_node_flush, (FT_LruNode_CompareFunc)ftc_size_node_compare }; /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) FTC_Manager_Lookup_Size( FTC_Manager manager, FTC_Font font, FT_Face *aface, FT_Size *asize ) { FT_Error error; /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ if ( aface ) *aface = 0; if ( asize ) *asize = 0; error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); if ( !error ) { FTC_SizeQueryRec query; FTC_SizeNode node; query.face = *aface; query.width = font->pix_width; query.height = font->pix_height; error = FT_LruList_Lookup( manager->sizes_list, (FT_LruKey)&query, (FT_LruNode*)&node ); if ( !error ) { /* select the size as the current one for this face */ FT_Activate_Size( node->size ); if ( asize ) *asize = node->size; } } return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** SET TABLE MANAGEMENT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static void ftc_family_table_init( FTC_FamilyTable table ) { table->count = 0; table->size = 0; table->entries = NULL; table->free = FTC_FAMILY_ENTRY_NONE; } static void ftc_family_table_done( FTC_FamilyTable table, FT_Memory memory ) { FT_FREE( table->entries ); table->free = 0; table->count = 0; table->size = 0; } FT_EXPORT_DEF( FT_Error ) ftc_family_table_alloc( FTC_FamilyTable table, FT_Memory memory, FTC_FamilyEntry *aentry ) { FTC_FamilyEntry entry; FT_Error error = 0; /* re-allocate table size when needed */ if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size ) { FT_UInt old_size = table->size; FT_UInt new_size, idx; if ( old_size == 0 ) new_size = 8; else { new_size = old_size * 2; /* check for (unlikely) overflow */ if ( new_size < old_size ) new_size = 65534; } if ( FT_RENEW_ARRAY( table->entries, old_size, new_size ) ) return error; table->size = new_size; entry = table->entries + old_size; table->free = old_size; for ( idx = old_size; idx + 1 < new_size; idx++, entry++ ) { entry->link = idx + 1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -