Index: src/cache/ftcglyph.h |
diff --git a/src/cache/ftcglyph.h b/src/cache/ftcglyph.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5fed19cb8fa20049ddc6260f1f265f96b437a20b |
--- /dev/null |
+++ b/src/cache/ftcglyph.h |
@@ -0,0 +1,329 @@ |
+/***************************************************************************/ |
+/* */ |
+/* ftcglyph.h */ |
+/* */ |
+/* FreeType abstract glyph cache (specification). */ |
+/* */ |
+/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 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. */ |
+/* */ |
+/***************************************************************************/ |
+ |
+ |
+ /* |
+ * |
+ * FTC_GCache is an _abstract_ cache object optimized to store glyph |
+ * data. It works as follows: |
+ * |
+ * - It manages FTC_GNode objects. Each one of them can hold one or more |
+ * glyph `items'. Item types are not specified in the FTC_GCache but |
+ * in classes that extend it. |
+ * |
+ * - Glyph attributes, like face ID, character size, render mode, etc., |
+ * can be grouped into abstract `glyph families'. This avoids storing |
+ * the attributes within the FTC_GCache, since it is likely that many |
+ * FTC_GNodes will belong to the same family in typical uses. |
+ * |
+ * - Each FTC_GNode is thus an FTC_Node with two additional fields: |
+ * |
+ * * gindex: A glyph index, or the first index in a glyph range. |
+ * * family: A pointer to a glyph `family'. |
+ * |
+ * - Family types are not fully specific in the FTC_Family type, but |
+ * by classes that extend it. |
+ * |
+ * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. |
+ * They share an FTC_Family sub-class called FTC_BasicFamily which is |
+ * used to store the following data: face ID, pixel/point sizes, load |
+ * flags. For more details see the file `src/cache/ftcbasic.c'. |
+ * |
+ * Client applications can extend FTC_GNode with their own FTC_GNode |
+ * and FTC_Family sub-classes to implement more complex caches (e.g., |
+ * handling automatic synthesis, like obliquing & emboldening, colored |
+ * glyphs, etc.). |
+ * |
+ * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and |
+ * `ftcsbits.h', which both extend FTC_GCache with additional |
+ * optimizations. |
+ * |
+ * A typical FTC_GCache implementation must provide at least the |
+ * following: |
+ * |
+ * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: |
+ * my_node_new (must call FTC_GNode_Init) |
+ * my_node_free (must call FTC_GNode_Done) |
+ * my_node_compare (must call FTC_GNode_Compare) |
+ * my_node_remove_faceid (must call ftc_gnode_unselect in case |
+ * of match) |
+ * |
+ * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: |
+ * my_family_compare |
+ * my_family_init |
+ * my_family_reset (optional) |
+ * my_family_done |
+ * |
+ * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query |
+ * data. |
+ * |
+ * - Constant structures for a FTC_GNodeClass. |
+ * |
+ * - MyCacheNew() can be implemented easily as a call to the convenience |
+ * function FTC_GCache_New. |
+ * |
+ * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will |
+ * automatically: |
+ * |
+ * - Search for the corresponding family in the cache, or create |
+ * a new one if necessary. Put it in FTC_GQUERY(myquery).family |
+ * |
+ * - Call FTC_Cache_Lookup. |
+ * |
+ * If it returns NULL, you should create a new node, then call |
+ * ftc_cache_add as usual. |
+ */ |
+ |
+ |
+ /*************************************************************************/ |
+ /* */ |
+ /* Important: The functions defined in this file are only used to */ |
+ /* implement an abstract glyph cache class. You need to */ |
+ /* provide additional logic to implement a complete cache. */ |
+ /* */ |
+ /*************************************************************************/ |
+ |
+ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /********* *********/ |
+ /********* WARNING, THIS IS BETA CODE. *********/ |
+ /********* *********/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ /*************************************************************************/ |
+ |
+ |
+#ifndef __FTCGLYPH_H__ |
+#define __FTCGLYPH_H__ |
+ |
+ |
+#include <ft2build.h> |
+#include "ftcmanag.h" |
+ |
+ |
+FT_BEGIN_HEADER |
+ |
+ |
+ /* |
+ * We can group glyphs into `families'. Each family correspond to a |
+ * given face ID, character size, transform, etc. |
+ * |
+ * Families are implemented as MRU list nodes. They are |
+ * reference-counted. |
+ */ |
+ |
+ typedef struct FTC_FamilyRec_ |
+ { |
+ FTC_MruNodeRec mrunode; |
+ FT_UInt num_nodes; /* current number of nodes in this family */ |
+ FTC_Cache cache; |
+ FTC_MruListClass clazz; |
+ |
+ } FTC_FamilyRec, *FTC_Family; |
+ |
+#define FTC_FAMILY(x) ( (FTC_Family)(x) ) |
+#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) |
+ |
+ |
+ typedef struct FTC_GNodeRec_ |
+ { |
+ FTC_NodeRec node; |
+ FTC_Family family; |
+ FT_UInt gindex; |
+ |
+ } FTC_GNodeRec, *FTC_GNode; |
+ |
+#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) |
+#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) |
+ |
+ |
+ typedef struct FTC_GQueryRec_ |
+ { |
+ FT_UInt gindex; |
+ FTC_Family family; |
+ |
+ } FTC_GQueryRec, *FTC_GQuery; |
+ |
+#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) |
+ |
+ |
+ /*************************************************************************/ |
+ /* */ |
+ /* These functions are exported so that they can be called from */ |
+ /* user-provided cache classes; otherwise, they are really part of the */ |
+ /* cache sub-system internals. */ |
+ /* */ |
+ |
+ /* must be called by derived FTC_Node_InitFunc routines */ |
+ FT_LOCAL( void ) |
+ FTC_GNode_Init( FTC_GNode node, |
+ FT_UInt gindex, /* glyph index for node */ |
+ FTC_Family family ); |
+ |
+#ifdef FTC_INLINE |
+ |
+ /* returns TRUE iff the query's glyph index correspond to the node; */ |
+ /* this assumes that the `family' and `hash' fields of the query are */ |
+ /* already correctly set */ |
+ FT_LOCAL( FT_Bool ) |
+ FTC_GNode_Compare( FTC_GNode gnode, |
+ FTC_GQuery gquery, |
+ FTC_Cache cache, |
+ FT_Bool* list_changed ); |
+ |
+#endif |
+ |
+ /* call this function to clear a node's family -- this is necessary */ |
+ /* to implement the `node_remove_faceid' cache method correctly */ |
+ FT_LOCAL( void ) |
+ FTC_GNode_UnselectFamily( FTC_GNode gnode, |
+ FTC_Cache cache ); |
+ |
+ /* must be called by derived FTC_Node_DoneFunc routines */ |
+ FT_LOCAL( void ) |
+ FTC_GNode_Done( FTC_GNode node, |
+ FTC_Cache cache ); |
+ |
+ |
+ FT_LOCAL( void ) |
+ FTC_Family_Init( FTC_Family family, |
+ FTC_Cache cache ); |
+ |
+ typedef struct FTC_GCacheRec_ |
+ { |
+ FTC_CacheRec cache; |
+ FTC_MruListRec families; |
+ |
+ } FTC_GCacheRec, *FTC_GCache; |
+ |
+#define FTC_GCACHE( x ) ((FTC_GCache)(x)) |
+ |
+ |
+#if 0 |
+ /* can be used as @FTC_Cache_InitFunc */ |
+ FT_LOCAL( FT_Error ) |
+ FTC_GCache_Init( FTC_GCache cache ); |
+#endif |
+ |
+ |
+#if 0 |
+ /* can be used as @FTC_Cache_DoneFunc */ |
+ FT_LOCAL( void ) |
+ FTC_GCache_Done( FTC_GCache cache ); |
+#endif |
+ |
+ |
+ /* the glyph cache class adds fields for the family implementation */ |
+ typedef struct FTC_GCacheClassRec_ |
+ { |
+ FTC_CacheClassRec clazz; |
+ FTC_MruListClass family_class; |
+ |
+ } FTC_GCacheClassRec; |
+ |
+ typedef const FTC_GCacheClassRec* FTC_GCacheClass; |
+ |
+#define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) |
+ |
+#define FTC_CACHE__GCACHE_CLASS( x ) \ |
+ FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) |
+#define FTC_CACHE__FAMILY_CLASS( x ) \ |
+ ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) |
+ |
+ |
+ /* convenience function; use it instead of FTC_Manager_Register_Cache */ |
+ FT_LOCAL( FT_Error ) |
+ FTC_GCache_New( FTC_Manager manager, |
+ FTC_GCacheClass clazz, |
+ FTC_GCache *acache ); |
+ |
+#ifndef FTC_INLINE |
+ FT_LOCAL( FT_Error ) |
+ FTC_GCache_Lookup( FTC_GCache cache, |
+ FT_PtrDist hash, |
+ FT_UInt gindex, |
+ FTC_GQuery query, |
+ FTC_Node *anode ); |
+#endif |
+ |
+ |
+ /* */ |
+ |
+ |
+#define FTC_FAMILY_FREE( family, cache ) \ |
+ FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ |
+ (FTC_MruNode)(family) ) |
+ |
+ |
+#ifdef FTC_INLINE |
+ |
+#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ |
+ gindex, query, node, error ) \ |
+ FT_BEGIN_STMNT \ |
+ FTC_GCache _gcache = FTC_GCACHE( cache ); \ |
+ FTC_GQuery _gquery = (FTC_GQuery)( query ); \ |
+ FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ |
+ FTC_MruNode _mrunode; \ |
+ \ |
+ \ |
+ _gquery->gindex = (gindex); \ |
+ \ |
+ FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ |
+ _mrunode, error ); \ |
+ _gquery->family = FTC_FAMILY( _mrunode ); \ |
+ if ( !error ) \ |
+ { \ |
+ FTC_Family _gqfamily = _gquery->family; \ |
+ \ |
+ \ |
+ _gqfamily->num_nodes++; \ |
+ \ |
+ FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ |
+ \ |
+ if ( --_gqfamily->num_nodes == 0 ) \ |
+ FTC_FAMILY_FREE( _gqfamily, _gcache ); \ |
+ } \ |
+ FT_END_STMNT |
+ /* */ |
+ |
+#else /* !FTC_INLINE */ |
+ |
+#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ |
+ gindex, query, node, error ) \ |
+ FT_BEGIN_STMNT \ |
+ \ |
+ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ |
+ FTC_GQUERY( query ), &node ); \ |
+ \ |
+ FT_END_STMNT |
+ |
+#endif /* !FTC_INLINE */ |
+ |
+ |
+FT_END_HEADER |
+ |
+ |
+#endif /* __FTCGLYPH_H__ */ |
+ |
+ |
+/* END */ |