Al-Qurtas-Islamic-bank-The-.../src/cache/ftcglyph.h

329 lines
11 KiB
C
Raw Normal View History

/****************************************************************************
*
* ftcglyph.h
*
* FreeType abstract glyph cache (specification).
*
2022-01-11 10:54:10 +01:00
* Copyright (C) 2000-2022 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 "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;
2022-04-01 08:50:33 +02:00
#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; */
2006-03-24 13:46:49 +01:00
/* 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,
[cache] Notice if a cache query induced the node list change. Some node comparators (comparing the cache node content and the properties specified by the query) can flush the cache node to prevent the cache inflation. The change may invalidate the pointers to the node obtained before the node comparison, so the change should be noticed to the caller. The problem caused by the cache node changing is reported by Harsha, see Savannah bug #31923. * src/cache/ftccache.h (FTC_Node_CompareFunc): Add new argument `FT_Bool* list_changed' to indicate the change of the cached nodes to the caller. (FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes by `_list_changed'. (FTC_CACHE_TRYLOOP_END): Take new macro argument `_list_changed' and update it when FTC_Manager_FlushN() flushes any nodes. * src/cache/ftccback.h (ftc_snode_compare): Updated to fit with new FTC_Node_CompareFunc type. (ftc_gnode_compare): Ditto. * src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to use TRUE/FALSE macros. (ftc_basic_gnode_compare_faceid): New argument `FT_Bool* list_changed' to indicate the change of the cache nodes, anyway, it is always FALSE. * src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to use TRUE/FALSE macros. (ftc_cmap_node_compare): New argument `FT_Bool* list_changed' to indicate the change of the cache nodes, anyway, it is always FALSE. (ftc_cmap_node_remove_faceid): Ditto. * src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL pointer to FTC_CACHE_TRYLOOP_END(), because the result is not needed. (FTC_Cache_Lookup): Watch the change of the cache nodes by `list_changed'. (FTC_Cache_RemoveFaceID): Ditto. * src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to use TRUE/FALSE macros. (ftc_gnode_compare): New argument `FT_Bool* list_changed' to indicate the change of the cache nodes, anyway, it is always FALSE. (FTC_GNode_Compare): New argument `FT_Bool* list_changed' to be passed to ftc_gnode_compare(). * src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto. * src/cache/ftcsbits.c (ftc_snode_compare): New argument `FT_Bool* list_changed' to indicate the change of the cache nodes, anyway. It is updated by FTC_CACHE_TRYLOOP(). (FTC_SNode_Compare): New argument `FT_Bool* list_changed' to be passed to ftc_snode_compare(). * src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto.
2011-01-09 14:49:07 +01:00
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 ) \
2022-04-01 08:50:33 +02:00
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_Offset 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 */