OLD | NEW |
(Empty) | |
| 1 /***************************************************************************/ |
| 2 /* */ |
| 3 /* ftcglyph.h */ |
| 4 /* */ |
| 5 /* FreeType abstract glyph cache (specification). */ |
| 6 /* */ |
| 7 /* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 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 /* |
| 20 * |
| 21 * FTC_GCache is an _abstract_ cache object optimized to store glyph |
| 22 * data. It works as follows: |
| 23 * |
| 24 * - It manages FTC_GNode objects. Each one of them can hold one or more |
| 25 * glyph `items'. Item types are not specified in the FTC_GCache but |
| 26 * in classes that extend it. |
| 27 * |
| 28 * - Glyph attributes, like face ID, character size, render mode, etc., |
| 29 * can be grouped into abstract `glyph families'. This avoids storing |
| 30 * the attributes within the FTC_GCache, since it is likely that many |
| 31 * FTC_GNodes will belong to the same family in typical uses. |
| 32 * |
| 33 * - Each FTC_GNode is thus an FTC_Node with two additional fields: |
| 34 * |
| 35 * * gindex: A glyph index, or the first index in a glyph range. |
| 36 * * family: A pointer to a glyph `family'. |
| 37 * |
| 38 * - Family types are not fully specific in the FTC_Family type, but |
| 39 * by classes that extend it. |
| 40 * |
| 41 * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. |
| 42 * They share an FTC_Family sub-class called FTC_BasicFamily which is |
| 43 * used to store the following data: face ID, pixel/point sizes, load |
| 44 * flags. For more details see the file `src/cache/ftcbasic.c'. |
| 45 * |
| 46 * Client applications can extend FTC_GNode with their own FTC_GNode |
| 47 * and FTC_Family sub-classes to implement more complex caches (e.g., |
| 48 * handling automatic synthesis, like obliquing & emboldening, colored |
| 49 * glyphs, etc.). |
| 50 * |
| 51 * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and |
| 52 * `ftcsbits.h', which both extend FTC_GCache with additional |
| 53 * optimizations. |
| 54 * |
| 55 * A typical FTC_GCache implementation must provide at least the |
| 56 * following: |
| 57 * |
| 58 * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: |
| 59 * my_node_new (must call FTC_GNode_Init) |
| 60 * my_node_free (must call FTC_GNode_Done) |
| 61 * my_node_compare (must call FTC_GNode_Compare) |
| 62 * my_node_remove_faceid (must call ftc_gnode_unselect in case |
| 63 * of match) |
| 64 * |
| 65 * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: |
| 66 * my_family_compare |
| 67 * my_family_init |
| 68 * my_family_reset (optional) |
| 69 * my_family_done |
| 70 * |
| 71 * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query |
| 72 * data. |
| 73 * |
| 74 * - Constant structures for a FTC_GNodeClass. |
| 75 * |
| 76 * - MyCacheNew() can be implemented easily as a call to the convenience |
| 77 * function FTC_GCache_New. |
| 78 * |
| 79 * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will |
| 80 * automatically: |
| 81 * |
| 82 * - Search for the corresponding family in the cache, or create |
| 83 * a new one if necessary. Put it in FTC_GQUERY(myquery).family |
| 84 * |
| 85 * - Call FTC_Cache_Lookup. |
| 86 * |
| 87 * If it returns NULL, you should create a new node, then call |
| 88 * ftc_cache_add as usual. |
| 89 */ |
| 90 |
| 91 |
| 92 /*************************************************************************/ |
| 93 /* */ |
| 94 /* Important: The functions defined in this file are only used to */ |
| 95 /* implement an abstract glyph cache class. You need to */ |
| 96 /* provide additional logic to implement a complete cache. */ |
| 97 /* */ |
| 98 /*************************************************************************/ |
| 99 |
| 100 |
| 101 /*************************************************************************/ |
| 102 /*************************************************************************/ |
| 103 /*************************************************************************/ |
| 104 /*************************************************************************/ |
| 105 /*************************************************************************/ |
| 106 /********* *********/ |
| 107 /********* WARNING, THIS IS BETA CODE. *********/ |
| 108 /********* *********/ |
| 109 /*************************************************************************/ |
| 110 /*************************************************************************/ |
| 111 /*************************************************************************/ |
| 112 /*************************************************************************/ |
| 113 /*************************************************************************/ |
| 114 |
| 115 |
| 116 #ifndef __FTCGLYPH_H__ |
| 117 #define __FTCGLYPH_H__ |
| 118 |
| 119 |
| 120 #include <ft2build.h> |
| 121 #include "ftcmanag.h" |
| 122 |
| 123 |
| 124 FT_BEGIN_HEADER |
| 125 |
| 126 |
| 127 /* |
| 128 * We can group glyphs into `families'. Each family correspond to a |
| 129 * given face ID, character size, transform, etc. |
| 130 * |
| 131 * Families are implemented as MRU list nodes. They are |
| 132 * reference-counted. |
| 133 */ |
| 134 |
| 135 typedef struct FTC_FamilyRec_ |
| 136 { |
| 137 FTC_MruNodeRec mrunode; |
| 138 FT_UInt num_nodes; /* current number of nodes in this family */ |
| 139 FTC_Cache cache; |
| 140 FTC_MruListClass clazz; |
| 141 |
| 142 } FTC_FamilyRec, *FTC_Family; |
| 143 |
| 144 #define FTC_FAMILY(x) ( (FTC_Family)(x) ) |
| 145 #define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) |
| 146 |
| 147 |
| 148 typedef struct FTC_GNodeRec_ |
| 149 { |
| 150 FTC_NodeRec node; |
| 151 FTC_Family family; |
| 152 FT_UInt gindex; |
| 153 |
| 154 } FTC_GNodeRec, *FTC_GNode; |
| 155 |
| 156 #define FTC_GNODE( x ) ( (FTC_GNode)(x) ) |
| 157 #define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) |
| 158 |
| 159 |
| 160 typedef struct FTC_GQueryRec_ |
| 161 { |
| 162 FT_UInt gindex; |
| 163 FTC_Family family; |
| 164 |
| 165 } FTC_GQueryRec, *FTC_GQuery; |
| 166 |
| 167 #define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) |
| 168 |
| 169 |
| 170 /*************************************************************************/ |
| 171 /* */ |
| 172 /* These functions are exported so that they can be called from */ |
| 173 /* user-provided cache classes; otherwise, they are really part of the */ |
| 174 /* cache sub-system internals. */ |
| 175 /* */ |
| 176 |
| 177 /* must be called by derived FTC_Node_InitFunc routines */ |
| 178 FT_LOCAL( void ) |
| 179 FTC_GNode_Init( FTC_GNode node, |
| 180 FT_UInt gindex, /* glyph index for node */ |
| 181 FTC_Family family ); |
| 182 |
| 183 #ifdef FTC_INLINE |
| 184 |
| 185 /* returns TRUE iff the query's glyph index correspond to the node; */ |
| 186 /* this assumes that the `family' and `hash' fields of the query are */ |
| 187 /* already correctly set */ |
| 188 FT_LOCAL( FT_Bool ) |
| 189 FTC_GNode_Compare( FTC_GNode gnode, |
| 190 FTC_GQuery gquery, |
| 191 FTC_Cache cache, |
| 192 FT_Bool* list_changed ); |
| 193 |
| 194 #endif |
| 195 |
| 196 /* call this function to clear a node's family -- this is necessary */ |
| 197 /* to implement the `node_remove_faceid' cache method correctly */ |
| 198 FT_LOCAL( void ) |
| 199 FTC_GNode_UnselectFamily( FTC_GNode gnode, |
| 200 FTC_Cache cache ); |
| 201 |
| 202 /* must be called by derived FTC_Node_DoneFunc routines */ |
| 203 FT_LOCAL( void ) |
| 204 FTC_GNode_Done( FTC_GNode node, |
| 205 FTC_Cache cache ); |
| 206 |
| 207 |
| 208 FT_LOCAL( void ) |
| 209 FTC_Family_Init( FTC_Family family, |
| 210 FTC_Cache cache ); |
| 211 |
| 212 typedef struct FTC_GCacheRec_ |
| 213 { |
| 214 FTC_CacheRec cache; |
| 215 FTC_MruListRec families; |
| 216 |
| 217 } FTC_GCacheRec, *FTC_GCache; |
| 218 |
| 219 #define FTC_GCACHE( x ) ((FTC_GCache)(x)) |
| 220 |
| 221 |
| 222 #if 0 |
| 223 /* can be used as @FTC_Cache_InitFunc */ |
| 224 FT_LOCAL( FT_Error ) |
| 225 FTC_GCache_Init( FTC_GCache cache ); |
| 226 #endif |
| 227 |
| 228 |
| 229 #if 0 |
| 230 /* can be used as @FTC_Cache_DoneFunc */ |
| 231 FT_LOCAL( void ) |
| 232 FTC_GCache_Done( FTC_GCache cache ); |
| 233 #endif |
| 234 |
| 235 |
| 236 /* the glyph cache class adds fields for the family implementation */ |
| 237 typedef struct FTC_GCacheClassRec_ |
| 238 { |
| 239 FTC_CacheClassRec clazz; |
| 240 FTC_MruListClass family_class; |
| 241 |
| 242 } FTC_GCacheClassRec; |
| 243 |
| 244 typedef const FTC_GCacheClassRec* FTC_GCacheClass; |
| 245 |
| 246 #define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) |
| 247 |
| 248 #define FTC_CACHE__GCACHE_CLASS( x ) \ |
| 249 FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) |
| 250 #define FTC_CACHE__FAMILY_CLASS( x ) \ |
| 251 ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) |
| 252 |
| 253 |
| 254 /* convenience function; use it instead of FTC_Manager_Register_Cache */ |
| 255 FT_LOCAL( FT_Error ) |
| 256 FTC_GCache_New( FTC_Manager manager, |
| 257 FTC_GCacheClass clazz, |
| 258 FTC_GCache *acache ); |
| 259 |
| 260 #ifndef FTC_INLINE |
| 261 FT_LOCAL( FT_Error ) |
| 262 FTC_GCache_Lookup( FTC_GCache cache, |
| 263 FT_PtrDist hash, |
| 264 FT_UInt gindex, |
| 265 FTC_GQuery query, |
| 266 FTC_Node *anode ); |
| 267 #endif |
| 268 |
| 269 |
| 270 /* */ |
| 271 |
| 272 |
| 273 #define FTC_FAMILY_FREE( family, cache ) \ |
| 274 FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ |
| 275 (FTC_MruNode)(family) ) |
| 276 |
| 277 |
| 278 #ifdef FTC_INLINE |
| 279 |
| 280 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ |
| 281 gindex, query, node, error ) \ |
| 282 FT_BEGIN_STMNT \ |
| 283 FTC_GCache _gcache = FTC_GCACHE( cache ); \ |
| 284 FTC_GQuery _gquery = (FTC_GQuery)( query ); \ |
| 285 FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ |
| 286 FTC_MruNode _mrunode; \ |
| 287 \ |
| 288 \ |
| 289 _gquery->gindex = (gindex); \ |
| 290 \ |
| 291 FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ |
| 292 _mrunode, error ); \ |
| 293 _gquery->family = FTC_FAMILY( _mrunode ); \ |
| 294 if ( !error ) \ |
| 295 { \ |
| 296 FTC_Family _gqfamily = _gquery->family; \ |
| 297 \ |
| 298 \ |
| 299 _gqfamily->num_nodes++; \ |
| 300 \ |
| 301 FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ |
| 302 \ |
| 303 if ( --_gqfamily->num_nodes == 0 ) \ |
| 304 FTC_FAMILY_FREE( _gqfamily, _gcache ); \ |
| 305 } \ |
| 306 FT_END_STMNT |
| 307 /* */ |
| 308 |
| 309 #else /* !FTC_INLINE */ |
| 310 |
| 311 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ |
| 312 gindex, query, node, error ) \ |
| 313 FT_BEGIN_STMNT \ |
| 314 \ |
| 315 error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ |
| 316 FTC_GQUERY( query ), &node ); \ |
| 317 \ |
| 318 FT_END_STMNT |
| 319 |
| 320 #endif /* !FTC_INLINE */ |
| 321 |
| 322 |
| 323 FT_END_HEADER |
| 324 |
| 325 |
| 326 #endif /* __FTCGLYPH_H__ */ |
| 327 |
| 328 |
| 329 /* END */ |
OLD | NEW |