| 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 */
|
|
|