1 /**************************************************************************** 2 * 3 * ftcglyph.c 4 * 5 * FreeType Glyph Image (FT_Glyph) cache (body). 6 * 7 * Copyright (C) 2000-2020 by 8 * David Turner, Robert Wilhelm, and Werner Lemberg. 9 * 10 * This file is part of the FreeType project, and may only be used, 11 * modified, and distributed under the terms of the FreeType project 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 19 #include <freetype/internal/ftobjs.h> 20 #include <freetype/ftcache.h> 21 #include "ftcglyph.h" 22 #include <freetype/fterrors.h> 23 24 #include "ftccback.h" 25 #include "ftcerror.h" 26 27 28 /* create a new chunk node, setting its cache index and ref count */ 29 FT_LOCAL_DEF( void ) FTC_GNode_Init(FTC_GNode gnode,FT_UInt gindex,FTC_Family family)30 FTC_GNode_Init( FTC_GNode gnode, 31 FT_UInt gindex, 32 FTC_Family family ) 33 { 34 gnode->family = family; 35 gnode->gindex = gindex; 36 family->num_nodes++; 37 } 38 39 40 FT_LOCAL_DEF( void ) FTC_GNode_UnselectFamily(FTC_GNode gnode,FTC_Cache cache)41 FTC_GNode_UnselectFamily( FTC_GNode gnode, 42 FTC_Cache cache ) 43 { 44 FTC_Family family = gnode->family; 45 46 47 gnode->family = NULL; 48 if ( family && --family->num_nodes == 0 ) 49 FTC_FAMILY_FREE( family, cache ); 50 } 51 52 53 FT_LOCAL_DEF( void ) FTC_GNode_Done(FTC_GNode gnode,FTC_Cache cache)54 FTC_GNode_Done( FTC_GNode gnode, 55 FTC_Cache cache ) 56 { 57 /* finalize the node */ 58 gnode->gindex = 0; 59 60 FTC_GNode_UnselectFamily( gnode, cache ); 61 } 62 63 64 FT_LOCAL_DEF( FT_Bool ) ftc_gnode_compare(FTC_Node ftcgnode,FT_Pointer ftcgquery,FTC_Cache cache,FT_Bool * list_changed)65 ftc_gnode_compare( FTC_Node ftcgnode, 66 FT_Pointer ftcgquery, 67 FTC_Cache cache, 68 FT_Bool* list_changed ) 69 { 70 FTC_GNode gnode = (FTC_GNode)ftcgnode; 71 FTC_GQuery gquery = (FTC_GQuery)ftcgquery; 72 FT_UNUSED( cache ); 73 74 75 if ( list_changed ) 76 *list_changed = FALSE; 77 return FT_BOOL( gnode->family == gquery->family && 78 gnode->gindex == gquery->gindex ); 79 } 80 81 82 #ifdef FTC_INLINE 83 84 FT_LOCAL_DEF( FT_Bool ) FTC_GNode_Compare(FTC_GNode gnode,FTC_GQuery gquery,FTC_Cache cache,FT_Bool * list_changed)85 FTC_GNode_Compare( FTC_GNode gnode, 86 FTC_GQuery gquery, 87 FTC_Cache cache, 88 FT_Bool* list_changed ) 89 { 90 return ftc_gnode_compare( FTC_NODE( gnode ), gquery, 91 cache, list_changed ); 92 } 93 94 #endif 95 96 /*************************************************************************/ 97 /*************************************************************************/ 98 /***** *****/ 99 /***** CHUNK SETS *****/ 100 /***** *****/ 101 /*************************************************************************/ 102 /*************************************************************************/ 103 104 FT_LOCAL_DEF( void ) FTC_Family_Init(FTC_Family family,FTC_Cache cache)105 FTC_Family_Init( FTC_Family family, 106 FTC_Cache cache ) 107 { 108 FTC_GCacheClass clazz = FTC_CACHE_GCACHE_CLASS( cache ); 109 110 111 family->clazz = clazz->family_class; 112 family->num_nodes = 0; 113 family->cache = cache; 114 } 115 116 117 FT_LOCAL_DEF( FT_Error ) ftc_gcache_init(FTC_Cache ftccache)118 ftc_gcache_init( FTC_Cache ftccache ) 119 { 120 FTC_GCache cache = (FTC_GCache)ftccache; 121 FT_Error error; 122 123 124 error = FTC_Cache_Init( FTC_CACHE( cache ) ); 125 if ( !error ) 126 { 127 FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; 128 129 FTC_MruList_Init( &cache->families, 130 clazz->family_class, 131 0, /* no maximum here! */ 132 cache, 133 FTC_CACHE( cache )->memory ); 134 } 135 136 return error; 137 } 138 139 140 #if 0 141 142 FT_LOCAL_DEF( FT_Error ) 143 FTC_GCache_Init( FTC_GCache cache ) 144 { 145 return ftc_gcache_init( FTC_CACHE( cache ) ); 146 } 147 148 #endif /* 0 */ 149 150 151 FT_LOCAL_DEF( void ) ftc_gcache_done(FTC_Cache ftccache)152 ftc_gcache_done( FTC_Cache ftccache ) 153 { 154 FTC_GCache cache = (FTC_GCache)ftccache; 155 156 157 FTC_Cache_Done( (FTC_Cache)cache ); 158 FTC_MruList_Done( &cache->families ); 159 } 160 161 162 #if 0 163 164 FT_LOCAL_DEF( void ) 165 FTC_GCache_Done( FTC_GCache cache ) 166 { 167 ftc_gcache_done( FTC_CACHE( cache ) ); 168 } 169 170 #endif /* 0 */ 171 172 173 FT_LOCAL_DEF( FT_Error ) FTC_GCache_New(FTC_Manager manager,FTC_GCacheClass clazz,FTC_GCache * acache)174 FTC_GCache_New( FTC_Manager manager, 175 FTC_GCacheClass clazz, 176 FTC_GCache *acache ) 177 { 178 return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, 179 (FTC_Cache*)acache ); 180 } 181 182 183 #ifndef FTC_INLINE 184 185 FT_LOCAL_DEF( FT_Error ) FTC_GCache_Lookup(FTC_GCache cache,FT_Offset hash,FT_UInt gindex,FTC_GQuery query,FTC_Node * anode)186 FTC_GCache_Lookup( FTC_GCache cache, 187 FT_Offset hash, 188 FT_UInt gindex, 189 FTC_GQuery query, 190 FTC_Node *anode ) 191 { 192 FT_Error error; 193 194 195 query->gindex = gindex; 196 197 FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); 198 if ( !error ) 199 { 200 FTC_Family family = query->family; 201 202 203 /* prevent the family from being destroyed too early when an */ 204 /* out-of-memory condition occurs during glyph node initialization. */ 205 family->num_nodes++; 206 207 error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); 208 209 if ( --family->num_nodes == 0 ) 210 FTC_FAMILY_FREE( family, cache ); 211 } 212 return error; 213 } 214 215 #endif /* !FTC_INLINE */ 216 217 218 /* END */ 219