00001 /***************************************************************************/ 00002 /* */ 00003 /* ftcglyph.h */ 00004 /* */ 00005 /* FreeType abstract glyph cache (specification). */ 00006 /* */ 00007 /* Copyright 2000-2001, 2003, 2004, 2006, 2007 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 /* 00020 * 00021 * FTC_GCache is an _abstract_ cache object optimized to store glyph 00022 * data. It works as follows: 00023 * 00024 * - It manages FTC_GNode objects. Each one of them can hold one or more 00025 * glyph `items'. Item types are not specified in the FTC_GCache but 00026 * in classes that extend it. 00027 * 00028 * - Glyph attributes, like face ID, character size, render mode, etc., 00029 * can be grouped into abstract `glyph families'. This avoids storing 00030 * the attributes within the FTC_GCache, since it is likely that many 00031 * FTC_GNodes will belong to the same family in typical uses. 00032 * 00033 * - Each FTC_GNode is thus an FTC_Node with two additional fields: 00034 * 00035 * * gindex: A glyph index, or the first index in a glyph range. 00036 * * family: A pointer to a glyph `family'. 00037 * 00038 * - Family types are not fully specific in the FTC_Family type, but 00039 * by classes that extend it. 00040 * 00041 * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. 00042 * They share an FTC_Family sub-class called FTC_BasicFamily which is 00043 * used to store the following data: face ID, pixel/point sizes, load 00044 * flags. For more details see the file `src/cache/ftcbasic.c'. 00045 * 00046 * Client applications can extend FTC_GNode with their own FTC_GNode 00047 * and FTC_Family sub-classes to implement more complex caches (e.g., 00048 * handling automatic synthesis, like obliquing & emboldening, colored 00049 * glyphs, etc.). 00050 * 00051 * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and 00052 * `ftcsbits.h', which both extend FTC_GCache with additional 00053 * optimizations. 00054 * 00055 * A typical FTC_GCache implementation must provide at least the 00056 * following: 00057 * 00058 * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: 00059 * my_node_new (must call FTC_GNode_Init) 00060 * my_node_free (must call FTC_GNode_Done) 00061 * my_node_compare (must call FTC_GNode_Compare) 00062 * my_node_remove_faceid (must call ftc_gnode_unselect in case 00063 * of match) 00064 * 00065 * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: 00066 * my_family_compare 00067 * my_family_init 00068 * my_family_reset (optional) 00069 * my_family_done 00070 * 00071 * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query 00072 * data. 00073 * 00074 * - Constant structures for a FTC_GNodeClass. 00075 * 00076 * - MyCacheNew() can be implemented easily as a call to the convenience 00077 * function FTC_GCache_New. 00078 * 00079 * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will 00080 * automatically: 00081 * 00082 * - Search for the corresponding family in the cache, or create 00083 * a new one if necessary. Put it in FTC_GQUERY(myquery).family 00084 * 00085 * - Call FTC_Cache_Lookup. 00086 * 00087 * If it returns NULL, you should create a new node, then call 00088 * ftc_cache_add as usual. 00089 */ 00090 00091 00092 /*************************************************************************/ 00093 /* */ 00094 /* Important: The functions defined in this file are only used to */ 00095 /* implement an abstract glyph cache class. You need to */ 00096 /* provide additional logic to implement a complete cache. */ 00097 /* */ 00098 /*************************************************************************/ 00099 00100 00101 /*************************************************************************/ 00102 /*************************************************************************/ 00103 /*************************************************************************/ 00104 /*************************************************************************/ 00105 /*************************************************************************/ 00106 /********* *********/ 00107 /********* WARNING, THIS IS BETA CODE. *********/ 00108 /********* *********/ 00109 /*************************************************************************/ 00110 /*************************************************************************/ 00111 /*************************************************************************/ 00112 /*************************************************************************/ 00113 /*************************************************************************/ 00114 00115 00116 #ifndef __FTCGLYPH_H__ 00117 #define __FTCGLYPH_H__ 00118 00119 00120 #include <ft2build.h> 00121 #include "ftcmanag.h" 00122 00123 00124 FT_BEGIN_HEADER 00125 00126 00127 /* 00128 * We can group glyphs into `families'. Each family correspond to a 00129 * given face ID, character size, transform, etc. 00130 * 00131 * Families are implemented as MRU list nodes. They are 00132 * reference-counted. 00133 */ 00134 00135 typedef struct FTC_FamilyRec_ 00136 { 00137 FTC_MruNodeRec mrunode; 00138 FT_UInt num_nodes; /* current number of nodes in this family */ 00139 FTC_Cache cache; 00140 FTC_MruListClass clazz; 00141 00142 } FTC_FamilyRec, *FTC_Family; 00143 00144 #define FTC_FAMILY(x) ( (FTC_Family)(x) ) 00145 #define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) 00146 00147 00148 typedef struct FTC_GNodeRec_ 00149 { 00150 FTC_NodeRec node; 00151 FTC_Family family; 00152 FT_UInt gindex; 00153 00154 } FTC_GNodeRec, *FTC_GNode; 00155 00156 #define FTC_GNODE( x ) ( (FTC_GNode)(x) ) 00157 #define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) 00158 00159 00160 typedef struct FTC_GQueryRec_ 00161 { 00162 FT_UInt gindex; 00163 FTC_Family family; 00164 00165 } FTC_GQueryRec, *FTC_GQuery; 00166 00167 #define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) 00168 00169 00170 /*************************************************************************/ 00171 /* */ 00172 /* These functions are exported so that they can be called from */ 00173 /* user-provided cache classes; otherwise, they are really part of the */ 00174 /* cache sub-system internals. */ 00175 /* */ 00176 00177 /* must be called by derived FTC_Node_InitFunc routines */ 00178 FT_LOCAL( void ) 00179 FTC_GNode_Init( FTC_GNode node, 00180 FT_UInt gindex, /* glyph index for node */ 00181 FTC_Family family ); 00182 00183 /* returns TRUE iff the query's glyph index correspond to the node; */ 00184 /* this assumes that the `family' and `hash' fields of the query are */ 00185 /* already correctly set */ 00186 FT_LOCAL( FT_Bool ) 00187 FTC_GNode_Compare( FTC_GNode gnode, 00188 FTC_GQuery gquery ); 00189 00190 /* call this function to clear a node's family -- this is necessary */ 00191 /* to implement the `node_remove_faceid' cache method correctly */ 00192 FT_LOCAL( void ) 00193 FTC_GNode_UnselectFamily( FTC_GNode gnode, 00194 FTC_Cache cache ); 00195 00196 /* must be called by derived FTC_Node_DoneFunc routines */ 00197 FT_LOCAL( void ) 00198 FTC_GNode_Done( FTC_GNode node, 00199 FTC_Cache cache ); 00200 00201 00202 FT_LOCAL( void ) 00203 FTC_Family_Init( FTC_Family family, 00204 FTC_Cache cache ); 00205 00206 typedef struct FTC_GCacheRec_ 00207 { 00208 FTC_CacheRec cache; 00209 FTC_MruListRec families; 00210 00211 } FTC_GCacheRec, *FTC_GCache; 00212 00213 #define FTC_GCACHE( x ) ((FTC_GCache)(x)) 00214 00215 00216 #if 0 00217 /* can be used as @FTC_Cache_InitFunc */ 00218 FT_LOCAL( FT_Error ) 00219 FTC_GCache_Init( FTC_GCache cache ); 00220 #endif 00221 00222 00223 #if 0 00224 /* can be used as @FTC_Cache_DoneFunc */ 00225 FT_LOCAL( void ) 00226 FTC_GCache_Done( FTC_GCache cache ); 00227 #endif 00228 00229 00230 /* the glyph cache class adds fields for the family implementation */ 00231 typedef struct FTC_GCacheClassRec_ 00232 { 00233 FTC_CacheClassRec clazz; 00234 FTC_MruListClass family_class; 00235 00236 } FTC_GCacheClassRec; 00237 00238 typedef const FTC_GCacheClassRec* FTC_GCacheClass; 00239 00240 #define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) 00241 00242 #define FTC_CACHE__GCACHE_CLASS( x ) \ 00243 FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) 00244 #define FTC_CACHE__FAMILY_CLASS( x ) \ 00245 ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) 00246 00247 00248 /* convenience function; use it instead of FTC_Manager_Register_Cache */ 00249 FT_LOCAL( FT_Error ) 00250 FTC_GCache_New( FTC_Manager manager, 00251 FTC_GCacheClass clazz, 00252 FTC_GCache *acache ); 00253 00254 #ifndef FTC_INLINE 00255 FT_LOCAL( FT_Error ) 00256 FTC_GCache_Lookup( FTC_GCache cache, 00257 FT_UInt32 hash, 00258 FT_UInt gindex, 00259 FTC_GQuery query, 00260 FTC_Node *anode ); 00261 #endif 00262 00263 00264 /* */ 00265 00266 00267 #define FTC_FAMILY_FREE( family, cache ) \ 00268 FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ 00269 (FTC_MruNode)(family) ) 00270 00271 00272 #ifdef FTC_INLINE 00273 00274 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ 00275 gindex, query, node, error ) \ 00276 FT_BEGIN_STMNT \ 00277 FTC_GCache _gcache = FTC_GCACHE( cache ); \ 00278 FTC_GQuery _gquery = (FTC_GQuery)( query ); \ 00279 FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ 00280 FTC_MruNode _mrunode; \ 00281 \ 00282 \ 00283 _gquery->gindex = (gindex); \ 00284 \ 00285 FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ 00286 _mrunode, error ); \ 00287 _gquery->family = FTC_FAMILY( _mrunode ); \ 00288 if ( !error ) \ 00289 { \ 00290 FTC_Family _gqfamily = _gquery->family; \ 00291 \ 00292 \ 00293 _gqfamily->num_nodes++; \ 00294 \ 00295 FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ 00296 \ 00297 if ( --_gqfamily->num_nodes == 0 ) \ 00298 FTC_FAMILY_FREE( _gqfamily, _gcache ); \ 00299 } \ 00300 FT_END_STMNT 00301 /* */ 00302 00303 #else /* !FTC_INLINE */ 00304 00305 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ 00306 gindex, query, node, error ) \ 00307 FT_BEGIN_STMNT \ 00308 \ 00309 error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ 00310 FTC_GQUERY( query ), node ); \ 00311 \ 00312 FT_END_STMNT 00313 00314 #endif /* !FTC_INLINE */ 00315 00316 00317 FT_END_HEADER 00318 00319 00320 #endif /* __FTCGLYPH_H__ */ 00321 00322 00323 /* END */