tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ftcglyph.h (11080B)


      1 /****************************************************************************
      2 *
      3 * ftcglyph.h
      4 *
      5 *   FreeType abstract glyph cache (specification).
      6 *
      7 * Copyright (C) 2000-2025 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_done
     69   *
     70   * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
     71   *   data.
     72   *
     73   * - Constant structures for a FTC_GNodeClass.
     74   *
     75   * - MyCacheNew() can be implemented easily as a call to the convenience
     76   *   function FTC_GCache_New.
     77   *
     78   * - MyCacheLookup with a call to FTC_GCache_Lookup.  This function will
     79   *   automatically:
     80   *
     81   *   - Search for the corresponding family in the cache, or create
     82   *     a new one if necessary.  Put it in FTC_GQUERY(myquery).family
     83   *
     84   *   - Call FTC_Cache_Lookup.
     85   *
     86   *   If it returns NULL, you should create a new node, then call
     87   *   ftc_cache_add as usual.
     88   */
     89 
     90 
     91  /**************************************************************************
     92   *
     93   * Important: The functions defined in this file are only used to
     94   *            implement an abstract glyph cache class.  You need to
     95   *            provide additional logic to implement a complete cache.
     96   *
     97   */
     98 
     99 
    100  /*************************************************************************/
    101  /*************************************************************************/
    102  /*************************************************************************/
    103  /*************************************************************************/
    104  /*************************************************************************/
    105  /*********                                                       *********/
    106  /*********             WARNING, THIS IS BETA CODE.               *********/
    107  /*********                                                       *********/
    108  /*************************************************************************/
    109  /*************************************************************************/
    110  /*************************************************************************/
    111  /*************************************************************************/
    112  /*************************************************************************/
    113 
    114 
    115 #ifndef FTCGLYPH_H_
    116 #define FTCGLYPH_H_
    117 
    118 
    119 #include "ftcmanag.h"
    120 
    121 
    122 FT_BEGIN_HEADER
    123 
    124 
    125 /*
    126  * We can group glyphs into `families'.  Each family correspond to a
    127  * given face ID, character size, transform, etc.
    128  *
    129  * Families are implemented as MRU list nodes.  They are
    130  * reference-counted.
    131  */
    132 
    133  typedef struct  FTC_FamilyRec_
    134  {
    135    FTC_MruNodeRec    mrunode;
    136    FT_UInt           num_nodes; /* current number of nodes in this family */
    137    FTC_Cache         cache;
    138    FTC_MruListClass  clazz;
    139 
    140  } FTC_FamilyRec, *FTC_Family;
    141 
    142 #define  FTC_FAMILY( x )    ( (FTC_Family)(x) )
    143 #define  FTC_FAMILY_P( x )  ( (FTC_Family*)(x) )
    144 
    145 
    146  typedef struct  FTC_GNodeRec_
    147  {
    148    FTC_NodeRec      node;
    149    FTC_Family       family;
    150    FT_UInt          gindex;
    151 
    152  } FTC_GNodeRec, *FTC_GNode;
    153 
    154 #define FTC_GNODE( x )    ( (FTC_GNode)(x) )
    155 #define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
    156 
    157 
    158  typedef struct  FTC_GQueryRec_
    159  {
    160    FT_UInt      gindex;
    161    FTC_Family   family;
    162 
    163  } FTC_GQueryRec, *FTC_GQuery;
    164 
    165 #define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
    166 
    167 
    168  /**************************************************************************
    169   *
    170   * These functions are exported so that they can be called from
    171   * user-provided cache classes; otherwise, they are really part of the
    172   * cache sub-system internals.
    173   */
    174 
    175  /* must be called by derived FTC_Node_InitFunc routines */
    176  FT_LOCAL( void )
    177  FTC_GNode_Init( FTC_GNode   node,
    178                  FT_UInt     gindex,  /* glyph index for node */
    179                  FTC_Family  family );
    180 
    181  /* call this function to clear a node's family -- this is necessary */
    182  /* to implement the `node_remove_faceid' cache method correctly     */
    183  FT_LOCAL( void )
    184  FTC_GNode_UnselectFamily( FTC_GNode  gnode,
    185                            FTC_Cache  cache );
    186 
    187  /* must be called by derived FTC_Node_DoneFunc routines */
    188  FT_LOCAL( void )
    189  FTC_GNode_Done( FTC_GNode  node,
    190                  FTC_Cache  cache );
    191 
    192 
    193  FT_LOCAL( void )
    194  FTC_Family_Init( FTC_Family  family,
    195                   FTC_Cache   cache );
    196 
    197  typedef struct FTC_GCacheRec_
    198  {
    199    FTC_CacheRec    cache;
    200    FTC_MruListRec  families;
    201 
    202  } FTC_GCacheRec, *FTC_GCache;
    203 
    204 #define FTC_GCACHE( x )  ((FTC_GCache)(x))
    205 
    206 
    207 #if 0
    208  /* can be used as @FTC_Cache_InitFunc */
    209  FT_LOCAL( FT_Error )
    210  FTC_GCache_Init( FTC_GCache  cache );
    211 #endif
    212 
    213 
    214 #if 0
    215  /* can be used as @FTC_Cache_DoneFunc */
    216  FT_LOCAL( void )
    217  FTC_GCache_Done( FTC_GCache  cache );
    218 #endif
    219 
    220 
    221  /* the glyph cache class adds fields for the family implementation */
    222  typedef struct  FTC_GCacheClassRec_
    223  {
    224    FTC_CacheClassRec  clazz;
    225    FTC_MruListClass   family_class;
    226 
    227  } FTC_GCacheClassRec;
    228 
    229  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
    230 
    231 #define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))
    232 
    233 #define FTC_CACHE_GCACHE_CLASS( x ) \
    234          FTC_GCACHE_CLASS( FTC_CACHE( x )->org_class )
    235 #define FTC_CACHE_FAMILY_CLASS( x ) \
    236          ( (FTC_MruListClass)FTC_CACHE_GCACHE_CLASS( x )->family_class )
    237 
    238 
    239  /* convenience function; use it instead of FTC_Manager_Register_Cache */
    240  FT_LOCAL( FT_Error )
    241  FTC_GCache_New( FTC_Manager       manager,
    242                  FTC_GCacheClass   clazz,
    243                  FTC_GCache       *acache );
    244 
    245 #ifndef FTC_INLINE
    246  FT_LOCAL( FT_Error )
    247  FTC_GCache_Lookup( FTC_GCache   cache,
    248                     FT_Offset    hash,
    249                     FT_UInt      gindex,
    250                     FTC_GQuery   query,
    251                     FTC_Node    *anode );
    252 #endif
    253 
    254 
    255  /* */
    256 
    257 
    258 #define FTC_FAMILY_FREE( family, cache )                      \
    259          FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \
    260                              (FTC_MruNode)(family) )
    261 
    262 
    263 #ifdef FTC_INLINE
    264 
    265 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
    266                               gindex, query, node, error )                 \
    267  FT_BEGIN_STMNT                                                            \
    268    FTC_GCache               _gcache   = FTC_GCACHE( cache );               \
    269    FTC_GQuery               _gquery   = (FTC_GQuery)( query );             \
    270    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
    271    FTC_MruNode              _mrunode;                                      \
    272                                                                            \
    273                                                                            \
    274    _gquery->gindex = (gindex);                                             \
    275                                                                            \
    276    FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare,         \
    277                            _mrunode, error );                              \
    278    _gquery->family = FTC_FAMILY( _mrunode );                               \
    279    if ( !error )                                                           \
    280    {                                                                       \
    281      FTC_Family  _gqfamily = _gquery->family;                              \
    282                                                                            \
    283                                                                            \
    284      _gqfamily->num_nodes++;                                               \
    285                                                                            \
    286      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );     \
    287                                                                            \
    288      if ( --_gqfamily->num_nodes == 0 )                                    \
    289        FTC_FAMILY_FREE( _gqfamily, _gcache );                              \
    290    }                                                                       \
    291  FT_END_STMNT
    292  /* */
    293 
    294 #else /* !FTC_INLINE */
    295 
    296 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,          \
    297                               gindex, query, node, error )           \
    298   FT_BEGIN_STMNT                                                     \
    299                                                                      \
    300     error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex,    \
    301                                FTC_GQUERY( query ), &node );         \
    302                                                                      \
    303   FT_END_STMNT
    304 
    305 #endif /* !FTC_INLINE */
    306 
    307 
    308 FT_END_HEADER
    309 
    310 
    311 #endif /* FTCGLYPH_H_ */
    312 
    313 
    314 /* END */