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